Question

Modifié: SOLUTION TROUVE. Ceci est étrange et pas la meilleure solution, mais je suis allé de l'avant et mettre mon JAVA CODE (com. *) Les classes dans le swt.jar afin que swt.jar et mes classes sont chargées au même moment exact et par la même classloader. Pas la meilleure solution, mais une solution temporaire

Modifié: J'ai ajouté la plupart du code ici: 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

Ceci est l'erreur étrange ne classdef pas trouvé. Voici le scénario qui est un peu différent de 90% de mes œuvres de code. S'il vous plaît ignorer que j'utilise Clojure, je l'ai également fait avec le code java régulier et toujours obtenir la même erreur.

Idéalement, j'espérais un peu d'aide sur classloader personnalisé. Ma première pensée était que je pouvais créer le classloader, ajoutez le filepath / url des pots à classloader et je pouvais lancer mon code. Mais apparemment, il y a une certaine étrangeté passe.

  1. J'ai un fichier jar qui charge dynamiquement 4-5 fichiers jar auxillary. Il est construit sur un simple URLClassLoader. Je veux le faire parce que je peux avoir un utilisateur clique sur un fichier jar et lancez l'application. Donc, il y a un élément que l'utilisateur doit se préoccuper.

  2. En cliquant sur ce fichier jar, les charges d'application fichiers jar du système de fichiers. Par exemple. les (boîte à outils d'Eclipse widget) swt.jar charges d'application et d'autres pots.

3 (mais ne vous inquiétez pas à ce sujet), ma demande est construite sur Clojure (le langage de programmation dynamique), la première application à lancer ce script est Clojure. La plupart de mon application est dans le script clojure.

4. Tout à 1-3 fonctionne très bien. Le chargement de l'application et le script clojure fonctionne, l'application GUI SWT fonctionne, etc.

  1. Voici la partie qui ne fonctionne pas.

  2. J'ai une bibliothèque java existante, appelez mon-SWT-gui.jar. C'est aussi une application SWT. Il est essentiellement une autre application IUG est déjà construit. Je suis en train de charger la fenêtre de mon application actuelle clojure / SWT. Pour une raison quelconque, la bibliothèque JAVA orientée ne reconnaîtra pas SWT et je reçois des erreurs noclassdef.

Voici la bizarrerie. Et je vais identifier où je pense qu'il pourrait y avoir des bizarreries.

Entitis: A. Le classloader orienté java. Dans le classloader java, je lance l'application clojure. SWT et d'autres fichiers jar sont chargés avec ce classloader. B. Le code orienté Clojure qui obtient invoqué par l'article entité a. Le code Clojure est une application GUI basée sur SWT. B fonctionne très bien. C. code Java qui contient une autre fenêtre GUI. Pour une raison quelconque, cette bibliothèque habitude de charger et j'obtiens l'erreur, noclassdef.

NOTE: Je sais pertinemment que la classe SWT est en fait dans le classpath ou je recevrais une exception NoClassFound. Je ne reçois pas cette exception. Quelque chose d'autre se passe.

Remarque: pourrait-il être aussi un problème avec le fait que SWT comprend dll win32? l'accès peut-être le dll win32 jar les premiers travaux de temps, mais avec le code Java ne fonctionne pas? Mais voilà qui est étrange. Pourquoi serait SWT travail et ne pas fonctionner?

Je ne peux pas vous montrer tout le code, je l'espère, je peux vous montrer les éléments pertinents.

Voici le code principal classloader:

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

///////////// 

Et voilà comment j'ai essayé de charger la fenêtre SWT java. J'ai essayé d'imprimer autant sur le classloader et changer à DIFFElouer classloader.

(service IStartService, shell objet final, de globalClassLoader objet final) public final createPDFWindowShell static void throws Exception {

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

}


Voici l'erreur:

 [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

-

Était-ce utile?

La solution

J'ai vu des problèmes similaires dans un scénario plus simple où une classe chargée par un enfant classloader tente d'obtenir une classe chargée par un chargeur de classe parent pour charger dynamiquement l'un des frères et sœurs de l'enfant classloader - il ne fonctionne pas, parce que la enfant -.> relation parent est à sens unique

Sans tout le code, je ne peux pas être sûr, mais je soupçonne que quelque chose comme ce qui suit se passe:

  1. "Global" les délégués de classloader à classLoader A à charger les classes SWT
  2. "Global" de délégués classloader à classLoader B pour charger le code Clojure
  3. Code Clojure tente de charger dynamiquement les classes SWT via le seul classloader il sait - c'est classloader B
  4. Classloader B ne sait pas où les trouver, et explose

Est-ce que l'aide?

Autres conseils

Pas une solution spécifique, mais il semble que vous dupliquez un grand nombre de fonctionnalités qui est déjà présent dans One jar.

Vous pouvez regrouper votre code, ainsi que tous vos pots auxiliaires, en un seul fichier jar. Le classloader One-Pot fonctionnera dehors lors de l'exécution. Il m'a sauvé d'avoir à écrire du code classloader personnalisé à plusieurs reprises.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top