【问题标题】:running jetty web service via reflection通过反射运行码头网络服务
【发布时间】:2018-12-11 07:24:38
【问题描述】:

大家好,我一直在尝试将 jetty 作为我的 rest web 服务的嵌入式服务器,并且在独立使用它时,程序运行良好,但是当我尝试使用反射调用包含 jetty 服务器启动逻辑的类的 main 方法时,我无法让它工作。此外,当我从代码中删除 jettyServer.join 行时,我会收到错误 java.lang.NoClassDefFoundError: org/eclipse/jetty/io/ManagedSelector$Accept 如果我取消注释然后我没有收到任何错误,但是当我尝试访问我的网络服务时,我收到 404 错误。

这是一个名为 App 的类中的服务器启动代码

public static void main(String[] args) {
        // TODO Auto-generated method stub

        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
          context.setContextPath("/JettyService/Servlet1");
          StartupListener sup=new StartupListener();
          context.addEventListener(sup);

          Server jettyServer = new Server(8080);
          jettyServer.setHandler(context);

          ServletHolder jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*");
          jerseyServlet.setInitOrder(0);

          jerseyServlet.setInitParameter("jersey.config.server.provider.classnames", JettyServiceApp.class.getCanonicalName());

          try {
           jettyServer.start();
         // jettyServer.join();
           //stopServer(jettyServer);
          // jettyServer.stop();
          } catch (Exception e) {
           e.printStackTrace();
          } 
          finally{
          // jettyServer.destroy();
          }

    }

这是通过反射调用此方法的代码

try {
            List<URL> urlsR=new ArrayList<URL>();
//contains source classes
            File file = new File("C:\\Users\\DemonKing\\Documents\\eclipseprojects\\JettyDemo\\bin\\");
//contains the depenedencies jars of jetty
            File file2 = new File("F:\\JettyJarsComplete");
            for(File child:file2.listFiles())
            {
                File resFile=new File(file2+"\\"+child.getName());
                System.out.println(resFile);
                URL url2 = resFile.toURI().toURL();
                urlsR.add(url2);
            }

            // convert the file to URL format
            URL url = file.toURI().toURL();
            urlsR.add(url); 
            //URL url2 = file2.toURI().toURL();
            //URL[] urls = new URL[] { url,url2 };
            URL[] urls = urlsR.toArray(new URL[urlsR.size()]);
            //url

            // load this folder into Class loader
            ClassLoader cl = new URLClassLoader(urls);
            Class<?> cls = cl.loadClass("org.demonking.App");
            System.out.println("web class loaders:" + cls.getClassLoader());
            Method m = cls.getDeclaredMethod("main", String[].class);
            m.invoke(null, (Object) null);

            // code added by to avoid the resource leak class loader is
            // never closed warning
            URLClassLoader urlCl = (URLClassLoader) cl;
            urlCl.close();

        } catch (Exception ex) {
            ex.printStackTrace();
        }

需要关于我做错了什么的帮助或指针,这种情况是否可以通过另一个代码的反射来启动一个休息网络服务。

我理解为什么 java 中会出现 classnotfond 错误,但是类加载器引用了所有需要的 jars,并且 iam 在码头服务器启动时没有收到错误,因为我可以看到它在日志中被初始化,这只发生在尝试访问我的 web 服务时它的路径

更新:摆脱了 classnotfound 异常和所有类加载器问题,但仍然无法访问 Web 服务,它总是返回 404 错误而没有任何异常。请注意,这只发生在通过反射调用该方法时,否则代码可以正常工作。需要帮助

【问题讨论】:

  • @talex 你能确认我想要实现的目标是否可行吗?
  • 是的。很可能是您在类路径中的问题。确保所需的类在 JettyJarsComplete 文件夹中的某个 jar 中。
  • @talex 但这些罐子与独立项目的工作正常的罐子相同
  • 您确定您的独立项目除了上述文件夹中的之外没有任何其他 jars 吗?

标签: java web-services reflection jetty


【解决方案1】:

我终于让它工作了。刚刚将我的 urlclassloader 添加为线程的当前 contextclassloader 并且代码开始工作。只是在 jettyServer.start 方法之前添加的

Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());

现在有人可以解释为什么这是有效的,因为我认为从 jettyserver.start 方法开始的线程没有引用我的 urlclassloader?我说的对吗?

【讨论】:

    猜你喜欢
    • 2015-11-30
    • 1970-01-01
    • 1970-01-01
    • 2012-02-05
    • 1970-01-01
    • 2012-02-27
    • 2014-10-09
    • 2010-10-25
    • 1970-01-01
    相关资源
    最近更新 更多