All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ru.yandex.qatools.camelot.maven.service.CamelotJettyRunner Maven / Gradle / Ivy

The newest version!
package ru.yandex.qatools.camelot.maven.service;

import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ShutdownHandler;
import org.eclipse.jetty.webapp.WebAppClassLoader;
import org.eclipse.jetty.webapp.WebAppContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;

import static java.lang.System.err; //NOSONAR

/**
 * @author Dmitry Baev [email protected]
 *         Date: 11.07.14
 *         

* Start Jetty with specified configuration */ public class CamelotJettyRunner { public static final String SHUTDOWN_PASSWORD = "shutdown-camelot-jetty"; //NOSONAR private final Logger logger = LoggerFactory.getLogger(getClass()); private final ClassLoader parent; private final String[] additionalClassPath; /** * Create {@link CamelotJettyRunner} with getClass().getClassLoader() parent. * Used in {@link CamelotRunner} via reflection api */ @SuppressWarnings("unused") public CamelotJettyRunner() { parent = getClass().getClassLoader(); additionalClassPath = new String[]{}; } /** * Create {@link CamelotJettyRunner} with new URL class loader with given classpath * * @param classPath specified classpath for classloader */ public CamelotJettyRunner(String... classPath) { this(CamelotJettyRunner.class.getClassLoader(), classPath); } /** * Create {@link CamelotJettyRunner} with specified parent classloader * * @param parent given parent classloader */ public CamelotJettyRunner(ClassLoader parent, String[] additionalClassPath) { this.parent = parent; this.additionalClassPath = unify(additionalClassPath); } /** * Start jetty server * * @param webApp path to web application directory * @param contextPath given context path for jetty server * @param port given port for jetty server * @param waitFor true if need to join to server, false otherwise * @throws Exception if can't start server with specified configuration */ public void run(String webApp, String contextPath, int port, boolean waitFor) throws Exception { //NOSONAR Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); Server server = new Server(port); WebAppContext context = new WebAppContext(); context.setContextPath(contextPath); context.setWar(webApp); context.setParentLoaderPriority(true); context.setClassLoader(createWebAppClassLoader(context)); server.setHandler(createHandlersForServer(context)); server.start(); if (waitFor) { logger.info("Waiting until process is finished..."); server.join(); } } /** * Create {@link WebAppClassLoader} with {@link #parent} as parent class loader and with extra classpath * * @param context {@link WebAppContext} to set to class loader * @return created class loader * @throws IOException if can't read resource from one of given extra class path elements */ private WebAppClassLoader createWebAppClassLoader(WebAppContext context) throws IOException { WebAppClassLoader classLoader = new WebAppClassLoader(parent, context) { @Override protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { try { return super.loadClass(name, resolve); } catch (NoClassDefFoundError e) { logger.trace("Ignored exception", e); Class c = super.findClass(name); if (resolve) { resolveClass(c); } return c; } } }; for (String url : additionalClassPath) { classLoader.addClassPath(url); } return classLoader; } /** * Create {@link org.eclipse.jetty.server.handler.HandlerList} for given jetty server and web application context * * @param context specified web application context * @return created handlers */ public static HandlerList createHandlersForServer(WebAppContext context) { HandlerList handlers = new HandlerList(); final ShutdownHandler shutdownHandler = new JettyKillHandler(SHUTDOWN_PASSWORD, true, true); handlers.setHandlers(new Handler[]{shutdownHandler, context}); return handlers; } /** * Unify given strings * * @param strings specified strings to unify * @return array of string without duplicates */ public static String[] unify(String... strings) { Set result = new LinkedHashSet<>(); result.addAll(Arrays.asList(strings)); return result.toArray(new String[result.size()]); } /** * Main point for start Jetty. * * @param args given arguments. * args[0] - web application directory path * args[1] - web application context path * args[2] - port * args[3] - path to jar with additional classpath * args[4] - true if need to wait for jetty shutdown, false otherwise * @throws Exception */ public static void main(String[] args) throws Exception { //NOSONAR if (args.length != 5) { err.println("Failed to launch Jetty: arguments count must be 6"); return; } final String webAppDirectory = args[0]; final String contextPath = args[1]; final int port = Integer.parseInt(args[2]); final String additionalClassPath = args[3]; final boolean waitFor = Boolean.parseBoolean(args[4]); new CamelotJettyRunner(additionalClassPath).run(webAppDirectory, contextPath, port, waitFor); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy