Lookup-Problem mit JBoss 4.2 und EJB 3

schnuffie

Erfahrenes Mitglied
Hallo Experten,

leider habe ich hier und beim Googlen keine Lösung gefunden.
Mein Problem ist folgendes:

Ich verwende EJB3 (mit Hibernate-Persistence - nur zur Info erwähnt) mit JBoss 4.2 und deploye über Eclipse 3.3. Das funktioniert auch alles super, bis auf:

Ich bekomme keinen Lookup hin. Aus diesem Grund habe ich zum Testen ein ganz einfaches Beispiel erstellt:

Bean-Code:
Code:
import javax.ejb.Remote;
@Remotepublicinterface SimpleBean {
public String sayHello(String name);
 
}
Code:
import javax.ejb.*; 
@Stateless(name="Example", mappedName="java:comp/env/SimpleBean")
publicclass SimpleBeanImpl implements SimpleBean {
public String sayHello(String name) { 
return"Hello " + name + "!"; 
} 

}

Lookup-Klasse:
Code:
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import javax.ejb.EJB;
import javax.naming.InitialContext;

import com.webnobis.storehousesystem.facade.SimpleBean;
publicclass SimpleClient {

private SimpleBean bean;
private String text = "Banane";
public SimpleClient() {
try {
InitialContext ctx = new InitialContext();
this.bean = (SimpleBean)ctx.lookup("java:comp/env/SimpleBean");
} catch (Exception e) {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(bout));
text = new String(bout.toByteArray());
}
}


public String getText() {
returntext;
}



public String getBeanText() {
return (bean != null)? bean.sayHello("Steffen"): "bean = null";
}



}

Die beiden Methoden-Rückgaben gebe ich testweise in einer ganz simplen JSP aus:
HTML:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@page import="com.webnobis.storehousesystem.delegate.SimpleClient;"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>

<jsp:declaration>
SimpleClient sc = new SimpleClient();
</jsp:declaration>

<p>#<%=sc.getText() %>#</p>
<p>##<%=sc.getBeanText() %>##</p>

</body>
</html>

Dabei erscheint dann aber:
HTML:
#javax.naming.NameNotFoundException: SimpleBean not bound at org.jnp.server.NamingServer.getBinding(NamingServer.java:529) at org.jnp.server.NamingServer.getBinding(NamingServer.java:537) at org.jnp.server.NamingServer.getObject(NamingServer.java:543) at org.jnp.server.NamingServer.lookup(NamingServer.java:296) at org.jnp.server.NamingServer.lookup(NamingServer.java:270) at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:625) at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:716) at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:587) at javax.naming.InitialContext.lookup(Unknown Source) at com.webnobis.storehousesystem.delegate.SimpleClient.(SimpleClient.java:21) at org.apache.jsp.index_jsp.(index_jsp.java:12) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at java.lang.Class.newInstance0(Unknown Source) at java.lang.Class.newInstance(Unknown Source) at org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:143) at org.apache.jasper.servlet.JspServletWrapper.getDependants(JspServletWrapper.java:260) at org.apache.jasper.compiler.Compiler.isOutDated(Compiler.java:416) at org.apache.jasper.compiler.Compiler.isOutDated(Compiler.java:342) at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:562) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:308) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266) at javax.servlet.http.HttpServlet.service(HttpServlet.java:803) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:228) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179) at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104) at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:216) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:624) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:445) at java.lang.Thread.run(Unknown Source) #
##bean = null##

Auf der Kommandozeile wird beim Deployen kein Fehler ausgegeben. Die JSP funktioniert auch. Nur der Lookup bringt null. Da ich nicht glaube, daß die JBosser ein Problem in ihrem App-Server haben, gehe ich davon aus, daß ich ein entscheidendes Detail übersehen habe und ihr mir das bestimmt sagen könnt, wo mein Fehler liegt.

Zusatzinfo:
Bei EJB3 sind die Deployment-Descriptoren optional, daher habe ich keine angelegt. Soweit ich weiß, wird durch die Angabe des "mappedName" der Name im App-Server hinterlegt, oder irre ich da? Mit der Annotation "@EJB" statt InitialContext komme ich hier leider auch nicht weiter.

Unter dem Link http://localhost:8080/jmx-console/HtmlAdaptor?action=inspectMBean&name=jboss:service=JNDIView, "Output JNDI info as text", Button "Invoke", erscheint dieser JNDI-name auch nicht.

Was mache ich noch falsch?
 
Zuletzt bearbeitet:
Ergänzend möchte ich noch erwähnen, daß ich das Serverprofil "all" verwende und eine Ergänzung der "jndi.properties" im "conf"-Verzeichnis um die folgende Zeile brachte leider auch keinen Erfolg:
HTML:
java.naming.provider.url=jnp://localhost:1099

Inhalt der "jndi.properties" jetzt:
HTML:
# DO NOT EDIT THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING
#
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=jnp://localhost:1099

In zahlreichen Foren wird dieses Problem beschrieben, doch eine Lösung habe ich leider noch nicht gefunden. Ich hoffe, Ihr könnt mir helfen.
 
Nun habe ich eine weitere Bean geschrieben:
Code:
import javax.ejb.Remote;


@Remote
public interface OtherBean {


public SimpleBean getSimpleBean();


}
Code:
import javax.ejb.EJB;
import javax.ejb.Stateless;
 
@Stateless(name="Example2", mappedName="ejb/OtherBeanJNDI")
public class OtherBeanImpl implements OtherBean {
 
 @EJB
 private SimpleBean simple;
 
 @Override
 public SimpleBean getSimpleBean() {
  return simple;
 }
 
}

In meiner Testklasse werte ich das dann auch aus:
Code:
//...
public String getOtherText() {
try {
InitialContext ctx = new InitialContext();
OtherBean bean1 = (OtherBean) ctx.lookup("ejb/OtherBeanJNDI");
SimpleBean bean2 = bean1.getSimpleBean();
if (bean2 != null) {
return bean2.sayHello("Fritz");
} else {
return "OtherBean(SimpleBean) = null";
}
} catch (Exception e) {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(bout));
return new String(bout.toByteArray());
}
}
//...

In der JSP wird das dann ausgegeben:
HTML:
<!-- ... -->
<p>###<%=sc.getOtherText() %>###</p>
<!-- ... -->

Ergebnis:
HTML:
#Banane#
##Hello Steffen!##
###Hello Fritz!###

Und warum?:
Weil die Annotation-Angabe "mappedName" anscheinend völlig Wurscht ist, denn es funktionierte erst, als ich im META-INF-Verzeichnis die angeblich bei EJB3 nicht mehr erforderliche spezielle App-Server-Datei "jboss.xml" anlegte:
HTML:
<?xml version="1.0" encoding="UTF-8"?>
<jboss>
<enterprise-beans>
<session>
<ejb-name>Example</ejb-name>
<jndi-name>ejb/SimpleBeanJNDI</jndi-name>
</session>
<session>
<ejb-name>Example2</ejb-name>
<jndi-name>ejb/OtherBeanJNDI</jndi-name>
</session>
</enterprise-beans>
</jboss>

Nun hatte ich mir lang genug "einen Wolf" gesucht und kann mich nun endlich auf die eigentlichen Projektinhalte konzentrieren. Ich hoffe nur, daß das, was ich eben herausgefunden habe auch vielen anderen EJB3-Geplagten nützt.
 
Zuletzt bearbeitet:
Hallo,

warum einfach wenns auch kompliziert geht...

Unser Service Interface:
Java:
/**
 * 
 */
package de.tutorials.services;

import javax.ejb.Remote;

/**
 * @author Thomas.Darimont
 *
 */
@Remote
public interface IBusinessService {
  String businessOperation(String arg);
}


Unsere Service Implementierung:
Java:
/**
 * 
 */
package de.tutorials.services.internal;

import javax.ejb.Stateless;

import de.tutorials.services.IBusinessService;

/**
 * @author Thomas.Darimont
 *
 */
@Stateless
public class BusinessService implements IBusinessService{

  public String businessOperation(String arg) {
    return arg + " rockz!";
  }

}

Unser Client:
Java:
/**
 * 
 */
package de.tutorials;

import javax.naming.InitialContext;

import de.tutorials.services.IBusinessService;

/**
 * @author Thomas.Darimont
 */
public class Client {

  /**
   * @param args
   */
  public static void main(String[] args) throws Exception {
    InitialContext initialContext = new InitialContext();
    IBusinessService businessService = (IBusinessService) initialContext.lookup("java:/BusinessService/remote");
    System.out.println(businessService.businessOperation("tutorials.de"));
  }

}

jndi.properties im Classpath des Clients:
Code:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=jnp://localhost:1099

JBoss 4.2 mit run -c all in der all - Konfiguration gestartet.

Klassen aus bin in tutorials-ejb3-example.jar exportieren und nach %JBOSS_HOME%\server\all\deploy kopieren.
Fertig.

Das tutorials-ejb3-example.jar liegt im deploy Verzeichnis des Projekts im Anhang.

Gruß Tom
 

Anhänge

  • de.tutorials.ejb3.example.zip
    6,3 KB · Aufrufe: 275
So einfach geht's leider nicht Tom, denn für JNDI-Namen != "Klasse/remote" funktioniert's nicht ohne die jboss.xml-Einträge:

Code:
@Stateless(name="ManagementFacade", mappedName="ejb/ManagementFacade")

Code:
InitialContext ctx = new InitialContext();
ManagementFacade mf = (ManagementFacade) ctx.lookup("java:/ejb/ManagementFacade");

HTML:
javax.naming.NameNotFoundException: ManagementFacade not bound
 at org.jnp.server.NamingServer.getBinding(NamingServer.java:529)
 at org.jnp.server.NamingServer.getBinding(NamingServer.java:537)
 at org.jnp.server.NamingServer.getObject(NamingServer.java:543)
 at org.jnp.server.NamingServer.lookup(NamingServer.java:296)
 at org.jnp.server.NamingServer.lookup(NamingServer.java:270)
 at sun.reflect.GeneratedMethodAccessor80.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305)
 at sun.rmi.transport.Transport$1.run(Transport.java:159)
 at java.security.AccessController.doPrivileged(Native Method)
 at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
 at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
 at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
 at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
 at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
 at java.lang.Thread.run(Thread.java:619)
 at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
 at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
 at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
 at org.jnp.server.NamingServer_Stub.lookup(Unknown Source)
 at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:625)
 at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:587)
 at javax.naming.InitialContext.lookup(InitialContext.java:392)
 at com.webnobis.storehousesystem.delegate.SimpleClient.getCustomerName(SimpleClient.java:63)
 at org.apache.jsp.index_jsp._jspService(index_jsp.java:79)
 at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
 at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:384)
 at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
 at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:228)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
 at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
 at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
 at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:216)
 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
 at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:624)
 at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:445)
 at java.lang.Thread.run(Thread.java:619)

Erst wenn ich den Eintrag in die jboss.xml übernehme, funktioniert's wieder.
 
Hallo,

normalerweise verwendet man für in-container Lookup's die Local Interfaces anstatt Remote Interfaces. Bei EJB 3.0 sollte man auch manuelle Lookups vermeiden und statt dessen den vom Container bereitgestellten Dependency Injection Mechanismus (@EJB / @Resource ...) verwenden, damit spart man sich die fehleranfälligen manuellen Lookups.
Weiterhin kann man mit EJB 3.0 Annotations so ziemlich all das machen was man früher mit Deployment-Descriptoren (ejb-jar.xml / jboss-ejb.xml, etc.). Deployment-Descriptoren verwendet man heute noch um Applikationsweite Metadaten (wie Standard Interceptoren etc.) zu definieren oder um Werte der Annotations basierten Konfiguration zu überschreiben.

Gruß Tom
 
Hallo,
ich habe ein ähnliches Problem mit dem Lookup. Kann es sein, dass sich das ganze wieder anders verhält, wenn kein "JAR" sondern ein "EAR" deployed wird?

Danke für jeden Tip.
Grüsse
 
Hallo zusammen,

es sind zwar nun fast 4 Jahre das Problem habe ich auch.

ich habe ein ähnliches Problem mit dem Lookup. Kann es sein, dass sich das ganze wieder anders verhält, wenn kein "JAR" sondern ein "EAR" deployed wird?


Ich habe ein Beispiel gefunden
http://andrevollimweb.de/docs/Tutorial EJB.pdf

Das Beispiel läuft unter JBOss 5.0.1 sollte doch auch unter 4.2.1 laufen****?

Ich erhalte jedoch immer einen "Nullpointer" und zwar dort, wo auf die EJB verwiesen wird.



Danke im Voraus.
Viele Grüße
 
Zuletzt bearbeitet:
Zurück