ArchiveException: архиватор при передаче аргумента в файл Jar

У меня была аналогичная ситуация, но мне нужно было предоставить один сингл с сервлетом, развернутым через войну, с помощью горячего (повторного) развертывания в контейнере Jetty. Принятый ответ был не совсем тем, что мне нужно в моем случае, так как сервлет имеет жизненный цикл и контекст, управляемые установщиком.

Я закончил с применением грубой силы, добавив объект в server, который сохраняется для жизни контейнера, а затем извлекает объект из сервлета (ов). Это потребовало загрузки класса объекта в родительский (системный) загрузчик классов, чтобы war Webapp не загружал свою собственную версию класса в свой собственный загрузчик классов, что вызвало бы исключение литья, как описано здесь здесь .

Код сервера Embedded Jetty:

    Server server = new Server(8090);

    // Add all classes related to the object(s) you want to share here.
    WebAppContext.addSystemClasses(server, "my.package.MyFineClass", ...);

    // Handler config
    ContextHandlerCollection contexts = new ContextHandlerCollection();
    HandlerCollection handlers = new HandlerCollection();
    handlers.setHandlers(new Handler[] { contexts });
    server.setHandler(handlers);

    // Deployer config (hot deploy)
    DeploymentManager deployer = new DeploymentManager();
    DebugListener debug = new DebugListener(System.err,true,true,true);
    server.addBean(debug);
    deployer.addLifeCycleBinding(new DebugListenerBinding(debug));
    deployer.setContexts(contexts);
    deployer.setContextAttribute(
            "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
            ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/[^/]*taglibs.*\\.jar$");

    WebAppProvider webapp_provider = new WebAppProvider();
    webapp_provider.setMonitoredDirName("/.../webapps");
    webapp_provider.setScanInterval(1);
    webapp_provider.setExtractWars(true);
    webapp_provider.setConfigurationManager(new PropertiesConfigurationManager());

    deployer.addAppProvider(webapp_provider);
    server.addBean(deployer);

    // Other config...

    // Tuck any objects/data you want into the root server object.
    server.setAttribute("my.package.MyFineClass", myFineSingleton);

    server.start();
    server.join();

Пример сервлета:

public class MyFineServlet extends HttpServlet
{
    MyFineClass myFineSingleton;

    @Override
    public void init() throws ServletException
    {
        // Sneak access to the root server object (non-portable).
        // Not possible to cast this to `Server` because of classloader restrictions in Jetty.
        Object server = request.getAttribute("org.eclipse.jetty.server.Server");

        // Because we cannot cast to `Server`, use reflection to access the object we tucked away there.
        try {
            myFineSingleton = (MyFineClass) server.getClass().getMethod("getAttribute", String.class).invoke(server, "my.package.MyFineClass");
        } catch (Exception ex) {
            throw new ServletException("Unable to reflect MyFineClass instance via Jetty Server", ex);
        }
    }

    @Override
    protected void doGet( HttpServletRequest request,
            HttpServletResponse response ) throws ServletException, IOException
    {
        response.setContentType("text/html");
        response.setStatus(HttpServletResponse.SC_OK);
        response.getWriter().println("

Hello from MyFineServlet

"); response.getWriter().println("Here's: " + myFineSingleton.toString()); } }

Мой файл сборки для сервлета (sbt) помещал my.package.MyFineClass в «предоставленный» объем, чтобы он не попал в войну, поскольку он уже будет загружен на сервер Jetty.

0
задан Abhay S 1 April 2019 в 08:16
поделиться