# Exception javax.naming.CommunicationException



## Gast (27. Nov 2008)

hab einen Swing-Client, der per RMI auf einen JBoss 4.0.5 (PC mit Vista) zugreift. 

Der Swing-Client läuft auf WinXP und führt die Dienste auf dem JBoss ordnungsgemäß aus. Wenn der gleiche Swing-Client auf einer grafischen Linuxoberfläche läuft (Debian/Gnome), gibt es eine Exception. 
javax.naming.CommunicationException [Root exception is java.lang.ClassNotFoundException: project.query.projectQHome] 



```
Properties objProperties = new Properties(); 
 objProperties.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory"); 
 objProperties.put(Context.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces"); 
 objProperties.put(Context.PROVIDER_URL, "localhost:2001" ); 

 javax.naming.InitialContext initial = new javax.naming.InitialContext(objProperties); 
  
 NamingEnumeration ne=initial.list(""); 
 while(ne.hasMore()) 
 { 
  System.out.println("Bind Objects :"+ne.next()); 
 } 
/*ergibt 
Bind Objects :project_projectQ: $Proxy58 
Bind Objects :projectD_adminE: $Proxy87 
Bind Objects :project_adminE: $Proxy64 
Bind Objects :project_ServiceContext: $Proxy70 
Bind Objects :TopicConnectionFactory: org.jboss.naming.LinkRefPair 
Bind Objects :projectD_projectDE: $Proxy85 
Bind Objects :jmx: org.jnp.interfaces.NamingContext 
Bind Objects :projectD_ServiceContext: $Proxy93 
Bind Objects :project_projectE: $Proxy62 
Bind Objects :HTTPXAConnectionFactory: org.jboss.mq.SpyXAConnectionFactory 
Bind Objects :ConnectionFactory: org.jboss.mq.SpyConnectionFactory 
Bind Objects :UserTransactionSessionFactory: $Proxy12 
Bind Objects :HTTPConnectionFactory: org.jboss.mq.SpyConnectionFactory 
Bind Objects :XAConnectionFactory: org.jboss.mq.SpyXAConnectionFactory 
Bind Objects :UserTransaction: org.jboss.tm.usertx.client.ClientUserTransaction 
Bind Objects :UILXAConnectionFactory: javax.naming.LinkRef 
Bind Objects :project_projectS: $Proxy66 
Bind Objects :UIL2XAConnectionFactory: javax.naming.LinkRef 
Bind Objects :projectD_AdminS: $Proxy91 
Bind Objects :project_AdminS: $Proxy68 
Bind Objects :queue: org.jnp.interfaces.NamingContext 
Bind Objects :topic: org.jnp.interfaces.NamingContext 
Bind Objects :console: org.jnp.interfaces.NamingContext 
Bind Objects :UIL2ConnectionFactory: javax.naming.LinkRef 
Bind Objects :projectD_adminQ: $Proxy83 
Bind Objects :project_adminQ: $Proxy60 
Bind Objects :HiLoKeyGeneratorFactory: org.jboss.ejb.plugins.keygenerator.hilo.HiLoKeyGeneratorFactory 
Bind Objects :UILConnectionFactory: javax.naming.LinkRef 
Bind Objects :projectD_projectDS: $Proxy89 
Bind Objects :projectD_projectDQ: $Proxy81 
Bind Objects :QueueConnectionFactory: org.jboss.naming.LinkRefPair 
Bind Objects :UUIDKeyGeneratorFactory: org.jboss.ejb.plugins.keygenerator.uuid.UUIDKeyGeneratorFactory 
*/ 

 //hier die Exception obwohl project_projectQ gebunden 
 Object ref=initial.lookup("project_projectQ");
```


Beim lookup passiert es: 

```
Object obj = initial.lookup("project_projectQ");                
 projectQHome home = (projectQHome) javax.rmi.PortableRemoteObject.narrow(obj, projectQHome.class);                
 projectQ con_project = home.create();
```
nicht etwa Object 'obj' ist null sondern offensichtlích 'initial.lookup("project_projectQ")' 
obwohl das project_projectQ eigentlich im *initial* gebunden ist (s.o.).


----------



## Guest (28. Nov 2008)

Ich fasse nochmal zusammen:

Es wird eine Exception beim Swing-Client auf der Debian-Maschine geworfen, und zwar hier:

initial.lookup("project_projectQ");

Die Exception lautet:
java.lang.ClassNotFoundException: *project.query.projectQHome*
(in diesem Moment gibt es keine einzige Reaktion im Server-Log des JBoss (der Vista-Maschine), auch nicht im Debug-Modus)

Die project.query.projectQHome ist bei uns ein Interface in einer project.ear, die auf dem JBoss (der Vista-Maschine) deployed ist.

Das Interface project.query.projectQHome existiert nicht in der .jar-Datei des Swing-Client (und soll dort auch nicht existieren).

Bisher hatte ich mich nicht darum gekümmert, weil der Swing-Client völlig problemlos auch auf Vista- und WinXP-Maschinen läuft, die im Grunde nichts mit der Client-Entwicklung zu tun haben und lediglich über eine jre 1.6.0 verfügen und auch keinen speziellen SET CLASSPATH besitzen.

Der Swing-Client läuft also völlig konfliktfrei auf diversen Machinen, auf denen nur ein Netzwerkzugang und jre 1.6.0 vorhanden sein muss.


Auf der Debian-Maschine laufen alle Funktionalitäten des Swing-Client normal, auch ein Email-Versand funktioniert reibungslos,
aber hier wirfts die Exception schon nur beim Versuch von initial.lookup("project_projectQ"),
als wenn die Kommunikation nicht klappen würde. Dabei sind alle Ports des JBoss (der Vista-Maschine) von der Debian-Maschine aus erreichbar/sichtbar.

Hauptfragestellung:
1.
Warum funtioniert das initial.lookup("project_projectQ") nicht auf der Debian-Maschine?
2.
Woher kennt die Exception den Namen des Interfaces project.query.projectQHome?
3.
Warum können die in der Variable javax.naming.InitialContext *initial* = new javax.naming.InitialContext(objProperties); offensichtlich vorhandenen Informationen für das Naming-Objekt "project_projectQ" im *initial*.lookup("project_projectQ"); nicht genutzt werden?


----------



## maki (28. Nov 2008)

project.query.projectQHome scheint nicht im Classpath zu sein.


----------



## Guest (28. Nov 2008)

> Der Swing-Client läuft also völlig konfliktfrei auf diversen Machinen, auf denen nur ein Netzwerkzugang und jre 1.6.0 vorhanden sein muss.


----------



## maki (28. Nov 2008)

Was ich verwirrend finde ist die Exception im Titel, die eine andere ist als die ClassNotFoundException.

Poste doch mal den gesamten Stacktrace.


----------



## Gast (28. Nov 2008)

javax.naming.CommunicationException [Root exception is java.lang.ClassNotFoundException: project.query.projectQHome]


----------



## Guest (28. Nov 2008)

> Auf der Debian-Maschine laufen alle Funktionalitäten des Swing-Client normal, auch ein Email-Versand funktioniert reibungslos,
> aber hier wirfts die Exception schon nur beim Versuch von initial.lookup("project_projectQ"),
> als wenn die Kommunikation nicht klappen würde.


----------



## FArt (28. Nov 2008)

Die ClassNotFound geschieht während der Kommunikation und wenn sie nicht gefunden wird, ist sie nicht im Klassenpfad. Es könnte auch sein, dass es bei der Klasse statische Initialisierunge geschehen, die dann fehlschlagen und deswegen die Klasse nicht geladen werden kann...  das könnte sich auch so äußern...


----------



## Gast (28. Nov 2008)

Also nach meinem Verständnis müsste RMI wie folgt ablaufen:

1.
Der Server registriert ein remote-Objekt, bounded zu einem Namen
2.
Der Client macht einen naming-lookup-Aufruf
3.
Die RMI-Registry bringt eine Instanz von dem remote-Objekt zurück
4.
Der Client macht einen request auf die Klasse der codebase des Servers
5.
Der HTTP-Server bringt das remote-Objekt zum Client zurück

Das Problem tritt wohl beim Punkt 2. auf. 

Kann man da irgendwie näher in diesem Prozessablauf 'reinhorchen'?


----------



## FArt (28. Nov 2008)

Gast hat gesagt.:
			
		

> Also nach meinem Verständnis müsste RMI wie folgt ablaufen:
> 
> 1.
> Der Server registriert ein remote-Objekt, bounded zu einem Namen
> ...



Du redest von RMI und HTTP-Server... irgendwie verwirrend.

Annahme: du machst einfach einen Standarlookup auf ein EJB. Das Proxyobjekt auf Clientseite, welches den Beanstub darstellt, erzeugt den Fehler.
Welcher Invoker wird verwendet? IIOP?

Du kannst das Logging auf TRACE stellen, sowohl auf Server- als auch auf Clientseite. Dann sollte er sehr gesprächig werden. Wie das geht, steht im Beispiel log4j.xml bzw. in der Doku und im Wiki von JBoss.... dennoch ist die Fehlermeldung schon sehr aussagekräftig ;-)

Sieh nach ob das Interface geladen werden kann. Auch alles, was dieses Interface refernziert. Ist das JAR vorhanden und im Klassenpfad? Hat der User, unter dem der Client läuft auch Leserechte auf das JAR?


----------



## Guest (1. Dez 2008)

Der Swing-Client läuft fehlerfrei auf x-beliebigen Windows-Maschinen (nur jre 1.6.0 installiert und Netzwerkkontakt zum JBoss der Vista-Maschine). 

Auf der Debian-Maschine wird eine Exception geworfen, und zwar hier: 

initial.lookup("project_projectQ"); 

Die Exception lautet: 
javax.naming.CommunicationException [Root exception is java.lang.*ClassNotFoundException: project.query.projectQHome] *

Die project.query.projectQHome ist ein Interface in einer project.ear, die auf dem JBoss (der Vista-Maschine) deployed ist. 


```
package project.query; 
public interface projectQHome extends javax.ejb.EJBHome { 
    public projectQ create() throws java.rmi.RemoteException, javax.ejb.CreateException; 
}
```
*Wenn dieses Interface in der .jar-Datei des Swing-Client eingebunden wird, funktioniert der Aufruf auch auf der Debian-Maschine!! *

Warum funktioniert das Einbinden des Interfaces project.query.projectQHome aus der project.ear des JBoss bei der Debian-Maschine nicht? Laufen da Threads, die die Kommunikation bzw. den Download des Interfaces verpassen?


----------



## FArt (1. Dez 2008)

Nur nebenbei: projectQHome ist ein seltsamer Name für ein Interface, auch weil es jeglichen Konventionen widerspricht.

Zum Thema:
Das Home-Interface und das Remote-Interface des Beans müssen im Klassenpfad des Clients vorhanden sein, sonst klappt es nicht. (zumindest bei EJB2). 

Gibt es einen speziellen Mechanismus des JBoss und einen speziellen Client-Classloader (evtl. vergraben in dem Proxy, der den generischen Bean-Stub realisiert), der Ressourcen vom Server nachlädt oder ist das bei EJB3 unnötig (da es das Home-Interface in dieser Art nicht mehr gibt)? Mir wäre ein solcher Mechanismus nicht bekannt, aber ich kenne auch nicht alle Geheimnisse des JBoss.



> Der Swing-Client läuft fehlerfrei auf x-beliebigen Windows-Maschinen (nur jre 1.6.0 installiert und Netzwerkkontakt zum JBoss der Vista-Maschine).


Und wie wird der Swing-Client installiert? Per Hand? Webstart? Und wie unterscheiden sich die Klassenpfade des Swing-Clients auf den Maschinen?  Vermutung: sie sind unterschiedlich, denn einmal ist das Interface da, das andere mal nicht.


----------



## Guest (3. Dez 2008)

Ich glaube, ich bin der Lösung nahe. 

Ist das Interface project.query.ProjectQHome in der .jar-Datei des Swing-Client eingebunden, werden die Ports 2001,2000 und 4444 genutzt.

Ist dieses Interface nicht eingebunden, werden die Ports 2001,2000,4444 und *8083* genutzt.


Beim Starten des JBoss wird folgendes protokolliert:

08:47:05,244 INFO [WebService] Using RMI server codebase: *http://MAINSERV:8083*
08:47:05,986 INFO [NamingService] Started jndi bootstrap jnpPort=2001, rmiPort=2000, backlog=50, bindAddress=/192.168.1.2, Client SocketFactory=null, Server SocketFactory=org.jboss.net.sockets.DefaultSocketFactory@ad093076


Ausgerechnet der Webservice Using RMI server codebase 8083 hat hier die Einstellung auf MAINSERV. MAINSERV ist der Computername der Vista-Maschine. 

Meiner Meinung nach ist das die Ursache für die CommunicationException, da für alle Windows-Maschinen im lokalen Netzwerk der Computername 'MAINSERV' der Vista-Maschine erreichbar ist, *für alle anderen nicht*!!!

Hab schon bei der run.bat -b192.168.1.2 gesetzt, trotzdem holt sich der JBoss den Computernamen. 

Weiß jemand, wo man hier eine Einstellung für den Port 8083 vornehmen kann, um die IP-Adresse 192.168.1.2 zu nutzen?


----------



## FArt (3. Dez 2008)

Das ist der RMI ClassLoader-Mechanismus, ein Feature, welches ich aus verschiedensten Gründen (einen siehst du gerade) nicht nutze.

Konfiguriert wird der Dienst über die Datei conf/jboss-service.xml .
Ich denke aber, dass der Stub immer über die Namensauflösung geht, dazu müsste man mal in die Implementierung schauen.

Wäre es eine Alternative den Namen in die hosts-Datei einzutragen?

Meine Empfehlung ist immer noch den Mechanismus nicht zu nutzen und die Clients mit allen nötigen Ressourcen zu bestücken.


----------



## Guest (3. Dez 2008)

Da muss ich durch - die Bestückung des Clients ist keine Option.

hosts hatte nichts gebracht, 

deshalb habe ich versucht, die codebase properties für die ran.bat des JBoss zu ändern.
Die Änderungen wurden laut JBoss-Protokoll für den WebService auch angenommen, z.B.:

-Djava.rmi.server.codebase=http://192.168.1.2/
-Djava.rmi.server.codebase=http://192.168.1.2:8083/

Scheint vielleicht eine Möglichkeit zu sein, aber so funktioniert das nicht, 
denn hier übergebe ich wohl die falschen Daten. 

Die lokalen Windows-Maschinen werfen dann eine Exception, so wie vorher bei der Debian-Maschine:
javax.naming.CommunicationException [Root exception is java.lang.ClassNotFoundException: project.query.ProjectQHome]


----------



## tuxedo (4. Dez 2008)

Wo liegt denn das Problem darin dem Client das Interface gleich vor vornherein zu geben und nicht erst zur Laufzeit vom Server zu laden??!

- Alex


----------



## FArt (4. Dez 2008)

Anonymous hat gesagt.:
			
		

> Da muss ich durch - die Bestückung des Clients ist keine Option.


Das ist das Standardverfahren... warum soll das keine Option sein?


----------

