奇怪的Classpath,.NoClassDefFoundError错误

时间:2009-06-29 21:25:57

标签: java clojure swt classloader noclassdeffounderror

已编辑:已完成解决方案。这很奇怪,不是最好的解决方案,但我只是继续把我的JAVA CODE(com。*)放在swt.jar中的类中,以便swt.jar和我的类在同一时刻加载类加载器。不是最佳解决方案,而是临时修复

编辑:我在这里添加了大部分代码: http://groups.google.com/group/clojure/browse_thread/thread/1d7dd4913b2f9aa7 http://groups.google.com/group/clojure/web/NoClassDefIssue.zip http://groups.google.com/group/clojure/web/MostCodeIssue.java

这是奇怪的没有找到classdef错误。这是90%的代码工作有点不同的场景。请忽略我正在使用Clojure,我也使用常规java代码完成此操作并仍然得到相同的错误。

理想情况下,我希望在自定义类加载器上提供一些帮助。我最初的想法是我可以创建类加载器,将jar文件路径/ url添加到类加载器中,然后我可以启动我的代码。但显然有一些陌生感。

  1. 我有一个动态加载4-5个辅助jar文件的jar文件。它建立在一个简单的URLClassLoader上。我想这样做是因为我可以让用户点击一个jar文件并启动应用程序。因此,用户必须担心一件事。

  2. 通过单击此jar文件,应用程序从文件系统加载jar文件。例如。应用程序加载swt.jar(Eclipse的widget工具包)和其他一些jar。

  3. 3(但不要担心),我的应用程序是基于Clojure(动态编程语言)构建的,第一个启动的应用程序就是这个Clojure脚本。我的大多数应用程序都在clojure脚本中。

    4。一切都达到1-3工作正常。应用程序加载和clojure脚本运行,SWT GUI应用程序运行等

    1. 这是不起作用的部分。

    2. 我有一个现有的java库,称之为my-swt-gui.jar。这也是一个swt应用程序。它基本上是另一个gui应用程序已经构建。我正在尝试从我当前的clojure / swt应用程序加载窗口。出于某种原因,面向JAVA的库将无法识别SWT并且我得到noclassdef错误。

    3. 这是陌生感。而且我会确定我认为可能有些奇怪的地方。

      Entitis: A.面向java的类加载器。在java类加载器中,我启动了clojure应用程序。使用此类加载器加载SWT和其他jar文件。 B.由部分实体a调用的面向Clojure的代码。 clojure代码是基于swt的GUI应用程序。 B工作正常。 C.包含另一个GUI窗口的Java代码。出于某种原因,这个库不会加载,我收到错误,noclassdef。

      注意:我知道一个事实是SWT类实际上在类路径中,否则我会得到一个NoClassFound异常。我没有得到那个例外。还有其他事情正在发生。

      注意:SWT包含win32 dll的事实是否也是一个问题?也许第一次访问win32 dll jar工作,但使用java代码它不起作用?但这很奇怪。为什么SWT会起作用然后不起作用?

      我无法向您展示所有代码,我希望我能向您展示相关内容。

      以下是主要的类加载器代码:

       public static final String [] JAVA_LIBRARIES = {
              "lib\\log4j-1.2.15.jar",
              "lib\\octane_commons.jar",
              "lib\\clojure.jar",
              "lib\\swt\\win32\\swt.jar",
              "lib\\jfreechart\\jcommon-1.0.15.jar",
              "lib\\jfreechart\\jfreechart-1.0.12.jar",
              "lib\\jfreechart\\jfreechart-1.0.12-swt.jar",
              "lib\\pdf\\minium.jar",
              "lib\\pdf\\tagsoup-1.2.jar",
              "lib\\pdf\\core-renderer.jar",
              "lib",
              "conf",
              "src"
          };
      
      My classloader code is based on jetty's classloader and it works OK
      but I keep get ting classnotdef errors.  Strange ones.  I can see a
      clear distinction between classnotfound errors.  If the file path to
      the jar is invalid then I get classnotfound, easy to detect and fix.
      
      Here is essentially the classloader code for future reference.
      
      Classpath classpath = new Classpath();
      
      boolean res = classpath.addComponent(libFilePath);
      
      /// Classloader
      
      private class Loader extends URLClassLoader {
              String name;
              Loader(URL[] urls, ClassLoader parent) {
                  super(urls, parent);
                  name = "StartLoader" + Arrays.asList(urls);
              }
      
              public String toString() {
                  return name;
              }
          }
      
      //// Then set the classloader
      //// where the URLs are the JAR libraries:
         URL [] urls = new URL[NUMBER_OF_JARS];
         for (x in urls) {
            urls[i] = new URL("THE JAR PATH");
         }
      
          ClassLoader parent = Thread.currentThread().getContextClassLoader();
              if (parent == null) {
                  parent = Classpath.class.getClassLoader();
              }
              if (parent == null) {
      
                  parent = ClassLoader.getSystemClassLoader();
              }
              return new Loader(urls, parent);
      
      ///////////// 
      

      这就是我尝试加载java swt窗口的方法。我试着打印出关于类加载器的更多内容并更改为不同的类加载器。

      public static final void createPDFWindowShell(IStartService service,final Object shell,final Object globalClassLoader)抛出异常{

      if ((service != null) && (shell != null)) {
          synchronized(service) {
              service.runService();
              Thread.sleep(80);
          }
      } else {
          System.err.println("Invalid arguments : service => " + service + " shell =>" + shell);
          return;
      } // End of the if //    
      
      final ClassLoader cl = globalClassLoader == null ? service.getClass().getClassLoader() : (ClassLoader) globalClassLoader;
      System.out.println("Service Class Loader.1: " +  service.getClass().getClassLoader());  
      System.out.println("Service Class Loader.2 : " +  cl);
      System.out.println("-----------------");
      System.out.println("[From DynaClass.1] : " + cl.loadClass("com.octane.start.services.IStartService"));
      System.out.println("[From DynaClass.2] : " + cl.loadClass("org.eclipse.swt.SWT"));                      
      System.out.println("[From DynaClass.3] : " + cl.loadClass("org.eclipse.swt.events.SelectionListener"));
      System.out.println("-----------------");        
      
      final Class listenerTargetClass = cl.loadClass("org.eclipse.swt.events.SelectionListener");
      final ClassLoader newCl = globalClassLoader == null ? service.getClass().getClassLoader() : (ClassLoader) globalClassLoader;
      
      // Now launch the shell //        
      //final Class winClass = Class.forName("com.ca.util.gui.SimplePFSXHtmlPDFWin");
      final Class winClass = cl.loadClass("com.ca.util.gui.SimplePFSXHtmlPDFWin");
      final Method methodCreate = winClass.getMethod("createPDFWindowShell", new Class [] { Object.class });
      methodCreate.invoke(null, shell);
      

      }


      这是错误:

       [java] [INFO : Classpath Loader Check] : valid files=17 / total=17
       [java] [Classpath Loader] - thread class loader parent == false
       [java] [INFO : Classpath Loader Check] : classpath=StartLoader[file:/C%3a/Program%20Files/Java/jdk1.5.0_11/lib/tools.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/log4j-1.2.15.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/octane_commons.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/clojure.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/swt/win32/swt.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/jfreechart/jcommon-1.0.15.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/jfreechart/jfreechart-1.0.12.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/jfreechart/jfreechart-1.0.12-swt.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/jfreechart/gnujaxp.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/jfreechart/swtgraphics2d.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/jfreechart/jfreechart-1.0.12-experimental.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/pdf/xercesImpl.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/pdf/minium.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/pdf/tagsoup-1.2.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/pdf/core-renderer.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/, file:/C%3a/usr/local/pfs/projects/octane/conf/, file:/C%3a/usr/local/pfs/projects/octane/src/]
       [java] Active threads : 3
       [java] class clojure.lang.Script
       [java] class org.eclipse.swt.SWT
       [java] interface org.eclipse.swt.events.SelectionListener
       [java] class org.apache.log4j.Logger
       [java] class org.xhtmlrenderer.util.XRLog
       [java] [INFO] Thread ID : Thread[Thread-3,5,main]
       [java] Service Class Loader.1: sun.misc.Launcher$AppClassLoader@92e78c
       [java] Service Class Loader.2 : StartLoader[file:/C%3a/Program%20Files/Java/jdk1.5.0_11/lib/tools.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/log4j-1.2.15.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/octane_commons.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/clojure.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/swt/win32/swt.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/jfreechart/jcommon-1.0.15.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/jfreechart/jfreechart-1.0.12.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/jfreechart/jfreechart-1.0.12-swt.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/jfreechart/gnujaxp.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/jfreechart/swtgraphics2d.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/jfreechart/jfreechart-1.0.12-experimental.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/pdf/xercesImpl.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/pdf/minium.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/pdf/tagsoup-1.2.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/pdf/core-renderer.jar, file:/C%3a/usr/local/pfs/projects/octane/lib/, file:/C%3a/usr/local/pfs/projects/octane/conf/, file:/C%3a/usr/local/pfs/projects/octane/src/]
       [java] -----------------
       [java] [From DynaClass.1] : interface com.octane.start.services.IStartService
       [java] [From DynaClass.2] : class org.eclipse.swt.SWT
       [java] [From DynaClass.3] : interface org.eclipse.swt.events.SelectionListener
       [java] -----------------
       [java] java.lang.reflect.InvocationTargetException
       [java]     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       [java]     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       [java]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       [java]     at java.lang.reflect.Method.invoke(Method.java:585)
       [java]     at com.octane.start.OctaneClojureScript.invokeVarInvoke(OctaneClojureScript.java:89)
       [java]     at com.octane.start.OctaneClojureScript.invokeContract(OctaneClojureScript.java:118)
       [java]     at com.octane.start.OctaneClojureScript.main(OctaneClojureScript.java:129)
       [java]     at com.octane.start.services.ClassPathLoaderService.runService(ClassPathLoaderService.java:225)
       [java]     at com.octane.start.OctaneLauncherMain.runClasspathService(OctaneLauncherMain.java:73)
       [java]     at com.octane.start.OctaneLauncherMain.main(OctaneLauncherMain.java:97)
       [java] Caused by: java.lang.NoClassDefFoundError: org/eclipse/swt/events/SelectionListener (octane_main_window.clj:0)
       [java]     at clojure.lang.Compiler.eval(Compiler.java:4543)
       [java]     at clojure.lang.Compiler.load(Compiler.java:4857)
       [java]     at clojure.lang.RT.loadResourceScript(RT.java:326)
       [java]     at clojure.lang.RT.loadResourceScript(RT.java:317)
       [java]     at clojure.lang.RT.load(RT.java:395)
       [java]     at clojure.lang.RT.load(RT.java:367)
       [java]     at clojure.core$load__5058$fn__5061.invoke(core.clj:3734)
       [java]     at clojure.core$load__5058.doInvoke(core.clj:3733)
       [java]     at clojure.lang.RestFn.invoke(RestFn.java:413)
       [java]     at clojure.core$load_one__5010.invoke(core.clj:3578)
       [java]     at clojure.core$load_lib__5031.doInvoke(core.clj:3615)
       [java]     at clojure.lang.RestFn.applyTo(RestFn.java:147)
       [java]     at clojure.core$apply__3243.doInvoke(core.clj:390)
       [java]     at clojure.lang.RestFn.invoke(RestFn.java:443)
       [java]     at clojure.core$load_libs__5043.doInvoke(core.clj:3641)
       [java]     at clojure.lang.RestFn.applyTo(RestFn.java:142)
       [java]     at clojure.core$apply__3243.doInvoke(core.clj:390)
       [java]     at clojure.lang.RestFn.invoke(RestFn.java:443)
       [java]     at clojure.core$require__5049.doInvoke(core.clj:3701)
       [java]     at clojure.lang.RestFn.invoke(RestFn.java:413)
       [java]     at clojure.lang.Var.invoke(Var.java:346)
       [java]     ... 10 more
       [java] Caused by: java.lang.NoClassDefFoundError: org/eclipse/swt/events/SelectionListener
       [java]     at java.lang.Class.getDeclaredMethods0(Native Method)
       [java]     at java.lang.Class.privateGetDeclaredMethods(Class.java:2395)
       [java]     at java.lang.Class.getMethod0(Class.java:2642)
       [java]     at java.lang.Class.getMethod(Class.java:1579)
       [java]     at com.octane.start.PDFDynamicStartWin.createPDFWindowShell(PDFDynamicStartWin.java:39)
       [java]     at octane.toolkit.octane_core_widgets$pdf_handler__2659.invoke(octane_core_widgets.clj:81)
       [java]     at octane.toolkit.octane_core_widgets$fn__2662$fn__2664.invoke(octane_core_widgets.clj:87)
       [java]     at clojure.proxy.org.eclipse.swt.events.SelectionAdapter.widgetSelected(Unknown Source)
       [java]     at org.eclipse.swt.widgets.TypedListener.handleEvent(Unknown Source)
       [java]     at org.eclipse.swt.widgets.EventTable.sendEvent(Unknown Source)
       [java]     at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
       [java]     at org.eclipse.swt.widgets.Display.runDeferredEvents(Unknown Source)
       [java]     at org.eclipse.swt.widgets.Display.readAndDispatch(Unknown Source)
       [java]     at octane.toolkit.octane_main_window$create_gui_window__2990.invoke(octane_main_window.clj:234)
       [java]     at octane.toolkit.octane_main_window$main_1__2994.invoke(octane_main_window.clj:246)
       [java] Processing Time : 6235
       [java]     at octane.toolkit.octane_main_window$_main__2998.doInvoke(octane_main_window.clj:250)
       [java]     at clojure.lang.RestFn.invoke(RestFn.java:402)
       [java]     at octane.toolkit.octane_main_window$eval__3001.invoke(octane_main_window.clj:259)
       [java]     at clojure.lang.Compiler.eval(Compiler.java:4532)
       [java]     ... 30 more
      

      -

2 个答案:

答案 0 :(得分:3)

我在一个更简单的场景中看到了类似的问题,其中由子类加载器加载的类试图获取由父类加载器加载的类以动态加载其中一个子类加载器的兄弟 - 它不起作用,因为孩子 - >父母关系只是单向的。

如果没有所有代码,我无法确定,但我怀疑发生了以下情况:

  1. “Global”类加载器委托类加载器A加载SWT类
  2. “Global”类加载器委托类加载器B加载Clojure代码
  3. Clojure代码尝试通过它所知道的唯一类加载器动态加载SWT类 - 也就是类加载器B
  4. Classloader B不知道在哪里找到它们,然后爆炸
  5. 这有帮助吗?

答案 1 :(得分:-1)

不是具体的解决方案,但听起来你复制了One-Jar中已经存在的许多功能。

您可以将代码以及所有辅助jar包捆绑到一个jar文件中。 One-Jar类加载器将在运行时进行处理。它使我不必多次编写自定义类加载器代码。