1

Hello everyone I have been trying jetty as an embedded server for my rest web service and while using it standalone the program works fine but when i try to call the main method of the class that contains the jetty server startup logic using reflection i cant get it to work.Also when i remove the jettyServer.join line from my code then i get error java.lang.NoClassDefFoundError: org/eclipse/jetty/io/ManagedSelector$Accept and if i uncomment it then i get no error but when i try to access my web service i get 404 error.

Here is the code for server startup in a class called 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();
          }

    }

And here is the code that calls this method via reflection

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();
        }

Need Help or pointers as to what am i doing wrong and is this scenario even achievable that is starting up a rest web service via reflection from another code.

I understand why classnotfond errors occur in java but the classloader is referencing all the jars required and iam not getting error on jetty server startup as i can see it being initailised in the logs this only happens when itry to access my web service at its path

Update: got rid of the classnotfound exceptions and all classloader issues but still cant access the web service it always returns 404 error without any exception.Note this only happens when calling the method via reflection otherwise code works fine.Need Help

JayD
  • 748
  • 1
  • 13
  • 38
  • Possible duplicate of [Why am I getting a NoClassDefFoundError in Java?](https://stackoverflow.com/questions/34413/why-am-i-getting-a-noclassdeffounderror-in-java) – talex Dec 11 '18 at 07:38
  • @talex can you confirm whether what i am trying to achieve is possible? – JayD Dec 11 '18 at 08:02
  • Yes. Most probably your problem in classpath. Make sure that required class is in some jar in `JettyJarsComplete` folder. – talex Dec 11 '18 at 08:05
  • @talex but the jars are the same as the one that are wroking fine for the standalone project – JayD Dec 11 '18 at 08:07
  • Are you sure that you standalone project doesn't have any other jars except those in said folder? – talex Dec 11 '18 at 08:08
  • absolutely i actually created the folder after copying all the jars that were placed on the classpath of the working project – JayD Dec 11 '18 at 08:10
  • should the code above work as iam assuming it to work or is there a potential problem in it? – JayD Dec 11 '18 at 08:11
  • Do a simple check. In standalone project locate jar with problematic class. Make sure this jar in your folder. Make sure class is present in this jar. – talex Dec 11 '18 at 08:11
  • "should the code above work" yes it should. You do it right way, problem in configuration. – talex Dec 11 '18 at 08:12

1 Answers1

0

I finally got it to work. Just added my urlclassloader as thread's current contextclassloader and the code started to work. just added before jettyServer.start method

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

can somenone now explain why this works because i think the thread started from jettyserver.start method did'nt had reference of my urlclassloader? Am i right?

JayD
  • 748
  • 1
  • 13
  • 38