EJB Timer Service error - java

I'm trying to use the EJB timer service, I have a class named TimerBean which carries the methods to schedule a timer and handle the timeout, this implements TimerBeanRemote an interface class.
In another session bean I have the following:
TimerBeanRemote service = (TimerBeanRemote) new InitialContext().lookup("TimerBean/remote");
When I try to run it on the server I get the error:
javax.naming.NamingException: Lookup failed for 'TimerBean/remote' in SerialContext [Root exception is javax.naming.NameNotFoundException: TimerBean]
Any ideas as to why it can't find it? Thanks!

Following from your comments -if you are trying to access TimerBeanRemote within the same container then you can inject the #Remote ejb in your servlet or JSF Backing Bean else you can locate your EJB through a JNDI lookup.
Suppose your TimerBean is: com.mypackage.timer.TimerBeanRemote
then as per explanation above you can either inject or lookup:
Injection
public class MyServlet ...{
#EJB
com.mypackage.timer.TimerBeanRemote timerBean;
}
JNDI lookup:
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.SerialInitContextFactory");
String[] serverDetails = server.split(":");
props.setProperty("org.omg.CORBA.ORBInitialHost", MyHost);
props.setProperty("org.omg.CORBA.ORBInitialPort", MyPort);
InitialContext ic = new InitialContext(props);<br>
TimerBeanRemote timerBean = (TimerBeanRemote)ic.lookup("com.mypackage.timer.TimerBeanRemote");
You can read the following articles for further details:
http://download.oracle.com/javaee/1.4/tutorial/doc/Session5.html
http://www.javabeat.net/articles/3-ejb-30-timer-services-an-overview-1.html

Related

Can't get Remote EJB to work with EJB Client API on Wildfly

I'm currently struggling with getting remote EJB invocation to work on wildfly (8.x and 9.x).
In detail it's about remote invocation from a standalone client application (not from another app server) using the EJB Client API approach. The remote naming approach works for me but isn't applicable in my scenario because I need to use client-side interceptors for passing context data to a server-side interceptor for the remote invocations.
But for now I try to get remote invocations with the client API to work for a simple example. Therefore I tried the quickstart for remote ejb invocation which is available on github (wildfly/quickstart/ejb-remote). The point is that this quickstart raises the same error as my on simple sample app. Here are some details of my application:
My remote interface:
package test.ejb;
public interface HelloRemote {
String greet(String name);
}
My Bean implementation:
package test.ejb;
import javax.ejb.Remote;
import javax.ejb.Stateless;
#Stateless(name = "Hello")
#Remote(HelloRemote.class)
public class HelloBean implements HelloRemote {
public String greet(String name) {
return "Hello " + name;
}
}
The remote view of the bean is correctly registered at the server (in export namespace):
java:jboss/exported/ejb-test-backend.jar/Hello!de.coryx.HelloRemote
Here now the client side:
My Main class:
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.jboss.ejb.client.EJBClientContext;
import test.ejb.HelloRemote;
public class Main {
public static void main(String[] args) throws Exception {
Properties props = new Properties();
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
Context context = new InitialContext(props);
String jndiLookup = "ejb:/ejb-test-backend.jar/Hello!" + HelloRemote.class.getName();
HelloRemote hello = (HelloRemote) context.lookup(jndiLookup);
System.out.println(hello.greet("World"));
}
}
The jboss-ejb-client.properties (packaged in jar/META_INF):
endpoint.name=client-endpoint
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port=8080
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
When I execute the main Method I get the following error message (same thing occurs when trying the wildfly quickstart that I mentioned above):
Exception in thread "main" java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:, moduleName:ejb-test-backend.jar, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext#497470ed
at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:774)
at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:116)
at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:186)
at org.jboss.ejb.client.EJBInvocationHandler.sendRequestWithPossibleRetries(EJBInvocationHandler.java:255)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:200)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:183)
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:146)
at com.sun.proxy.$Proxy0.greet(Unknown Source)
at Main.main(Main.java:16)
When I use the remote naming approach everything is fine:
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
props.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080");
props.put("jboss.naming.client.ejb.context", true);
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
props.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
Context context = new InitialContext(props);
String jndiLookup = "/ejb-test-backend.jar/Hello!" + HelloRemote.class.getName();
HelloRemote hello = (HelloRemote) context.lookup(jndiLookup);
System.out.println(hello.greet("World"));
Output here is (as expected):
Hello World
So is there anyone who knows what could be wrong here or better, who has a working example for remote EJB invocation on Wildfly using the EJB client API?
Thanks in advance!
As so often, I stumbled over the solution shortly after writing down the question and talking about it.
The problem with this setup was that the jboss-ejb-client.properties file has not been loaded by the client API which was then missing the connection url, ...
I don't know whether there where changes to the required location where these properties have to be placed or whether I was too dumb to read it correctly or whether I just adapted a tutorial that was corrupted. It doesn't even matter ;)
The solution is to place the properties file toplevel on the classpath and not in the META-INF directory of the JAR!
It works now as expected and I can register client-side interceptors.

Remote lookup to another Glassfish from a Servlet

I'm trying to run a remote lookup to another Glassfish from a Servlet. So, I was following the link documentation (http://docs.oracle.com/cd/E19798-01/821-1752/beanv/index.html). First I created a Sateless Session Ben called CalculatorBean, packaged in an EJB JAR of the same name (CalculatorBean), the JNDI name was java:global/CalculatorBean/CalculatorBean.
According to the documentation, I created a Web project and declared my EJB in sub-web.xml the following file:
<ejb-ref>
<ejb-ref-name>ejb/CalculatorBean</ejb-ref-name>
<jndi-name>corbaname:iiop:127.0.0.1:3700#CalculatorBean/CalculatorBean</jndi-name>
</ejb-ref>
where 127.0.0.1 is the host of the machine (local!), 3700 is the default port for querying and, CalculatorBean/CalculatorBean is the global JNDI name. First question, theoretically the JNDI name passes into an interoperable String "CalculatorBean/CalculatorBean" instead of "java: global/CalculatorBean/CalculatorBean", right?
After that, I created a Servlet and put the following code snippet:
ctx = new InitialContext ();
bean = (CalculatorRemote) ctx.lookup ("java:comp/env/ejb/CalculatorBean");
Where, CalculatorRemote is the name of the remote interface that we included in the java project:comp/env/ is the directory section to access Java EE components and ejb/CalculatorBean is the name of my bean in the configuration of the sun-web.xml file
 
When put to run my Servlet I'm getting the exception:
Caused by: javax.naming.NameNotFoundException: No object bound to name java:comp/env/ejb/CalculatorBean
Obviously, it's not finding the name, however, do not really know what name I should use to set the lookup.
I had the same problem, and I solved it.
By default, your EJB is not visilbe into java:comp/env/ and you can not lookup for an EJB into InitialContext instance. But, you can successful lookup for an EJB after when at least one EJB instance is injected using #EJB annotation, like, for your example:
#EJB(name = "ejb/CalculatorBean")
private CalculatorRemote calc;
After that, CalculatorRemote EJB is visible in InitialContext instance.

ProgrammaticLogin

I use ProgrammaticLogin in Glassfish 3.1.2 with username,password and realm and it works good. Anyway when I call context.getCallerPrincipal() I get org.glassfish.security.common.PrincipalImpl with context.getCallerPrincipal().getName() which returns the username.
Is there any way that I can pass Principle via ProgrammaticLogin
so it is passed in my ejb and available from SessionContext - context.getCallerPrincipal()?
I guess you are in a context where resource-injection is not possible via annotations.
You can try to get an instance of the desired EJB via a manual JNDI lookup.
Example:
InitialContext init = new InitialContext();
YourBean bean = (YourBean) init.lookup(JNDI_NAME_OF_YOUR_BEAN);
Now you should be able to pass the Principal to your bean.

Where is the JNDI name in my code?

I have created a EJB2.0 using Eclipse 3.7 IDE, and deployed it in JBoss 5 application server (my bean name is product). I am doing normal context lookup (and other stuff to call ejb), and I am able to call EJB successfully. Now my question is what is JNDI name exactly, and where did it get used in all this. Is my bean name the JNDI name, or is this my JNDI name -> org.jnp.interfaces.NamingContextFactory. Where is the JNDI name in this?????
my code:-
// initial code.............
Context ctx = getContext();
Object obj=ctx.lookup("Product");
ProductHome home =(ProductHome) javax.rmi.PortableRemoteObject.narrow(obj,ProductHome.class);
ProductRemote remote=home.create();
Product prd = new rohit.Product("PRDCamera",001,50.50) ;
remote.addProduct(prd);
remote.updateProduct(prd);
remote.removeProduct(001);
remote.findProduct(001);
remote.findAllProduct();
// getContext Method
public static InitialContext getContext() throws Exception{
Properties pro = new Properties();
pro.put(javax.naming.InitialContext.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
pro.put(javax.naming.InitialContext.PROVIDER_URL,"localhost:1099");
return new InitialContext(pro);
}
There is no JNDI name in your code.
This is how you look up EJBs in EJB 2.0:
Object ejbHome = initialContext.lookup("java:comp/env/com/mycorp/MyEJB");
MyHome myHome = (MyHome)javax.rmi.PortableRemoteObject.narrow(
(org.omg.CORBA.Object)ejbHome, MyHome.class);
The JNDI name is java:comp/env/com/mycorp/MyEJB in this case.
In the much saner EJB 3.0, you just do
MyEJB myEJB = initialContext.lookup("java:comp/env/com/mycorp/MyEJB")
and do away with the terrible home interface idea.

CommunicationException while client's ctx.lookup() in GlassFish 3.1

I have one entity class which implements Serializable and I got this error on client:
javax.naming.CommunicationException:
Communication exception for
SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory,
java.naming.factory.url.pkgs=com.sun.enterprise.naming,
java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl}
[Root exception is
java.rmi.MarshalException: CORBA
BAD_PARAM 1398079494 Maybe; nested
exception is:
java.io.NotSerializableException:
----------BEGIN server-side stack trace----------
org.omg.CORBA.BAD_PARAM: WARNING:
IOP00100006: Class
com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate
is not Serializable vmcid: SUN minor
code: 6 completed: Maybe
when I'm doing SomeService serv = (SomeService)ctx.lookup("java:global/MyProject/SomeServiceImpl");
Does Entity class should be in the same package both in server and in client?
Now Entity class is in the package (dir) of Client App and in the package (dir) where SomeService interface is on the server.
I added #Remote annotation to service interface and error disapeared.
I tried the following and everything works Ok.
When creating InitialContext as:
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.SerialInitContextFactory");
props.setProperty("org.omg.CORBA.ORBInitialHost", "localhost");
props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");
InitialContext ctx = new InitialContext(props);
And later,
myBeanService = (MyBeanService) ctx.lookup("java:global/AppName/MyBeanService");
Shows that exception, but if I just call this way:
myBeanService = (MyBeanService) new InitialContext().lookup("java:global/AppName/MyBeanService");
There is no problem. The problem are the JNDI properties.

Categories