is it possible to create something like static object using EJB3 in Jboss. in other words i need to create something like a static object using singleton pattern or something like that, that is because i need to preload a configuration from database and i want that every bean that jboss creates uses this class to read this configuration instead of that every bean load it from the database.
Cheers,
EJB 3.1 does have a standard #Singleton annotation but EJB 3.0 doesn't. However, JBoss offers a JBoss extension to the EJB 3.0 spec to create a singleton with the #Service annotation.
From the JBoss EJB 3.0 Reference Documentation:
Chapter 6. JBoss EJB 3.0 extensions
JBoss provides a few extensions to the
EJB 3.0 spec. This chapter describes
those features here.
6.1. #Service EJBs
An extension offered by JBoss EJB 3.0
is the notion of a
#org.jboss.annotation.ejb.Service
annotated bean. They are singleton
beans and are not pooled, so only one
instance of the bean exists in the
server. They can have both #Remote and
#Local interfaces so they can be
accessed by java clients. When
different clients look up the
interfaces for #Service beans, all
clients will work on the same instance
of the bean on the server. When
installing the bean it gets given a
JMX ObjectName in the MBean server it
runs on. The default is
jboss.j2ee:service=EJB3,name=<Fully qualified name of #Service bean>,type=service
You can override this default
ObjectName by specifying the
objectName attribute of the
#Service annotation.
References
JBoss EJB 3.0 Reference Documentation
6.1. #Service EJBs
JBoss EJB3 Tutorials
Chapter 28. Service POJOs (JBoss extension of EJB3)
Bean with #Singleton annotation should work. Place your database initialize code in #PostConstruct & can release/cleanup in #PreDestroy.
Related
I have demo application with JPA 2.1 and weblogic 12.1.3 deployment works fine and am able to get EntityManager which is annotated on the stateless bean.
I have application where I have ejb-jar.xml, on this file we have configured all MDB and session beans, Note: application is not using annotation.
And ejb-jar.xml uses http://java.sun.com/dtd/ejb-jar_2_0.dtd(ejb 2), but our application is running on weblogic 12.1.3. On this configuration, I tried to get EntityManager with the help of annotation in MDB, but am getting null object.
Question.
1. Is it possible to annotate EntityManager, with above configuration.
2. If not possible what are alternative ways. meaning I need to move all the configuration of ejb-jar.xml to annotation.
Thanks
Daya
As part of an structural refactor, we moved our application EAR building technique from a custom, weird Ant script to a full Maven solution.
The final structure used to be a EAR containing a single EJB build by merging two EJBs; the application core and the customer-specific implementation which may define some decorators.
The new structure we wanted to put in place was rather an EAR containing the two EJBs side-by-side. This works mostly as expected except for the interceptors and decorators.
In the customer-specific implementation, we define decorators that looks like this:
import javax.annotation.Priority;
import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.inject.Inject;
import javax.interceptor.Interceptor;
#Decorator
#Priority(Interceptor.Priority.APPLICATION)
public class ServiceDecorator implements ServiceInterface {
#Inject
#Delegate
ServiceBean delegate;
Upon startup on Wildfly 10.1, Weld (2.3.5-Final, shipped with Wildfly) reports that the decorator is indeed enabled but it never seems to be able to bind the decorator to the service which reside in the core implementation.
DEBUG [org.jboss.weld.Bootstrap] (MSC service thread 1-6) WELD-000104: Enabled decorator types for Weld BeanManager for /opt/wildfly/standalone/deployments/app.ear/core.jar [bean count=2]:
- class ServiceDecorator
[...]
DEBUG [org.jboss.weld.Bootstrap] (MSC service thread 1-6) WELD-000108: Decorator: Decorator [class ServiceDecorator] decorates [Service] with delegate type [ServiceBean] and delegate qualifiers [#Default]
We even tracked down the code in Weld core and we have indeed seen that the decorator is globally enabled () but never bound to the service since the core implementation bean manager does not see the decorator bean.
We also tried moving the decorator in a regular lib jar and got the same result. Interceptors were also attempted as well as using the #Specialize annotation, all to no avail...
So, in summary, is there any way to define a decorator or interceptor in an EJB to enhance the behavior of a service located in another EJB when both are contained in the same EAR?
We're using Maven and Artifactory, and therefore our ear files have names like
our-project-ear-0.0.1-20151215.151526-3.ear.
So JNDI names for our EJBs have names like
java:global/our-project-ear/our-project-ejb/AnEjbJar!com.acme.ourproject.SomeEjb.
These names are not just ugly and complex, they also embed temporary suffixes added by Maven/Artifactory.
I thought we could simplify the names via the JBoss-specific #RemoteHomeBinding annotation, but I do not find this annotation in EAP 6.3. Is there still a way to do this? If not, how can I control the JNDI name under which my EJBs are published?
Figured it out myself. The #RemoteBinding, #LocalBinding, #RemoteHomeBinding and #LocalHomeBinding annotations have been phased out in AS7.x. A version of the JBoss instructions for migrating from AS5/6 to AS7 (not the current one) states:
>In AS7 there is no possibility for custom JNDI names of EJB beans and it's not planned for 7.1.
>Therefor the annotation #RemoteBindings and #LocalBindings are not available.
The recommended approach is to use the default bindings. However, custom JNDI names can also be defined via the #EJB annotation, as stated in this Oracle blog:
The developer can select an additional JNDI name that resolves to a particular client view of a session bean by using the #EJB annotation. Starting with Java EE 6, the #EJB name() attribute value can be prefixed with any one of the three portable Java EE namespaces : java:global, java:app, java:module. This has the effect of exporting the dependency into the selected scope.
I think what you are looking for is :
#Ejb(lookup="java:/global/somecustomPath")
As this will not affect where in JNDI the bean is bound but rather where to find it in JNDI.
If I'm right this is because JBOSS7 is a JEE6 application server and JEE6 introduced the concept of Portable Global JNDI names in JEE6.
First I will describe what I am trying to accomplish here. I have a Java application that periodically reads data and calls stateless EJB on JBoss AS 7.1.1 for further operations (computing data and saving it into the DB). Then I have front end which uses JSF 2.0. In controller which is a #ApplicationScoped CDI bean and resides in JSF project I inject EJB into it. Now I need EJB for getting data from the DB. I am using #ApplicationScoped CDI bean because of this reason:
The application context is shared between all servlet requests, web service invocations, EJB remote method invocations, EJB asynchronous method invocations, EJB timeouts and message deliveries to message-driven beans that execute within the same application. The application context is destroyed when the application is shut down.
I want only one CDI bean for all the clients, because the data is independent of the user.
Now I want to update data in #ApplicationScoped CDI bean, which is defined under JSF project with the help of EJB bean, which method is executed when new data arrives. I have already successfully used #Inject in #ApplicationScoped CDI bean, where I have injected EJB from EJB project. Now I want to do the other way around. I tried to inject ApplicationScoped CDI bean from JSF project into EJB bean. But when I wrote this I got #Inject underline as warning:
#Inject
private CurrentDataController currentDataController;
The warning is:
No bean is eligible for injection to the injection point [JSR-299 ยง5.2.1]
When I try to publish project I get error about class not found exception for CurrentDataController.
Caused by: java.lang.ClassNotFoundException: controllers.CurrentDataController from [Module "deployment.TestEAR.ear.TestEJB.jar:main" from Service Module Loader]
It seems that the EJB project can't reference class in JSF project. Also it is looking for CurentDataController class in TestEJB.jar instead of in the TestJSF.jar. What I am missing here?
The structure of my whole project is as follow:
TestEAR
TestEJB
TestEJBClient
TestJPA
TestJSF
Now I reckon that after I will fix the error about no class definition found I will have another problem connected with the warning I have posted.
In an EAR the EJB modules (jar) don't have visibility on the Web modules (war). EJB module is UI agnostic so it's normal to have this layer decoupling.
To resolve you issue you have two options.
Move the bean that need to be injected in your EJB in one EJB module (the war would also be able to inject that bean)
Refactor your app to have only a war (yes you can have EJB in war now). Architecture would be simplier and full EJB will work under JBoss (remote EJB too)
I have a java class which implements an interface from an external library.
I converted this java class into an EJB by anotating with #Stateless.
The reason I converted this to an EJB is for leveraging the dependency injection and to get an handle for EntityManager API. But I am not able to inject this Stateless bean into other EJBs.
Have you tried to annotate your EJB with #Stateless and #Local too? It should contain the name of the interface as value: #Local(MyBeanInterface.class)