ClassNotFoundException mit Netbeans

Added by timekeeper 10 months ago

Hallo Alex,
ich arbeite mit Netbeans und habe nun das erste mal angefangen, einen GUI-Client zu implementieren. Wiederverwendung von Codeteilen ist in Netbeans nicht ganz trivial, wenn man größere Projekte machen will (also Module Suites benutzt).

Mein Projektsetup sieht nun so aus:

Der Server ist eine Module Suite (ohne GUI), welche folgende Module enthält:
- WorkbenchServerBase: enthält den Code, welchen jeder der geplanten Server benötigt (login, handling object model, persistenzschicht, ...)
- WorkbenchCommonInterfaces: enthält bisher nur die Interfaces zum Austausch zwischen Client & Server
- Simon (library wrapper module)

Der Admin-*Client* (der erste, den ich schreibe, mit GUI), ist ebenfalls eine Module Suite, welche folgende Module enthält:
- WorkbenchClientBase: enthält den Code, welchen jeder der geplanten Clients benötigt (login, session handling, logout, ...)
Ausserdem importiert er die Module WorkbenchCommonInterfaces und Simon vom Server.

Der Server fährt sauber hoch und wartet auf requests.

Beim Versuch, sich am Server anzumelden (in der restored() Methode des Modul-Installers von WorkbenchClientBase), bekommt jedoch der Client folgenden trace:

INFO [de.hermannmatthes.workbench.base.client.Installer]: connecting
SEVERE [org.netbeans.core.modules]
de.root1.simon.exceptions.SimonRemoteException: session was closed. sessionid=0x00000002
at de.root1.simon.Dispatcher.interruptWaitingRequests(Dispatcher.java:761)
at de.root1.simon.Dispatcher.sessionClosed(Dispatcher.java:812)
at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.sessionClosed(DefaultIoFilterChain.java:665)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextSessionClosed(DefaultIoFilterChain.java:395)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$900(DefaultIoFilterChain.java:46)
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.sessionClosed(DefaultIoFilterChain.java:781)
at org.apache.mina.filter.codec.ProtocolCodecFilter.sessionClosed(ProtocolCodecFilter.java:387)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextSessionClosed(DefaultIoFilterChain.java:395)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$900(DefaultIoFilterChain.java:46)
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.sessionClosed(DefaultIoFilterChain.java:781)
at org.apache.mina.core.filterchain.IoFilterAdapter.sessionClosed(IoFilterAdapter.java:95)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextSessionClosed(DefaultIoFilterChain.java:395)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireSessionClosed(DefaultIoFilterChain.java:388)
at org.apache.mina.core.service.IoServiceListenerSupport.fireSessionDestroyed(IoServiceListenerSupport.java:244)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.removeNow(AbstractPollingIoProcessor.java:580)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.removeSessions(AbstractPollingIoProcessor.java:540)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$600(AbstractPollingIoProcessor.java:67)
at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:1087)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
[catch] at java.lang.Thread.run(Thread.java:662)
INFO [org.netbeans.core.startup.NbEvents]: Aktiviere Module:
org.openide.util.lookup [8.3.1 201008030030]
org.openide.util [8.6.1 201008030030]
org.openide.modules [7.17.1 201008030030]
de.hermannmatthes.workbench.common.interfaces [1.0 110726]
org.netbeans.bootstrap/1 [2.33.1 201008030030]
de.root1.simon [1.1.2 110726]
org.openide.filesystems [7.38.2 201008030030]
org.netbeans.core.startup/1 [1.25.1 201008030030]
de.hermannmatthes.workbench.base.client [1.0 110726]
SEVERE [org.openide.util.Exceptions]
java.lang.ClassNotFoundException: de.hermannmatthes.workbench.common.interfaces.ILogin
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at org.netbeans.ProxyClassLoader.loadClass(ProxyClassLoader.java:262)
Caused: java.lang.ClassNotFoundException: de.hermannmatthes.workbench.common.interfaces.ILogin starting from ModuleCL@2f8116[de.root1.simon] with possible defining loaders [ModuleCL@bef361[de.hermannmatthes.workbench.common.interfaces]] and declared parents []
at org.netbeans.ProxyClassLoader.loadClass(ProxyClassLoader.java:264)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at de.root1.simon.codec.base.MsgNameLookupReturnDecoder.decodeBody(MsgNameLookupReturnDecoder.java:62)
at de.root1.simon.codec.base.AbstractMessageDecoder.decode(AbstractMessageDecoder.java:97)
at org.apache.mina.filter.codec.demux.DemuxingProtocolDecoder.doDecode(DemuxingProtocolDecoder.java:178)
at org.apache.mina.filter.codec.CumulativeProtocolDecoder.decode(CumulativeProtocolDecoder.java:178)
at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:241)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:434)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1200(DefaultIoFilterChain.java:46)
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:796)
at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:119)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:434)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:426)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:693)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:646)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:635)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$400(AbstractPollingIoProcessor.java:67)
at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:1079)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
Caused: de.root1.simon.exceptions.SimonException: An error occured while reading a message. Error message: Error while decoding name lookup return: Not able to load interfaces due to ClassNotFoundException
at de.root1.simon.ProcessMessageRunnable.processError(ProcessMessageRunnable.java:700)
at de.root1.simon.ProcessMessageRunnable.run(ProcessMessageRunnable.java:178)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
[catch] at java.lang.Thread.run(Thread.java:662)

Der Server läuft noch. Was mache ich falsch? Ist das ein Netbeans spezifisches class loader problem?

Ich weiss, dass dies alles ziemlich chaotisch aussieht. Vielleicht kannst Du mir ja trotzdem helfen.

Vielen Dank für die Mühe
Hermann


Replies (10)

RE: ClassNotFoundException mit Netbeans - Added by achristian 10 months ago

Hallo Hermann,

hab mit der Netbeans-Platform Entwicklung noch nicht viel Erfahrung, arbeite mich gerade erst ein. Aber so wie es scheint hast du recht:

Ist das ein Netbeans spezifisches class loader problem?

Sieht so aus, denn:

Caused: java.lang.ClassNotFoundException: de.hermannmatthes.workbench.common.interfaces.ILogin starting from ModuleCL@2f8116[de.root1.simon] with possible defining loaders [ModuleCL@bef361[de.hermannmatthes.workbench.common.interfaces]] and declared parents []
at org.netbeans.ProxyClassLoader.loadClass(ProxyClassLoader.java:264)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at de.root1.simon.codec.base.MsgNameLookupReturnDecoder.decodeBody(MsgNameLookupReturnDecoder.java:62)

Ganz unten sieht man wie das Return-Paket für den Name-Lookup versucht wird zu dekodieren. Darin wird die benötigte Klasse "ILogin" versucht zu laden. Und das schlägt im Netbeans Proxy-Classloader fehl...

Für solche fälle hab ich vor längerem eine (noch nicht javadoc dokumentierte) Methode zum setzen des Classloaders eingebaut: http://hudson.root1.de/job/SIMON%20-%20trunk/javadoc/de/root1/simon/Lookup.html#setClassLoader%28java.lang.ClassLoader%29

Damit kannst du den Classloader angeben der die Klasse laden soll. Allerdings bin ich mir wegen der Netbeans-Platform nicht sicher welchen CL du da angeben sollst.

Aber ich bin mir eigentlich sicher dass das auch ohne diesen "hack" gehen müsste.

Der Admin-*Client* (der erste, den ich schreibe, mit GUI), ist ebenfalls eine Module Suite, welche folgende Module enthält:
- WorkbenchClientBase: enthält den Code, welchen jeder der geplanten Clients benötigt (login, session handling, logout, ...)
Ausserdem importiert er die Module WorkbenchCommonInterfaces und Simon vom Server.

Wenn ich das "chaos" richtig verstehe, dann steckt der Code, der den Lookup macht in "WorkbenchClientBase". Der Code der das Laden dann veranlässt, steckt im Modul "SIMON", die zu ladende Klasse in "WorkbenchCommonInterfaces".

Mein beschränktes Netbeans-Platform Wissen sagt mir, dass man die Klassen und Pakete in Modul A einem Modul-B zugänglich machen kann. Glaub das geht über die Manifest-Datei. Somit müsste das SIMON-Modul eine Dependency zum WorkbenchCommonInterface (welches die Interfaces öffentlich zugänglich konfiguriert hat), und das WorkbenchClientBase-Modul eine Dependency zum SIMON-Modul haben.
Aber ich nehme fast mal an dass du schon so schlau warst und das entsprechend etwas konfiguriert hast, oder?

Gruß
Alex

RE: ClassNotFoundException mit Netbeans - Added by timekeeper 10 months ago

Hallo Alex,
dies ist eine email, welche ich gestern in der NBDEV user group gepostet habe:

Hello all,
it seems like I have a build or class loader issue.

I implemented 2 module suites (using ant):

The server suite contains

  • a module A , which defines the interfaces and implements the classes both applications (client &server) need.
  • a library wrapper module B which contains the communication library and
  • a server specific module

The client suite contains

  • modules A and B (using Add Project.. in the suite properties)
  • a client specific module

Build is ok, but after starting the client I get the following exception:

Caused: java.lang.ClassNotFoundException: de.hermannmatthes.workbench.common.interfaces.ILogin starting from
    ModuleCL@bef361[de.root1.simon] with possible defining loaders [ModuleCL@867fc9[de.hermannmatthes.workbench.common.interfaces]] and declared parents []

Here is the (compressed) output of the launcher (no setting contains my module A or B):

Boot & Ext. Classpath   =
    C:\Program Files (x86)\Java\jdk1.6.0_23\jre\lib\resources.jar;
    C:\Program Files (x86)\Java\jdk1.6.0_23\jre\lib\rt.jar;
    C:\Program Files (x86)\Java\jdk1.6.0_23\jre\lib\sunrsasign.jar;
    C:\Program Files (x86)\Java\jdk1.6.0_23\jre\lib\jsse.jar;
    C:\Program Files (x86)\Java\jdk1.6.0_23\jre\lib\jce.jar;
    C:\Program Files (x86)\Java\jdk1.6.0_23\jre\lib\charsets.jar;
    C:\Program Files (x86)\Java\jdk1.6.0_23\jre\lib\modules\jdk.boot.jar;
    C:\Program Files (x86)\Java\jdk1.6.0_23\jre\classes;
    C:\Program Files (x86)\Java\jdk1.6.0_23\jre\lib\ext\dnsns.jar;
    C:\Program Files (x86)\Java\jdk1.6.0_23\jre\lib\ext\localedata.jar;
    C:\Program Files (x86)\Java\jdk1.6.0_23\jre\lib\ext\sunjce_provider.jar;
    C:\Program Files (x86)\Java\jdk1.6.0_23\jre\lib\ext\sunmscapi.jar;
    C:\Program Files (x86)\Java\jdk1.6.0_23\jre\lib\ext\sunpkcs11.jar

Application Classpath   =
    C:\Program Files (x86)\NetBeans 6.9.1\platform\lib\boot.jar;
    C:\Program Files (x86)\NetBeans 6.9.1\platform\lib\org-openide-modules.jar;
    C:\Program Files (x86)\NetBeans 6.9.1\platform\lib\org-openide-util-lookup.jar;
    C:\Program Files (x86)\NetBeans 6.9.1\platform\lib\org-openide-util.jar;
    C:\Program Files (x86)\NetBeans 6.9.1\platform\lib\locale\boot_ar_SA.jar;
    ... (different locales)
    C:\Program Files (x86)\NetBeans 6.9.1\platform\lib\locale\boot_zh_TW.jar;
    C:\Program Files (x86)\NetBeans 6.9.1\platform\lib\locale\org-openide-modules_ar_SA.jar;
    ... (different locales)
    C:\Program Files (x86)\NetBeans 6.9.1\platform\lib\locale\org-openide-modules_zh_TW.jar;
    C:\Program Files (x86)\NetBeans 6.9.1\platform\lib\locale\org-openide-util-lookup_ca.jar;
    ... (different locales)
    C:\Program Files (x86)\NetBeans 6.9.1\platform\lib\locale\org-openide-util-lookup_tr.jar;
    C:\Program Files (x86)\NetBeans 6.9.1\platform\lib\locale\org-openide-util_ar_SA.jar;
    ... (different locales)
    C:\Program Files (x86)\NetBeans 6.9.1\platform\lib\locale\org-openide-util_zh_TW.jar;
    C:\Program Files (x86)\Java\jdk1.6.0_23\lib\dt.jar;C:\Program Files (x86)\Java\jdk1.6.0_23\lib\tools.jar

 Startup Classpath       =
    C:\Program Files (x86)\NetBeans 6.9.1\platform\core\core.jar;
    C:\Program Files (x86)\NetBeans 6.9.1\platform\core\org-openide-filesystems.jar;
    C:\Program Files (x86)\NetBeans 6.9.1\platform\core\locale\core_ar_SA.jar;
    ... (different locales)
    C:\Program Files (x86)\NetBeans 6.9.1\platform\core\locale\core_zh_TW.jar;
    C:\Program Files (x86)\NetBeans 6.9.1\platform\core\locale\org-openide-filesystems_ar_SA.jar;
    ... (different locales)
    C:\Program Files (x86)\NetBeans 6.9.1\platform\core\locale\org-openide-filesystems_zh_TW.jar;
    D:\Users\Hermann\Entwicklung\Projekte3\WorkbenchServerSuite\build\cluster\core\locale\core_workbenchserver.jar
My client suite build directory (...\build\public-package-jars) contains the correct jars:
  • de-hermannmatthes-workbench-common-interfaces.jar (Module A)
  • de-root1-simon.jar (Module B)
  • org-openide-modules.jar and
  • org-openide-util.jar

Do I have a build or a classpath issue?
Can anybody tell me how to solve it?

Thanks a lot in advance
Hermann

Mir ist nämlich mit meinem 3/4-Wissen noch aufgefallen, dass anscheinend nicht der Class-Loader das Problem ist, sondern der build. Anscheinend werden die libraries gar nicht in den CLASSPATH gestellt. Wenn ich Näheres erfahre, werde ich Dich hier informieren.

Hermann

RE: ClassNotFoundException mit Netbeans - Added by timekeeper 10 months ago

Hallo Christian,
es ist anscheinend doch ein class loader Problem.

Hier der output beim Starten des Clients:

INFO [de.hermannmatthes.workbench.base.client.Installer]: connecting
SEVERE [org.netbeans.core.modules]
de.root1.simon.exceptions.SimonRemoteException: session was closed. sessionid=0x00000002
        at de.root1.simon.Dispatcher.interruptWaitingRequests(Dispatcher.java:761)
        at de.root1.simon.Dispatcher.sessionClosed(Dispatcher.java:812)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.sessionClosed(DefaultIoFilterChain.java:665)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextSessionClosed(DefaultIoFilterChain.java:395)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$900(DefaultIoFilterChain.java:46)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.sessionClosed(DefaultIoFilterChain.java:781)
        at org.apache.mina.filter.codec.ProtocolCodecFilter.sessionClosed(ProtocolCodecFilter.java:387)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextSessionClosed(DefaultIoFilterChain.java:395)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$900(DefaultIoFilterChain.java:46)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.sessionClosed(DefaultIoFilterChain.java:781)
        at org.apache.mina.core.filterchain.IoFilterAdapter.sessionClosed(IoFilterAdapter.java:95)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextSessionClosed(DefaultIoFilterChain.java:395)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireSessionClosed(DefaultIoFilterChain.java:388)
        at org.apache.mina.core.service.IoServiceListenerSupport.fireSessionDestroyed(IoServiceListenerSupport.java:244)
        at org.apache.mina.core.polling.AbstractPollingIoProcessor.removeNow(AbstractPollingIoProcessor.java:580)
        at org.apache.mina.core.polling.AbstractPollingIoProcessor.removeSessions(AbstractPollingIoProcessor.java:540)
        at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$600(AbstractPollingIoProcessor.java:67)
        at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:1087)
        at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
[catch] at java.lang.Thread.run(Thread.java:662)
INFO [org.netbeans.core.startup.NbEvents]: Aktiviere Module:
        org.openide.util.lookup [8.3.1 201008030030]
        org.openide.util [8.6.1 201008030030]
        org.openide.modules [7.17.1 201008030030]
        de.root1.simon [1.1.2 110728]
        org.netbeans.bootstrap/1 [2.33.1 201008030030]
        de.hermannmatthes.workbench.common.interfaces [1.0 110728]
        de.hermannmatthes.workbench.common.rules [1.0 110728]
        org.openide.filesystems [7.38.2 201008030030]
        de.hermannmatthes.workbench.base.client [1.0 110728]
        de.hermannmatthes.workbench.admin.gui [1.0 110728]
        org.netbeans.core.startup/1 [1.25.1 201008030030]
SEVERE [org.openide.util.Exceptions]
java.lang.ClassNotFoundException: de.hermannmatthes.workbench.common.interfaces.ILogin
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
        at org.netbeans.ProxyClassLoader.loadClass(ProxyClassLoader.java:262)
Caused: java.lang.ClassNotFoundException: de.hermannmatthes.workbench.common.interfaces.ILogin starting from ModuleCL@1bf7b23[de.root1.simon] with possible defining loaders [ModuleCL@2b349d[de.hermannmatthes.workbench.common.interfaces]] and declared parents []
        at org.netbeans.ProxyClassLoader.loadClass(ProxyClassLoader.java:264)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:169)
        at de.root1.simon.codec.base.MsgNameLookupReturnDecoder.decodeBody(MsgNameLookupReturnDecoder.java:62)
        at de.root1.simon.codec.base.AbstractMessageDecoder.decode(AbstractMessageDecoder.java:97)
        at org.apache.mina.filter.codec.demux.DemuxingProtocolDecoder.doDecode(DemuxingProtocolDecoder.java:178)
        at org.apache.mina.filter.codec.CumulativeProtocolDecoder.decode(CumulativeProtocolDecoder.java:178)
        at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:241)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:434)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1200(DefaultIoFilterChain.java:46)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:796)
        at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:119)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:434)
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:426)
        at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:693)
        at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:646)
        at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:635)
        at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$400(AbstractPollingIoProcessor.java:67)
        at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:1079)
        at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
Caused: de.root1.simon.exceptions.SimonException: An error occured while reading a message. Error message: Error while decoding name lookup return: Not able to load interfaces due to ClassNotFoundException
        at de.root1.simon.ProcessMessageRunnable.processError(ProcessMessageRunnable.java:700)
        at de.root1.simon.ProcessMessageRunnable.run(ProcessMessageRunnable.java:178)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
[catch] at java.lang.Thread.run(Thread.java:662)

Vielleicht ist es ein Reihenfolgen-Problem: Mein Login-Dialog läuft im Installer eines Modules. Anschliessend erfolgt der connect. Der trace suggeriert, dass die restlichen Module erst später geladen werden. Kann natürlich auch daran liegen, dass ein INFO-log gepuffert ist und ein exception output wahrscheinlich nicht.

Hermann

RE: ClassNotFoundException mit Netbeans - Added by timekeeper 10 months ago

Hallo Alex,
auch wenn ich den connect verzögere, bis definitiv alle anderen Module geladen werden konnten, bekomme ich denselben Fehler.

Hier die anscheinend entscheidenden Zeilen:

Caused by: java.lang.ClassNotFoundException: de.hermannmatthes.workbench.common.interfaces.ILogin starting from ModuleCL@970c0e[de.root1.simon] with possible defining loaders [ModuleCL@12e7c6a[de.hermannmatthes.workbench.common.interfaces]] and declared parents []
        at org.netbeans.ProxyClassLoader.loadClass(ProxyClassLoader.java:264)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:169)
        at de.root1.simon.codec.base.MsgNameLookupReturnDecoder.decodeBody(MsgNameLookupReturnDecoder.java:62)

Ich kenne mich mit class loadern zuwenig aus, als dass ich hier eine qualifizierte Aussage machen könnte. Es steht zumindest das richtige package (de.hermannmatthes.workbench.common.interfaces) drin.

Verwendest Du einen eigenen class loader ? Netbeans hat einen eigenen und das Problem könnte daran liegen, dass Du nicht denselben verwendest.

Weisst Du, wie das mit den class loadern in SIMON funktioniert?

Hermann

RE: ClassNotFoundException mit Netbeans - Added by achristian 10 months ago

Verwendest Du einen eigenen class loader ?

Nein.

Netbeans hat einen eigenen und das Problem könnte daran liegen, dass Du nicht denselben verwendest.

Da ich nicht immer weiß in welchem Kontext SIMON läuft, weiß ich auch nicht welchen CL ich nehmen soll. Also nehm' ich den Standard-CL, und das ist der, der auch SIMON geladen hat.

Weisst Du, wie das mit den class loadern in SIMON funktioniert?

Klaro. ich habs ja implementiert ;-)
Beim Lookup sendet der Client eine Anfrage an den Server, welcher mit einer Liste von Interface-Namen antwortet die das Remote-Objekt implementiert. Der Client muss dann diese Interfaceklassen laden und ein passendes Proxy-Objekt erstellen. Das Lesen der Interfacenamen und das Laden der Interfaceklassen findet hier statt:

http://dev.root1.de/projects/simon/repository/entry/trunk/src/main/java/de/root1/simon/codec/base/MsgNameLookupReturnDecoder.java (Zeile 56-66):

 1            int arraySize = in.getInt();
 2            logger.trace("trying to read interfaces value. num of interfaces: {}", arraySize);
 3            Class<?>[] interfaces = new Class<?>[arraySize];
 4            for (int i = 0; i < arraySize; i++) {
 5                String iface = in.getPrefixedString(Charset.forName("UTF-8").newDecoder());
 6                logger.trace("Loading interface: [{}]",iface);
 7                interfaces[i] = Class.forName(iface);
 8                logger.trace("got interface=[{}]", interfaces[i].getCanonicalName());
 9            }
10            m.setErrorMsg(in.getPrefixedString(Charset.forName("UTF-8").newDecoder()));
11            m.setInterfaces(interfaces);

Mit Class.forName(...) wird das Interface geladen. Und in der JavaDoc dazu steht:

Returns the Class object associated with the class or
interface with the given string name. Invoking this method is
equivalent to:

Class.forName(className, true, currentLoader)

where currentLoader denotes the defining class loader of
the current class.

Der CL den man in der NameLookup-Klasse angeben kann wird dann beim erstellen des Proxy-Objekts genutzt. Eventuell könnte ich hier noch nachbessern, damit dieser CL auch beim laden der Remoteinterfaceklassen genutzt wird. Aber im Default-Fall gilt die Regel: Der CL, der SIMON geladen hat, der muss auch die Remote-Interfaces laden können. Ansonsten kommt's zu obigem Fehler.

Wär's möglich dass du ein kurzes, kompilierbares und ausführbares Sample bastelst und an diesen Thread anhängst, damit ich das hier lokal debuggen kann? Die Sache mit den Classloadern ist via Forum schwer zu debuggen/analysieren...

Gruß
Alex

RE: ClassNotFoundException mit Netbeans - Added by timekeeper 10 months ago

Hallo Christian,
hier eine Antwort aus dem Netbeans-Forum:

> When I create the NBM's, no *.nbm is generated for the modules of the other suite.

Right, update centers are generated per suite. If you want your app to include two update centers, you can do that easily.

But this would not seem to have anything to do with a ClassNotFoundException. If a module is entirely missing when an app is run, in any mode, the module system will simply prevent any modules depending on that module from being enabled either - well before there is a chance for a CNFE to occur.

So perhaps you are encountering some other problem. Narrow it down to a minimal, reproducible test case, and in the process you may well figure out where you went wrong, unless it is genuinely a NB bug.

Sobald ich Zeit habe, stelle ich ein Testbeispiel zusammen.
Hermann

RE: ClassNotFoundException mit Netbeans - Added by timekeeper 10 months ago

Hallo Alex,
leider schaffe ich es nicht, ein "kleines" Beispiel zusammenzustellen.

Deshalb habe ich meine Projektstruktur gezippt und auf meinem Webserver abgelegt. Die Datei hat insgesamt 1,7 MB. Du kannst sie unter http://hermannmatthes.de/timekeeper/temp/Projekte4.zip herunterladen.

Sie enthält folgende Projektstruktur (siehe auch attachment):
  • Die WB Common Suite (WB=Workbench) enthält alle Module, die sowohl Client auch als Server benötigen. Hier ist auch Deine Simon-Bibliothek enthalten sowie das Interfaces-Modul. Das Interface-Modul enthält das Interface, welches die ClassNotFoundException auslöst.
  • Die WB Server Base Suite enthält alle Module, welche jeder Server benötigt. Sie verwendet alle Module der Common Suite. Hier liegen z.B. die Implementierungen des Login-Interfaces und des Admin-Interfaces
  • Die WB Server Timekeeper Suite verwendet nun alle Module der WB Common Suite und der WB Server Base Suite. Sie hat bisher keine eigene Funktion.
  • Die WB Client Base Suite enthält nun alle Module der Common Suite und stellt (derzeit nur) den Login zur Verfügung.
  • Die WB Client Admin Suite ist das GUI-Frontend zur Administration der Server (derzeit noch ohne viel Funktion).

Zum debuggen must Du zunächst alle Suiten builden (in obiger Reihenfolge) und dann die WB Server Timekeeper Suite starten. Sie meldet sich nach erfolgreichem Hochfahren mit
INFO [de.hermannmatthes.workbench.server.base.core.main.DefaultServerImpl]: Server 'testServer' up and running on port 32.988 ! im Output-Fenster von Netbeans (Ich verwende übrigens Version 6.9.1).

Anschliessend startest Du die WB Client Admin Suite im debug-modus. Die Methode, welche die Verbindung zum Server herstellt und in welcher die ClassNotFoundException auftritt ist
de.hermannmatthes.workbench.client.base.login.Installer.login() im Modul WB Client Base Login der Module Suite WB Client Base Suite. Hier solltest Du einen breakpoint setzen.

Beim Start des Clients erscheint ein Login-Dialog. Dort must Du zunächt über den Knopf "Neu..." eine neue Verbindung einrichten. Trage bitte unter Name 'testServer', unter Internetaddresse 'localhost' und unter Port '32988' ein. Das sind die derzeitigen Connect-Daten des gestarteten Servers. Nach dem Bestätigen noch auf "Verbinden" klicken und dann solltest Du im breakpoint stehen.

Wenn Du noch Fragen hast, melde Dich bitte bei mir. Auf meiner homepage gibt es auch einen "Kontakt"-Button, über welchen Du mir direkt eine mail schicken kannst.

Herzlichen Dank für Deine Mühe
Hermann

RE: ClassNotFoundException mit Netbeans - Added by achristian 10 months ago

Hallo Hermann,

Bekomme ebenfalls reproduzierbar die CNFE. Eine erste Analyse hat gezeigt, dass SIMON mit dem Classloader des Moduls WM Common Simon geladen wurde (ergibt ja auch Sinn). Aber von da aus scheints keinen Zugriff auf Klassen aus WB Common Interfaces zu geben. Hab dann versucht WB Common Simon eine Dependency zu WM Common Interfaces hinzuzufügen um an die Klassen ranzukommen. Hat aber nicht den gewünschten Erfolg gebracht.

Wie ich zuletzt schon schrieb: Ich werde wohl das setzen des Classloaders in der Lookup-Klasse überarbeiten müssen..

Hab eben mal SIMON 1.2.0-SNAPSHOT um diesen Fix ergänzt und mit deinem Sample ausprobiert: Geht!

Der Trick wäre nun:

In deiner Installer-Klasse musst du eine Zeile ergänzen:

1// 'lookup' the server object
2LOG.info("connecting");
3nameLookup = Simon.createNameLookup(hostname, port);
4nameLookup.setClassLoader(ILogin.class.getClassLoader()); // <--- DIESE ZEILE ERGÄNZEN

Aus der Installer-Klasse heraus kommt man ja prima an die ILogin-Klasse (und alle anderen Remote-Interfaces). Deshalb diese Klasse nach ihrem CL fragen und der Lookup-Klasse mitteilen.

Wie gesagt, funktioniert nun. Setzt allerdings eine neue 1.2.0-SNAPSHOT Version vorraus. Diese bekommst du hier: http://nexus.root1.de/content/repositories/snapshots//de/root1/simon/1.2.0-SNAPSHOT/simon-1.2.0-20110730.162105-24-jar-with-dependencies.jar (1.2.0-SNAPSHOT ist von der Stabilität her mit 1.1.2 vergleichbar)

Da das Modul mit der Installer-Klasse auf die Interfaces zugreifen kann, müsste sich das auch für das Simon-Modul einrichten lassen. Dann braucht's diesen Fix nicht. Aber ich bin noch nicht dahinter gekommen wie man das mit Netbeans macht.

Gruß
Alex

RE: ClassNotFoundException mit Netbeans - Added by timekeeper 10 months ago

Aber ich!

Hurra, es funktioniert!

Ist ja auch völlig logisch. Das SIMON-Modul braucht eine dependency auf das interfaces-Modul. Man muss einfach nur in den Properties des SIMON-Moduls die anderen Module der Common Suite als dependency eintragen und alles neu builden.

Super, danke für die tolle Unterstützung.

Hermann

RE: ClassNotFoundException mit Netbeans - Added by achristian 10 months ago

Hmm, hatte ich auch so gemacht. Mit dem Unterschied dass ich dem SIMON Modul nur eine Dependency zum Interface Modul gegeben habe, und nicht zu allen Common Modulen. Hatte irgendwie nicht funktioniert. Aber gut dass es jetzt geht, und zwar ohne Workaround...

Gruß
Alex

(1-10/10)