# EJB auf externem Server aus GWT aufrufen



## GFEMajor (22. Jun 2009)

Hi.

Ich schreibe gerade an meinem ersten GWT Projekt und muss von einem externen Server (Also nicht der gleiche Server auf dem die GWT Sachen laufen) ein EJB ansprechen.
Ich habe schon im Netz gesucht aber nichts dergleichen gefunden.

Hat vielleicht jemand Erfahrung damit?
(Ich bin GWT und EJB Neuling )


LG Major


----------



## Noctarius (22. Jun 2009)

Würde das Ganze übver einen WebService anbinden. Du kannst ja trotz GWT auf Serverseite auch andere Frameworks benutzen. CXF z.B. wäre klasse geeignet.


----------



## byte (22. Jun 2009)

Wenn Du EJB auf dem Server benutzen willst, solltest Du den Embedded Jetty deaktivieren (siehe -noserver Option). Du kannst dann einfach den EJB-Container Deiner Wahl anbinden, bzw. von einem Servlet Container wie Tomcat auf Deine EJBs zugreifen.


----------



## byte (22. Jun 2009)

Noctarius hat gesagt.:


> Würde das Ganze übver einen WebService anbinden. Du kannst ja trotz GWT auf Serverseite auch andere Frameworks benutzen. CXF z.B. wäre klasse geeignet.



Wozu hier Webservices? Macht das ganze doch nur langsam. Einfach aus dem GWT-Servlet auf die EJB zugreifen.


----------



## Noctarius (22. Jun 2009)

Er hat aber von anderem Server gesprochen


----------



## maki (22. Jun 2009)

Macht doch nix, EJBs Remote aufrufen ist Standard


----------



## GFEMajor (22. Jun 2009)

maki hat gesagt.:


> Macht doch nix, EJBs Remote aufrufen ist Standard



Würde ich ja gern machen, wenn du mir sagst wie . (Wie gesagt, ich hab noch nie was mit EJBs gemacht)


----------



## maki (22. Jun 2009)

call ejb remote - Google-Suche

Ansonsten würde ich dir empfehlen zumindst mal ein Tutorial für EJBs durchzuarbeiten, wenn du konkretere Fragen kannst du diese ja stellen.


----------



## GFEMajor (23. Jun 2009)

Ok, ich hab gegoogelt und ausprobiert, aber es will nicht klappen.
Also hier nochmal meine Ausgangssituation:

Ich nutze GWT und will aus dem Server-Servlet ein EJB auf einem anderen Server aufrufen. Der EJB Server ist ein JBoss (zur zeit läuft bei mir eine locale Instanz zum Testen, es soll aber später ein wirklich entfernter server sein), die GWT-Applikation wird auf dem GWT Standart Jetty betrieben.

Was habe ich bis jetzt geschafft:

Wenn ich das von GWT erstellte war verzeichnis mit im JBoss deploye, dann kann ich mein TestEJB aufrufen und zwar mit dem Befehl:


```
try {
	InitialContext ctx = new InitialContext();
	GetDate myDate =(GetDate) ctx.lookup("DateImpl/remote");
		
	} catch (NamingException e) {
}
```
Versuche ich das ganze nun aus dem Jetty heraus kommt folgende Fehlermeldung:
"Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial"

Was die Fehlermeldung bedeutet weis ich nicht (vielleicht kanns mir einer erklären).

Also hab ich mich auf die Suche nach weiteren Beispielen gemacht. Was ich dabei herausgefunden habe, ich muss dem Jetty (bzw. meinem GWT RemoteService, also dem Servlet) ja noch mitteilen, wo es das EJB (bzw. den Context) finden kann. Ich habe also den code dahingegen geändert:


```
Hashtable<String, String> env = new Hashtable<String, String>();
			env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
			env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
			env.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");
			
			
			InitialContext ctx = new InitialContext(env);			

		GetDate myDate =(GetDate) ctx.lookup("DateImpl/remote");
		
		} catch (NamingException e) {
		}
```

Es wird dann die onFailure() methode im GWT aufgerufen und als Fehler kommt:


```
[WARN] Exception while dispatching incoming RPC call
com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract java.lang.String crs.Test.client.GreetingService.greetServer(java.lang.String)' threw an unexpected exception: java.lang.NoClassDefFoundError: org/jboss/logging/Logger
	at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:360)
	at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:546)
	at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:166)
	at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:86)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
	at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
	at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
	at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
	at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
	at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
	at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
	at org.mortbay.jetty.Server.handle(Server.java:324)
	at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
	at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
	at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
	at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:205)
	at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
	at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
	at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
Caused by: java.lang.NoClassDefFoundError: org/jboss/logging/Logger
	at org.jnp.interfaces.NamingContext.<clinit>(NamingContext.java:160)
	at org.jnp.interfaces.NamingContextFactory.getInitialContext(NamingContextFactory.java:56)
	at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
	at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
	at javax.naming.InitialContext.init(Unknown Source)
	at javax.naming.InitialContext.<init>(Unknown Source)
	at crs.Test.server.GreetingServiceImpl.greetServer(GreetingServiceImpl.java:43)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:527)
	at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:166)
	at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:86)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
	at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
	at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
	at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
	at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
	at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
	at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
	at org.mortbay.jetty.Server.handle(Server.java:324)
	at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
	at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
	at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
	at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:205)
	at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
	at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
	at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
Caused by: java.lang.ClassNotFoundException: org.jboss.logging.Logger
	at java.lang.ClassLoader.findClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:352)
	at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:337)
	at java.lang.ClassLoader.loadClassInternal(Unknown Source)
	at org.jnp.interfaces.NamingContext.<clinit>(NamingContext.java:160)
	at org.jnp.interfaces.NamingContextFactory.getInitialContext(NamingContextFactory.java:56)
	at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
	at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
	at javax.naming.InitialContext.init(Unknown Source)
	at javax.naming.InitialContext.<init>(Unknown Source)
	at crs.Test.server.GreetingServiceImpl.greetServer(GreetingServiceImpl.java:43)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:527)
	at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:166)
	at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:86)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
	at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
	at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
	at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
	at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
	at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
	at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
	at org.mortbay.jetty.Server.handle(Server.java:324)
	at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
	at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
	at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
	at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:205)
	at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
	at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
	at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
```

Kann mir einer Sagen was ich falsch mache?


----------



## byte (23. Jun 2009)

Ich habe doch oben schon geschrieben, dass es mit dem Embedded Jetty höchstwahrscheinlich nicht funktioniert. Der ist nur für triviale Servicecalls geeignet. Bei komplexeren Sachen (z.B. der Integration von JEE-Technologien wie EJB) sollte man die GWT Shell mit der Option -noserver starten und den Server als eigenes Projekt handhaben.

Das bedeutet im Klartext, Du musst den Servercode (also die GWT-Service Implementierungen) in ein eigenes "Dynamic Web Project" auslagern. Das kannst Du dann auf dem Container Deiner Wahl deployen (z.B. Tomcat oder JBoss).

Die GWT Shell startest Du mit -noserver und teilst ggf. noch die Serveradresse mit, falls diese sich vom Default (localhost:8080) unterscheidet.


----------



## GFEMajor (23. Jun 2009)

Ok, Rat befolgt .

Ich hab jetzt meine Applikation auf einem normalen Jetty laufen (Deployen mach ich erstmal von Hand).
Soweit alles ok.

Aber wenn ich mir mit 


```
Hashtable<String, String> env = new Hashtable<String, String>();
            env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
            env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
            env.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");
            
            InitialContext ctx = new InitialContext(env);
```

den Context von meinem JBoss holen will geht das nicht. Ich bekomme den Context vom Jetty zurückgeliefert.

Kann es auch daran liegen, dass die beiden auf dem gleichen Rechner (also meinem, aber natürlich mit unterschiedlichen Ports) laufen?


----------



## GFEMajor (24. Jun 2009)

Und weiter gehts .

Also, nach weiteren gefühlten 1000 Tuts und Forumsposts die ich mir durchgelesen habe, bin ich wieder ein Stückchen weiter.
Hier erstmal mein jetziger Code:

```
try {
Properties properties = new Properties();
			properties.put("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
			properties.put("java.naming.factory.url.pkgs","=org.jboss.naming:org.jnp.interfaces");
			properties.put("java.naming.provider.url","localhost:1099");
			
Context ctx = new InitialContext(properties);
			
 String ret = "";
			GetDate myDate;
			try {
				myDate = (GetDate) ctx.lookup("DateImpl/remote");
				ret += myDate.getDate().toString();
			
			} catch (Exception e) {
				ret += e.getMessage();
			}
			
		} catch (NamingException e) {
			ret += e.getMessage();
		}
	

		return ret;
```

Der Code ist halbwegs gleich geblieben. Ich hab nur die Properties verändert. Was ich nun aber herausgefunden habe, ich muss in mein Projekt noch ein JAR importieren, und zwar "jbossall-client.jar" (Und das EJB Projekt). In dieser jar sind alle Klasse drin, die vorher als Exception "ClassNotFound" geworfen wurden. Und siehe da, es funktioniert, zumindest local (auch mit dem embedded Jetty von GWT!!!).

Nochmal meine Konfiguration: GWT 1.6.4 im Hosted Mode + JBoss 4.3 für das EJB(GetDate ==> liefert einfach das aktuelle Datum zurück).

Der GWT Jetty läuft auf Port 2425 und der JBoss auf 8080. (Beide local auf meinem Rechner)

Kopiere ich nun den JBoss auf einen anderen Rechner im Netzwerk (Adresse: 192.168.0.2) und ändere in den Propertiers folgendes:


```
properties.put("java.naming.provider.url","192.168.0.2:1099");
```

erhalte ich beim aufruf einen Server timeout:
"Could not obtain connection to any of these urls: 192.168.0.2:1099 and discovery failed with error: javax.naming.CommunicationException: Receive timed out [Root exception is java.net.SocketTimeoutException: Receive timed out]"

Firewalls (die integrierte von Windows und meine eigene) sind zu testzwecken deaktiviert wurden.
Anpingen kann ich den anderen Rechner auch.
Also meine Frage, kann ich die Verbindung irgendwie testen oder hat jemand eine Idee an was das liegen könnte, dass es local funktioniert, aber nicht übers Netzwerk??

Vielen Danke schonmal und sorry für den langen Post


----------



## maki (24. Jun 2009)

[]quote]Also meine Frage, kann ich die Verbindung irgendwie testen oder hat jemand eine Idee an was das liegen könnte, dass es local funktioniert, aber nicht übers Netzwerk??[/quote]
Mit telnet zB.:

```
telnet ip port
```
So kommt man schnell drauf ob zB. der Port stimmt, oder nicht


----------



## GFEMajor (24. Jun 2009)

Problem gelöst .

Hab noch ein bisschen rumgesucht und das Problaem nun endlich gelöst. Der JBoss hört von Haus aus nur auf dem Localen System nach Anfragen. Wenn man ihn aber so startet:

```
%JBOSS_HOME%/bin/run.bat -b "0.0.0.0"
```
Dann lauscht er auch auf dem Netzwerk und das Ansprechen des Beans funktioniert *freu*.

Danke nochmal an alle die mir bei der Lösung geholfen haben.

LG Major


----------

