搜尋

首頁  >  問答  >  主體

java - Jetty启动不加载WEB-INF/lib下的JAR

Jetty启动不加载WEB-INF/lib下的JAR

直接使用java启动下面的main函数,发现Jetty没有到WEB-INF/lib下面的JAR。代码如下:

/**
 * 启动器
 */
public class Launcher {
    public static void main(String args[]) throws Exception {
        new Launcher().start();
    }

    void start() throws Exception {
        // 服务器的监听端口
        Server server = new Server(80);
        // 关联一个已经存在的上下文
        WebAppContext context = new WebAppContext();
        // 设置描述符位置
        String path = Launcher.class.getResource("/").getPath();
        context.setDescriptor(path + "../web.xml");
        // 设置Web内容上下文路径
        context.setResourceBase(path + "/../../");
        // 设置上下文路径
        context.setContextPath("/admin/");
        context.setParentLoaderPriority(true);
        //开启HTML,CSS,JS热部署
        context.setInitParameter("org.eclipse.jetty.servlet.Default.useFileMappedBuffer", "false");
        server.setHandler(context);
        // 启动
        server.start();
        server.join();
    }
}

错误日志:

2016-06-05 17:01:13.080 [main] ERROR o.s.web.servlet.DispatcherServlet - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'addressConsigneeIo' defined in file [D:\Project\CORP\EP\netease-ep\trunk\WebContent\WEB-INF\classes\org\darkgem\io\address\AddressConsigneeIo.class]: Post-processing failed of bean type [class org.darkgem.io.address.AddressConsigneeIo] failed; nested exception is java.lang.IllegalStateException: Failed to introspect bean class [org.darkgem.io.address.AddressConsigneeIo] for resource metadata: could not find class that it depends on
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:940)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:518)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:667)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:633)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:681)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:552)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:493)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
    at javax.servlet.GenericServlet.init(GenericServlet.java:244)
    at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:640)
    at org.eclipse.jetty.servlet.ServletHolder.initialize(ServletHolder.java:419)
    at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:875)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:348)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1379)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1341)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:774)
    at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:261)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:517)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.server.Server.start(Server.java:405)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.Server.doStart(Server.java:372)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.darkgem.jetty.Launcher.start(Launcher.java:31)
    at org.darkgem.jetty.Launcher.main(Launcher.java:11)
Caused by: java.lang.IllegalStateException: Failed to introspect bean class [org.darkgem.io.address.AddressConsigneeIo] for resource metadata: could not find class that it depends on
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.findResourceMetadata(CommonAnnotationBeanPostProcessor.java:334)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(CommonAnnotationBeanPostProcessor.java:287)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:935)
    ... 34 common frames omitted
Caused by: java.lang.NoClassDefFoundError: Lorg/springframework/jdbc/core/JdbcTemplate;
    at java.lang.Class.getDeclaredFields0(Native Method)
    at java.lang.Class.privateGetDeclaredFields(Class.java:2583)
    at java.lang.Class.getDeclaredFields(Class.java:1916)
    at org.springframework.util.ReflectionUtils.getDeclaredFields(ReflectionUtils.java:710)
    at org.springframework.util.ReflectionUtils.doWithLocalFields(ReflectionUtils.java:652)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.buildResourceMetadata(CommonAnnotationBeanPostProcessor.java:351)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.findResourceMetadata(CommonAnnotationBeanPostProcessor.java:330)
    ... 36 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.jdbc.core.JdbcTemplate
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 43 common frames omitted
PHP中文网PHP中文网2802 天前827

全部回覆(2)我來回復

  • 天蓬老师

    天蓬老师2017-04-18 09:08:36

    啟動的時候,使用 java -cp jetty.jar;WebContentWEB-INFclasses Launcher 啟動專案。

    從錯誤日誌可以看出是因為找不到 org.springframework.core.JdbcTemplate 这个类。而发生的问题的源码位于 classes 下面的業務代碼中。

    所以形成了一個:

    AppClassloader(业务代码,依赖spring.jar)
          |
    WebAppClssLoader(WEB-INF\lib\spring.jar)

    這樣子的依賴結構,所以在初始化Spring 容器的時候,初始化一個AppCloassLoader中的类(依赖Spring)发现无法查询到JdbcTemplate这个Spring类。这是因为加载器的双亲委托机制

    解決方法:

    1. 啟動的時候指定所有的lib和jar

    2. 或強制指定,不使用啟動jetty Launcher載入的classpath: context.setParentLoaderPriority(false);

    3. 使用一個 start.jar這種封裝好的jetty啟動器來啟動,啟動的時候,還是需要指定具體的classpath

    package org.darkgem.jetty;
    
    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.webapp.WebAppContext;
    
    import java.io.File;
    import java.io.FilenameFilter;
    
    /**
     * 启动器
     */
    public class Launcher {
        public static void main(String args[]) throws Exception {
            if (args.length == 0) {
                System.err.println("no web-app path");
                return;
            }
            String path = args[0];
            // 服务器的监听端口
            Server server = new Server(80);
            // 关联一个已经存在的上下文
            WebAppContext context = new WebAppContext();
            context.setDescriptor(path + "/WEB-INF/web.xml");
            // 设置Web内容上下文路径
            context.setResourceBase(path);
            // 设置上下文路径
            context.setContextPath("/admin/");
            context.setParentLoaderPriority(true);
            {
                StringBuilder sb = new StringBuilder();
                {
                    sb.append(path);
                    sb.append("/WEB-INF/classes");
                    sb.append(";");
                }
                {
                    File libDir = new File(path + "/WEB-INF/lib");
                    if (libDir.exists() && libDir.isDirectory()) {
                        for (File jar : libDir.listFiles(new FilenameFilter() {
                            @Override
                            public boolean accept(File dir, String name) {
                                if (name.endsWith(".zip") || name.endsWith(".jar")) {
                                    return true;
                                }
                                return false;
                            }
                        })) {
                            sb.append(jar.getAbsolutePath());
                            sb.append(";");
                        }
                    }
                }
                System.out.println(sb.toString());
                context.setExtraClasspath(sb.toString());
            }
            //开启HTML,CSS,JS热部署
            context.setInitParameter("org.eclipse.jetty.servlet.Default.useFileMappedBuffer", "false");
            server.setHandler(context);
            // 启动
            server.start();
            server.join();
        }
    }

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-18 09:08:36

    你試過設定context.setExtraClasspath(你的WEB-INF/lib)麼?

    回覆
    0
  • 取消回覆