I'm working on jms base wildfly application (wildfly 8, java 7). I have to use event driven library based on Rx Java. I want to send jms message from on even listener which I have to provide to library function to. The problem is that standard EJB based mechanisms for sending jms messages does not work from inside Rx Java handlers. The wild guess is that I can not inject / use annotation based EJB jms mechanisms inside Rx Java stream as they are not spawned by the EJB container (or pass EJB beans as Rx Java handlers). I have tried to send jms messages from EJB singleton as from standalone java application following tutorial like this. The problem is have with this approach is that standalone instance of wildfly can not find dependency for index factory org.jboss.naming.remote.client.InitialContextFactory. Or wildfly won't even deploy if I try to add maven dependency
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-jms-client-bom</artifactId>
<version>${version.wildfly}</version>
<type>pom</type>
</dependency>
to my application fat jar. Any ideas would be greatly appreciated as my understanding of EJB is quite lacking in this matter.
You can use EJBs without dependency injection making a lookup to InitialContext.
After code the Singleton EJB you need to know the "EJB name on JNDI registry" after that you can do:
Context ctx = new InitialContext()
MyStatlessBeanInterface bean = ctx.lookup("FULL NAME BEAN");
bean.sendJMSMessage();
Wilfly prints the EJB name in the console at deployment, but you can read about conventions in:
https://docs.jboss.org/author/display/AS71/JNDI+Reference
Also you can get more information about lookup in:
https://docs.oracle.com/cd/E16439_01/doc.1013/e13981/usclient003.htm
Related
I have a JavaEE ear containing an ejb and war being deployed to GlassFish v3.1.2.2. The war contains a Jersey/Atmosphere application that is using CDI. Within the war, I have an MDB that is asynchronously receiving events it will broadcast using Atmosphere. The message I need to broadcast using Atmosphere needs to includes some links to other resources in the web application.
In order to build those links, like in other places in the code, I would like to use UriBuilder. To do so, I need access to the application's deployed context root, so I can invoke UriBuilder.fromPath(contextRoot)
This Java EE 7 article implies I can inject a ContextServlet into a CDI bean this way:
#Inject ServletContext context;
But this does not work for my MDB. I'm also only on JavaEE6 w/ Glassfish v3.
How can I access the ServletContext from an MDB hosted in my war?
I ended up solving this with the following.
Installed the deltaspike servlet module since I'm on GlassFish v3.1.2.2 which does not have CDI 1.1 which includes a provider for ServletContext out of the box.
Followed the MDB piece of this article to convert my JMS message to a CDI event and then observed that CDI event from a pure CDI bean that had the ServletContext injected in order to build out the required URLs for the Atmosphere message.
We have a multimodule Java EE 5 project running on Weblogic 10.3.x. One module has the EJBs and our batch processor is running from the web-module. Since we don't have CDI in JavaEE5, we have to do a JNDI-lookup on the EJBs. The EJBs are defined with #Stateless on the class and #Remote on the interface.
I have succeeded accessing the EJBs by looking the following string:
ejb/batchService#com.example.service.batch.ejb.BatchServiceRemote
However, I belive this is highly platformdependent, and I suspect I should have put something inside the web.xml and probably into the weblogic.xml at least in the web-module - maybe even in the EJB module...
Could anyone enlighten me how to do this propperly? Or is this the best way available?
JNDI format of local bean is
java:comp/env/BeanClassName
JNDI format for remote bean is
mappedName#com.package.BeanClassName
for
#Stateless(mappedName = "mappedName")
public class BeanClassName {
PS. This format supported by WebLogic 10.3. Behaviour of another application servers may be differentю
Prior to EJB 3.1 / EE 6, there are no standardized lookup strings for EJBs. Since they're not standardized, hard-coding the actual binding name of the EJB does make your project product-specific.
The best solution is to create another level of indirection: declare an <ejb-local-ref> in web.xml (or as #EJB/#EJBs on a servlet or other component class), and then use java:comp/env/xyz to lookup the ref. Then, use platform-specific bindings for the EJB ref.
I've an EAR app contains two modules.
EJB Module and Web Module.
In web module, I am trying to get a ref to some EJB SLSB, I don't use injection cause the class the I need to invoke the method in is not managed.
I am using the following code from the web module:
IFooBarService service = InitialContext.doLookup("IFooBarService");
IFooBarService: the the Local Interface that defined as ( in the ejb module):
#Local
public interface IFooBarService
{
// ...
}
Do I miss something? (should I supply environment info?)
Are you sure that IFooBarService is the JNDI name the IFooBarService service is bound to? JBoss for example shows the JNDI names in the boot log. You can then use it for lookup purposes.
In general, if you want your app to be portable you shouldn't rely on the server mechanism to generate JNDI names, as the Java EE spec has its own. You should be able to do:
IFooBarService service = InitialContext.doLookup("java:comp/env/IFooBarService");
If you are using newer versions of Java EE (Java EE 6), and want to lookup an EJB which is in the same app but in a different module, you can do:
IFooBarService service = InitialContext.doLookup("java:app/[module name]/IFooBarService");
More info on standard names here.
From Here: https://forums.oracle.com/forums/thread.jspa?threadID=476903
The solution is:
fooBarService = (FooBarService) ((StatelessSessionDefaultLocalHome)
new InitialContext().lookup("EJBModuleName_FooBarServiceLocal")).create();
I have deployed an enterprise app in an EAR and a standalone web app in WAR (out side of the EAR) to the same Java EE server.
Question is can I access the local interface of the session bean in the EAR from the standalone WAR? if so can I use dependency injection (DI)?
Section 3.2.2 of the EJB 3.1 specification explicitly states that this is not portable:
Access to an enterprise bean through
the local client view is only required
to be supported for local clients
packaged within the same application
as the enterprise bean that provides
the local client view. Compliant
implementations of this specification
may optionally support access to the
local client view of an enterprise
bean from a local client packaged in a
different application. The
configuration requirements for
inter-application access to the local
client view are vendor-specific and
are outside the scope of this
specification. Applications relying on
inter-application access to the local
client view are non-portable.
In general, the solution will require at a minimum:
Some mechanism for allowing both the EAR and WAR class loaders to have visibility to the same interface class.
Some mechanism for looking up a local interface from another application. For example, java:global.
The answer anyway to both your questions is yes.
Since both the ear and war are in the same JVM, a local interface can be used. To get an instance of the session bean, you would use the global JNDI name of said bean to do either a JNDI lookup or use with the mappedName property on the #EJB annotation. Those names are standardized via the following pattern:
java:global[/<app-name>]/<module-name>/<bean-name>[!<fully-qualified-interface-name>]
Lookup would thus be if the name of your ear is my_app, your bean is MyBean.java and its local interface is com.foo.SomeBeanLocal:
InitialContext ctx = InitialContext();
SomeBeanLocal someBean = (SomeBeanLocal) ctx.lookup("java:global/my_ear/SomeBean/com.foo.SomeBeanLocal");
Injection would be:
public SomeManagedClass {
#EJB(mappedName="java:global/my_ear/SomeBean/com.foo.SomeBeanLocal")
SomeBeanLocal someBean;
}
There are two catches however:
Non-standard naming
Older Java EE implementations (e.g. JBoss AS 5.1, Glassfish 2, Websphere) used their own naming pattern. E.g. JBoss AS 5.x would use:
<app-name>/<bean-name>/local|global
E.g. with the same names as the previous example, the global JNDI name of that bean in JBoss AS 5.1 would be:
my_app/MyBean/local
As said, other old application servers might use other names.
Startup-order
Especially with injection you have to assure somehow that the application you want to inject from has been started before the application you want to inject into. I.e. in your case that the EAR has been started before the standalone WAR. There are no standard mechanisms for this. You might be just lucky that it happens to be in the right order for you. This order might be influenced by time-stamps, alphabetical order of application names, or something else entirely.
JBoss AS for example uses <depends> tags in many of its proprietary configuration files, which is perfectly suited for this although it can be hard to find out what exactly you need to depend on (the syntax can be very cryptic).
I'm trying to inject a EJB within my RESTful Service (RESTEasy) via Annotations.
public class MyServelet implements MyServeletInterface {
...
#EJB
MyBean mybean;
...
}
Unfortunately there is no compilation or AS error, the variable "mybean" is just null and I get a NullPointerException when I try to use it.
What I'm doing wrong?
Here are some side-informations about my architecture:
JBoss 4.2.2.GA
Java version: 1.5.0_17
local MDB-Project
remote EJB-Project
WAR Project with the RESTful Service which uses the remote EJB and sends messages to the local MDB-Project
Thanks in advance!
br
Dominik
p.s: everything is working fine when I use normal context lookup.
I had a similar problem (though without #Remote beans). The way it worked for me - sample application is here: https://github.com/kubamarchwicki/rest-app/ (this works: https://github.com/kubamarchwicki/rest-app/blob/master/service-webapp/src/main/webapp/WEB-INF/web.xml#L9)
The crack with context lookup is that the name changes with a change of the ear name. If you fancy things like versions, it makes the whole thing hard to trace or forces you to hardcode ear name somewhere in the code.
Just a few cents to an old discussion ;-)
This is not exactly my forte, so maybe I am way off... but, can you do EJB stuff in a WAR? I was under the impression you needed to do EJB work in an EAR.
JBoss 4.2.2.GA is not a fully compliant Java EE 5 server, it does not support EJB references injection in servlets or application clients, only in the EJB layer. Use JBoss 5 for that (or perform a lookup).
JBoss 4.2.2.GA supports only Servlet 2.4. There is no support of DI on Servlet 2.4. Hence you always get 'null' for myBean variable. As suggested, please migrate to JBoss 5.0 which supports Servlet 2.5 which makes use of Java 5 features like annotations.