How to set up EJB 3.0 client with annotation?

I am trying to call EJB but my simple program can't find a ejb

within netbeans. I also download a stub file from the admin page and add to the ejb client path. but still without the luck

@EJB

private static ConverterBean converterBean;

public static void main(String[] args) {

// TODO code application logic here

BigDecimal param = new BigDecimal ("100.00");

BigDecimal amount = converterBean.dollarToYen(param);

System.out.println( amount );

}

[506 byte] By [skoizumi2133a] at [2007-10-3 11:27:41]
# 1
I am actually following the sample chapter from this link http://java.sun.com/javaee/5/docs/tutorial/doc/EJB2.html
skoizumi2133a at 2007-7-15 13:53:49 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 2

@EJB

private static ConverterBean converterBean;

If ConverterBean is your remote business interface, it will work. But from the name, it seems like a bean implementation class, which won't work.

From NetBeans' convention, maybe it should be:

@EJB

private static ConverterRemote converterBean;

cheng-fanga at 2007-7-15 13:53:49 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 3
I tried with remove one still doesn't work.
skoizumi2133a at 2007-7-15 13:53:49 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 4

Hi everybody.

I am facing a problem related to this.

Is there any restriction in using annotation to invocate an EJB. My scenario has the invoker in a package, and the target EJB in a different package, but both of them located at the same machine.

Thanks in advance for your attention.

Sergio G.

sgutierba at 2007-7-15 13:53:49 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 5

There is no restriction on which java package either the business interface or the client has.

For Remote EJB access from a java client, the @EJB annotation can only be used on the main

class of an Application Client component.In addition, when using @EJB on a field, the field

must be marked static.

If you're having trouble getting this to work, please post as much detailed information as possible

about exactly what error you're seeing and the related code/descriptors.

--ken

ksaksa at 2007-7-15 13:53:49 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 6

Hi ksaks.

This is my situation.

1. I have a normal class in package A. When I use the Netbeans wizard to call an Enterprise bean located at package B, it creates a method which issues a JNDI lookup and returns the interface for the Bean. When I use this method to initialize a field, I get a NullPointerException.

2. I have a JAXWS Web Service (Stateless) in package B. When I use the wizard, it defines a field annotated with EJB, and it allows me to call methods from the Bean without problems.

3. Using the list-jndi-entries command in asadmin, is not consistent the appearance of the interfaces of the EJB.

Thanks in advance for any help.

Kind Regards.

Sergio G.

sgutierba at 2007-7-15 13:53:49 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 7
Hi Sergio,Without seeing the actual code generated by the IDE it's difficult to debug. Please post theapplicable code snippets, as well as the full NullPointerException stack trace. --ken
ksaksa at 2007-7-15 13:53:49 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 8

Hi Ken.

First, I apologize for the long post.

I will ommit the specifics of methods within bean and client class.

It is something like:

/** The bean */

package co.com.une.medium.utils;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.SQLException;

import javax.annotation.PostConstruct;

import javax.annotation.PreDestroy;

import javax.annotation.Resource;

import javax.ejb.Stateless;

import javax.sql.DataSource;

/**

*

* @author saguti

*/

@Stateless(mappedName="ejb/LoggerBean")

public class LoggerBean implements LoggerLocal

{

/** DataSource que provee las conexiones a la base de datos de Log */

@Resource(name="jdbc/Medium")

private DataSource bdFuente;

// Several non-static resources follow

/** Creates a new instance of LoggerBD2 */

public LoggerBean()

{

System.out.print("Constructor del EJB Logger");

}

// this callback method initializes the connection field

@PostConstruct

private void inicializar()

{

System.out.println("En postconstruct del EJB");

try

{

this.conexion = this.bdFuente.getConnection();

}

catch (Exception e)

{

e.printStackTrace();

}

}

// This is one of the methods exposed through the interface

// It receives the arguments and inserts into a database which is accesed through

// the connection field

public String registrarError(String ubicacionError, String transaccion, String idMensaje, String textoError)

{

....

}

// This other of the methods exposed through the interface

// It receives the arguments and inserts into a database which is accesed through

// the connection field

public String registrarRecepcion(String plataforma, String transaccion, String idMensaje, String mensaje)

{

....

}

// Callback annotated method to close the connection when database

@PreDestroy

private void finalizarLogger()

{

System.out.println("Invocado el predestroy del EJB");

try

{

conexion.close();

}

catch (SQLException ex)

{

System.out.println("LoggerBD:finalizarLogger:123:Error insertando a la base de datos de registro: " + ex.getMessage());

}

}

// A third method (dummy method) to test the reachability to the EJB)

public String chequear()

{

System.out.println("Chequear del EJB");

return "Aca estoy";

}

}

/** End of the bean code */

/** Remote interface of the bean */

package co.com.une.medium.utils;

import javax.ejb.Remote;

/**

* This is the business interface for Logger enterprise bean.

*/

@Remote

public interface LoggerLocal

{

java.lang.String registrarError(String ubicacionError, String transaccion, String idMensaje, String textoError);

java.lang.String chequear();

java.lang.String registrarRecepcion(String plataforma, String transaccion, String idMensaje, String mensaje);

}

/** End of the interface code */

/** Beginning of the class code, located at other ejb-module. This is where when using the wizard it creates a private method which performs a JNDI Lookup */

// Note that this class is at another package

package co.com.une.medium.utilidades;

import co.com.une.medium.utils.LoggerLocal;

import java.util.logging.Level;

import java.util.logging.Logger;

import javax.ejb.EJB;

import javax.jms.Session;

import javax.jms.TextMessage;

import javax.jms.Topic;

import javax.jms.TopicConnection;

import javax.jms.TopicConnectionFactory;

import javax.jms.TopicPublisher;

import javax.jms.TopicSession;

import javax.naming.Context;

import javax.naming.InitialContext;

import javax.naming.NamingException;

/**

* Clase utilitaria que genera un mensaje JMS y lo despacha en una cola

* @author sgutierb

* @version 1.0

*

*/

public class ClienteJMS

{

// Several fields which are particular to this class

/** Contexto de acceso al servicio de nombre JNDI */

private Context contextoJndi=null;

.....

/* Here I guess that:

1. I should annotate the field or...

2. Not to use the annotation and use the method below

*/

// I have tried the two ways. When using just the annotation, I got the

// NullPointerException. When using the method,

// I got the NamingLookupException

@EJB

private LoggerLocal loggerBean;

/** Constructor por defecto para el Cliente JMS */

public ClienteJMS()

{

}

public ClienteJMS(String nombre, String transaccion, String idMensaje, String texto)

{

this.textoMensaje = texto;

this.nombrePlataforma = nombre;

this.nombreTransaccion = transaccion;

this.idMensaje = idMensaje;

//this.interfaceLogger = this.lookupLoggerBD2();

try

{

// Code of the class

...

// Here I use the method

this.loggerBean = this.lookupLoggerBean();

}

catch (Exception ex)

{

// More code of the class

}

}

public boolean publicarMensaje()

{

boolean valorRetorno = false;

try

{

......

try

{

....

}

catch(Exception ex)

{

ex.printStackTrace();

}

}

catch (Exception ex)

{

...

}

finally

{

....

}

}

public boolean getEstadoCliente()

{

...

}

// This is the method which is created by the wizard

// When I use this to assign the field, I get a NamingLookupException

private LoggerLocal lookupLoggerBean()

{

try {

Context c = new InitialContext();

return (LoggerLocal) c.lookup("java:comp/env/ejb/LoggerBean");

}

catch(NamingException ne) {

Logger.getLogger(getClass().getName()).log(Level.SEVERE,"exception caught" ,ne);

throw new RuntimeException(ne);

}

}

}

/** End of the client class */

/ ** This is the text of the NullPointerException */

// The referred line at the class corresponds to a calling to a method of the bean */

[#|2007-05-23T15:34:10.203+0500|WARNING|sun-appserver-pe9.0|javax.enterprise.system.stream.err|_ThreadID=14;_ThreadName=ht

tpWorkerThread-8080-0;_RequestID=f82063a4-06d0-4839-80b3-1167e034715e;|

java.lang.NullPointerException

at co.com.une.medium.utilidades.ClienteJMS.publicarMensaje(ClienteJMS.java:165)

at co.com.une.medium.externo.InvocadorImpl.invocacionAsincronica(InvocadorImpl.java:60)

at co.com.une.medium.externo.InvocadorMedium.cambiarEstado(InvocadorMedium.java:60)

at co.com.une.medium.externo.Medium.cambiarServicio(Medium.java:290)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:585)

at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1050)

at com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:165)

at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:2766)

at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:3847)

at com.sun.ejb.containers.WebServiceInvocationHandler.invoke(WebServiceInvocationHandler.java:147)

at $Proxy245.cambiarServicio(Unknown Source)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:585)

at com.sun.xml.ws.server.PeptTie._invoke(PeptTie.java:61)

at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher.invokeEndpoint(SOAPMessageDispatcher.java:280)

at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher$SoapInvoker.invoke(SOAPMessageDispatcher.java:588)

at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher.receive(SOAPMessageDispatcher.java:147)

at com.sun.xml.ws.server.Tie.handle(Tie.java:90)

at com.sun.enterprise.webservice.Ejb3MessageDispatcher.handlePost(Ejb3MessageDispatcher.java:160)

at com.sun.enterprise.webservice.Ejb3MessageDispatcher.invoke(Ejb3MessageDispatcher.java:89)

at com.sun.enterprise.webservice.EjbWebServiceServlet.dispatchToEjbEndpoint(EjbWebServiceServlet.java:186)

at com.sun.enterprise.webservice.EjbWebServiceServlet.service(EjbWebServiceServlet.java:117)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)

at com.sun.enterprise.web.AdHocContextValve.invoke(AdHocContextValve.java:101)

at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)

at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:536)

at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:71)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:182)

at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)

at com.sun.enterprise.web.VirtualServerPipeline.invoke(VirtualServerPipeline.java:120)

at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:939)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:137)

at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)

at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:536)

at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:939)

at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:239)

at com.sun.enterprise.web.connector.grizzly.ProcessorTask.invokeAdapter(ProcessorTask.java:667)

at com.sun.enterprise.web.connector.grizzly.ProcessorTask.processNonBlocked(ProcessorTask.java:574)

at com.sun.enterprise.web.connector.grizzly.ProcessorTask.process(ProcessorTask.java:844)

at com.sun.enterprise.web.connector.grizzly.ReadTask.executeProcessorTask(ReadTask.java:287)

at com.sun.enterprise.web.connector.grizzly.ReadTask.doTask(ReadTask.java:212)

at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:252)

at com.sun.enterprise.web.connector.grizzly.WorkerThread.run(WorkerThread.java:75)

|#]

/** End of the NullPointerException */

/** Begin of the NamingLookupException. It occurs when using the lookup method */

[#|2007-05-23T16:07:53.821+0500|SEVERE|sun-appserver-pe9.0|co.com.une.medium.utilidades.ClienteJMS|_ThreadID=15;_ThreadNam

e=httpWorkerThread-8080-1;_RequestID=17f2997a-44af-4ce7-a9a5-b472dddcacfc;|exception caught

javax.naming.NameNotFoundException: No object bound to name java:comp/env/ejb/LoggerBean

at com.sun.enterprise.naming.NamingManagerImpl.lookup(NamingManagerImpl.java:751)

at com.sun.enterprise.naming.java.javaURLContext.lookup(javaURLContext.java:156)

at com.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:307)

at javax.naming.InitialContext.lookup(InitialContext.java:351)

at co.com.une.medium.utilidades.ClienteJMS.lookupLoggerBean(ClienteJMS.java:206)

at co.com.une.medium.utilidades.ClienteJMS.<init>(ClienteJMS.java:116)

at co.com.une.medium.externo.InvocadorImpl.invocacionAsincronica(InvocadorImpl.java:53)

at co.com.une.medium.externo.InvocadorMedium.cambiarEstado(InvocadorMedium.java:60)

at co.com.une.medium.externo.Medium.cambiarServicio(Medium.java:290)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:585)

at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1050)

at com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:165)

at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:2766)

at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:3847)

at com.sun.ejb.containers.WebServiceInvocationHandler.invoke(WebServiceInvocationHandler.java:147)

at $Proxy268.cambiarServicio(Unknown Source)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:585)

at com.sun.xml.ws.server.PeptTie._invoke(PeptTie.java:61)

at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher.invokeEndpoint(SOAPMessageDispatcher.java:280)

at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher$SoapInvoker.invoke(SOAPMessageDispatcher.java:588)

at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher.receive(SOAPMessageDispatcher.java:147)

at com.sun.xml.ws.server.Tie.handle(Tie.java:90)

at com.sun.enterprise.webservice.Ejb3MessageDispatcher.handlePost(Ejb3MessageDispatcher.java:160)

at com.sun.enterprise.webservice.Ejb3MessageDispatcher.invoke(Ejb3MessageDispatcher.java:89)

at com.sun.enterprise.webservice.EjbWebServiceServlet.dispatchToEjbEndpoint(EjbWebServiceServlet.java:186)

at com.sun.enterprise.webservice.EjbWebServiceServlet.service(EjbWebServiceServlet.java:117)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)

at com.sun.enterprise.web.AdHocContextValve.invoke(AdHocContextValve.java:101)

at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)

at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:536)

at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:71)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:182)

at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)

at com.sun.enterprise.web.VirtualServerPipeline.invoke(VirtualServerPipeline.java:120)

at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:939)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:137)

at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)

at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:536)

at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:939)

at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:239)

at com.sun.enterprise.web.connector.grizzly.ProcessorTask.invokeAdapter(ProcessorTask.java:667)

at com.sun.enterprise.web.connector.grizzly.ProcessorTask.processNonBlocked(ProcessorTask.java:574)

at com.sun.enterprise.web.connector.grizzly.ProcessorTask.process(ProcessorTask.java:844)

at com.sun.enterprise.web.connector.grizzly.ReadTask.executeProcessorTask(ReadTask.java:287)

at com.sun.enterprise.web.connector.grizzly.ReadTask.doTask(ReadTask.java:212)

at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:252)

at com.sun.enterprise.web.connector.grizzly.WorkerThread.run(WorkerThread.java:75)

|#]

sgutierba at 2007-7-15 13:53:49 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 9

It's important to understand the difference between a bean class and a utility class.A Session Bean

bean class is a managed class for an EJB component and is allowed to declare Java EE

environmnent annotations such as @EJB, @Resource, etc.A java class that is called from within

an invocation on a Bean class, such as ClienteJMS, is considered a utility class. In Java EE 5,

such a class is not permitted to use the environment annotations.It can, however, access the component environment of whatever bean component invoked it.

In this case, CilenteJMS assumes that whatever component invoked it has defined a local ejb

reference with environment name "ejb/LoggerBean".This is determined by the string passed

to the InitialContext.lookup method : "java:comp/env/ejb/LoggerBean".The portion of the

string after "java:comp/env/" is the unique name of the ejb dependency within the private

component environment.This is NOT the same thing as a global JNDI name.In this case,

the component environment name happens to be the same as the global JNDI name assigned

to the LoggerBean, but that is a coincidence and has no bearing on this problem.

So, what you need to do is define a local ejb dependency for the Medium bean so that

it can be looked up by the CilenteJMS utility class. The easiest thing is just to do that using

an @EJB annotation.Just put the following at the *class*-level of the Medium bean.

@EJB(name="ejb/LoggerBean", beanInterface=LoggerLocal.class)

This defines an Local EJB dependency on a bean with local business interface

LoggerLocal and names that dependency "ejb/LoggerBean" so that it can be

looked up via "java:comp/env/ejb/LoggerBean".This is equivalent to defining

an ejb-local-ref within the Medium bean's section in ejb-jar.xml.

--ken

ksaksa at 2007-7-15 13:53:49 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 10

Hi Ken.

It worked. The problem was in the dependency.

Thank you very much for your help and patience.

A last question to see if I understood well. When I have an utility class invocated from a EJB, I have to create the dependence so that the utility class can call the EJB, by using JNDI lookup; When I have an EJB calling another EJB, is enough to use the annotations. Right?

Thanks a lot!

Regards

Sergio

sgutierba at 2007-7-15 13:53:49 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 11

Hi Sergio,

Glad you got it working.

Yes, your understanding is correct.In Java EE 5 only certain managed classes can use

annotations. However, anything declared in a component environment is visible to any

other utility code running within the same component invocation.If A and B are Session beans

and AUtil,BUtil are utility classes then given this invocation path : A->AUtil->B->BUtil

Both A and AUtil can "see" the component environment of A but once a new 1st class

component invocation is made on B, then its component environment is in context and

is visible to it and BUtil.For EJB components, each EJB has its own private

component environment.In the case of a web application, there is only one shared

component environment for the entire .war.

--ken

ksaksa at 2007-7-15 13:53:49 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 12

Hi ken.

I apologize for my ignorance., but again I am facing the same problem. If I understood well:

- From an EJB, I can call another EJB by using @EJB annotation directly. (Session Bean is a managed class which supports annotations)

- From an utility class, to call an EJB I do have to use the JNDI lookup to obtain a reference to Remote or Local Interface.

- From an utility class which is instantiated from an EJB, I do need to annotate it (EJB) to inject a dependence which will be available to every class being instantiated within this.

Another question, Is there any way which I can use to validate that annotations are correcly processed at compilation or deployment time? May be using the validator (I am using Netbeans)

Thanks, and again, I apologize.

Kind regards.

Sergio.

Sgutierba at 2007-7-15 13:53:49 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 13

> - From an EJB, I can call another EJB by using @EJB

> annotation directly. (Session Bean is a managed class

> which supports annotations)

Yes.

>

> - From an utility class, to call an EJB I do have to

> use the JNDI lookup to obtain a reference to Remote

> or Local Interface.

>

Yes.The reference you look up is defined either by

an @EJB on the invoking bean class or an ejb-ref/ejb-local-ref

within the invoking bean's ejb-jar.xml

> - From an utility class which is instantiated from an

> EJB, I do need to annotate it (EJB) to inject a

> dependence which will be available to every class

> being instantiated within this.

It doesn't matter which class actually calls new() on the utility class.

All that's relevant is which component actively invokes the utility

class that performs the lookup.

@EJB and ejb-ref/ejb-local-ref describe the same metadata -- a

reference to an EJB.They are just two different ways to do it.

It's up to you which you choose, but the code that looks up the

ejb reference doesn't care whether it was declared via @EJB

or .xml.

>

> Another question, Is there any way which I can use to

> validate that annotations are correcly processed at

> compilation or deployment time? May be using the

> validator (I am using Netbeans)

>

You can always use the "verifier" command in the appserver's

bin directory.I'm not sure whether it warns about annotation

usage in utility classes.

Another thing you can do is look at the generated ejb-jar.xml corresponding

to your application after deployment. The deployment module in the

appserver always converts all the metadata for the application into what is

called a "metadata-complete" form.This is useful for debugging. You can

find it under <appserver_home>/domains/domain1/generated/xml

--ken

> Thanks, and again, I apologize.

>

> Kind regards.

>

> Sergio.

ksaksa at 2007-7-15 13:53:49 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 14

Hi Ken.

Again checking what you have suggested me, but I am stalled tryng to solve the issue.

I have the following scenario:

- Stateless bean, creating a dependency:

@EJB(name="ejb/PluginBean", beanInterface=PluginLocal.class)

Then, within EJB, I instantiate an utility class called CompletedTransactionDeliverer:

CompletedTransactionDeliverer deliverer = new CompletedTransactionDeliverer();

- Within the utility class, I perform a lookup to initialize a field type PluginLocal:

When using the wizard, it creates a method lookupPluginBean, which uses lookup, looking for: "java:comp/env/ejb/PluginBean"

That method causes a NamingException, saying that there is not any object bound to that name.

Here, there is something I do not know if could be a problem; the utility class inheritates from Runnable; it is a Thread.

The exception is like:

javax.naming.NameNotFoundException: No object bound to name java:comp/env/ejb/PluginBean

at com.sun.enterprise.naming.NamingManagerImpl.lookup(NamingManagerImpl.java:751)

at com.sun.enterprise.naming.java.javaURLContext.lookup(javaURLContext.java:156)

at com.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:307)

at javax.naming.InitialContext.lookup(InitialContext.java:351)

at co.com.une.medium.interno.telefonia.medcom.transaction.CompletedTransactionDeliverer.lookupPluginBean(CompletedTransactionDeliverer.java:452)

at co.com.une.medium.interno.telefonia.medcom.transaction.CompletedTransactionDeliverer.<init>(CompletedTransactionDeliverer.java:53)

at co.com.une.medium.interno.telefonia.TelefoniaImpl.<init>(TelefoniaImpl.java:84)

at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)

at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)

at java.lang.reflect.Constructor.newInstance(Constructor.java:494)

at java.lang.Class.newInstance0(Class.java:350)

at java.lang.Class.newInstance(Class.java:303)

at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:492)

at com.sun.ejb.containers.StatelessSessionContainer.access$100(StatelessSessionContainer.java:96)

at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:746)

at com.sun.ejb.containers.util.pool.NonBlockingPool.getObject(NonBlockingPool.java:186)

at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:469)

at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:1566)

at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1148)

at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:182)

at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:71)

at $Proxy124.inicializar(Unknown Source)

at co.com.une.medium.interno.telefonia.TelefoniaListener.onMessage(TelefoniaListener.java:70)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:585)

at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1050)

at com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:165)

at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:2766)

at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:3847)

at com.sun.ejb.containers.MessageBeanContainer.deliverMessage(MessageBeanContainer.java:997)

at com.sun.ejb.containers.MessageBeanListenerImpl.deliverMessage(MessageBeanListenerImpl.java:61)

at com.sun.enterprise.connectors.inflow.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:166)

at $Proxy132.onMessage(Unknown Source)

at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java:212)

at com.sun.enterprise.connectors.work.OneWork.doWork(OneWork.java:63)

at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:479)

|#]

What might I be doing wrong?

Thanks.

Kind regards

Sergio.

Message was edited by:

sgutierb

sgutierba at 2007-7-15 13:53:49 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 15

Hi Sergio,

In EJB, the Java class constructor on the bean class should not be used. It's best to keep it

empty.The private component environment is not available during new().If you have

logic to be performed at instance creation time, declare a method with no parameters and void

return type and annotate it with javax.annotation.PostConstruct. The container will call that

method when the bean instance is being taken through its initialization lifecycle. The container

calls @PostConstruct after any injection has taken place on the bean instance.

E.g.

@PostConstruct

void init() {

...

}

ksaksa at 2007-7-21 13:53:23 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 16

Hi Ken.

Perhaps I was not clear in my explanation:

1. There is a Bean named PluginBean, which exposes 4 methods through a Remote interface (As I understand, I have to use Remote interfaces because the calling class is located within another package)

2. There is another bean called TelefoniaImpl which can calls PluginBean through a @EJB annotation.

3. Within the code of TelefoniaImpl, I create an instance of a class named CompletedTransactionDeliverer, which is an utility class (no managed class). So that, as I understood, I have to create an injection at class level of TelefoniaImpl:

@EJB(name="ejb/PluginBean", interfaceClass=PluginLocal.class)

@Stateless

public class TelefoniaImpl

{

...

}

4. When I perform the lookup for ejb/PluginBean within a function or the constructor of CompletedTransactionDeliverer, a NamingException is produced

Thanks in advance for your help.

Best Regards.

Sergio.

sgutierba at 2007-7-21 13:53:23 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 17

>> 4. When I perform the lookup for ejb/PluginBean within a function or the constructor of

>> CompletedTransactionDeliverer, a NamingException is produced

Please reread my last post.The problem is that CompletedTransactionDeliverer

is used from the *constructor* of TelefoniaImpl.At that point of time the private

component environment of TelefoniaImpl is not available, so it is not available to

CompletedTransactionDeliverer either.You need to move the code that instantiates the

CompletedTransactionDelverer to a @PostConstruct method in TelefoniaImpl.

javax.naming.NameNotFoundException: No object bound to name java:comp/env/ejb/PluginBean

at com.sun.enterprise.naming.NamingManagerImpl.lookup(NamingManagerImpl.java:751)

at com.sun.enterprise.naming.java.javaURLContext.lookup(javaURLContext.java:156)

at com.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:307)

at javax.naming.InitialContext.lookup(InitialContext.java:351)

at co.com.une.medium.interno.telefonia.medcom.transaction.CompletedTransactionDeliverer.lookupPluginBean(CompletedTransactionDeliverer.java:452)

at co.com.une.medium.interno.telefonia.medcom.transaction.CompletedTransactionDeliverer.<init>(CompletedTransactionDeliverer.java:53)

at co.com.une.medium.interno.telefonia.TelefoniaImpl.<init>(TelefoniaImpl.java:84)

at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)

at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)

at java.lang.reflect.Constructor.newInstance(Constructor.java:494)

at java.lang.Class.newInstance0(Class.java:350)

at java.lang.Class.newInstance(Class.java:303)

at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:492)

ksaksa at 2007-7-21 13:53:23 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 18

Hi Ken.

It worked fine. Thanks a lot The problem was because of the invocation of classes located at constructor.

A last question (And hope not to disturb anymore :-) )

If I need to inject more than one dependence, how can I do it? Is it by using more than one @EJB annotation at the bean class?

Thanks a lot.

Best regards.

Sergio.

sgutierba at 2007-7-21 13:53:23 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 19

Hi Sergio,

Glad it's working now.

More questions are not a disturbance -- that's what the forum is here for :-)

It is possible to declare multiple annotations, but the syntax is a bit tricky because the

basic annotation archictecture in Java SE only allows one annotation per type

to appear at the class level.So, to declare multiple @EJB annotations at the class level

you need to use an enclosing annotation called @EJBs. Here's an example :

@EJBs(

{ @EJB(name="ejb/Sless1", beanInterface=Sless1.class),

@EJB(name="ejb/Sless2", beanInterface=Sless2.class) ,

@EJB(name="ejb/Sless3", beanInterface=Sless3.class)

})

You can also just declare a different field for each @EJB :

private @EJB(name="ejb/Sless1") Sless1 sless1;

private @EJB(name="ejb/Sless2") Sless2 sless2;

...

For field usage of @EJB the EJB reference will be injected into the bean class, but

it can *also* be looked up in the same way as the class-level usage. In this case,

there is no need to specify beanInterface since it can be derived from the type of

the field.

--ken

ksaksa at 2007-7-21 13:53:23 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 20

Hi Ken.

Really, thanks a lot. I was really stalled because of this issue.

>

> You can also just declare a different field for each

> @EJB :

>

> private @EJB(name="ejb/Sless1") Sless1 sless1;

> private @EJB(name="ejb/Sless2") Sless2 sless2;

> ...

Just to be sure, may this approach be used within not managed classes (utilities)?

I guess not.

Thanks again.

Sergio

sgutierba at 2007-7-21 13:53:23 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 21

> Just to be sure, may this approach be used within not

> managed classes (utilities)?

> I guess not.

No, the annotations themselves can only be declared on managed classes.

But, just like class-level annotations, the resulting dependencies can still

be looked up by other code running within the same context as the

bean.

>

> hanks again.

>

> Sergio

ksaksa at 2007-7-21 13:53:23 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...