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)
Related
I have 2 separate projects.
the first project is based on jboss server and implements ejb classes.
the second project is a rest api using the play server.
I want to invoke ejb classes from rest api using jndi .
Have someone any idea how to to invoke ejb classes from client side : we want to package ejb class and transform it into a jar that we want to use it in client side.
We have a widlfy REST API jaxrs and we want to secure it with keycloak.
The problem is the integration with #SecurityDomain("keycloak") is working only with an EJB entry-point. it is ignored on class with no #Stateless annotation
The issue is the entry point become an EJB and EJB poolManaged what is not really a good thing for a stateless application.
Moreover all methods in EJB are transactional and we do not want this behavior. So yes we can add an annotation transactional to specify to not use transaction in the method, but i think it is a workaround.
We want to work the most we can with CDI. and have entry point with ejb pool management with in wildlfy 20 EJB in same time can be a bottleneck in a big application.
Any idea ? or proper way to implement keycloak security with CDI ?
If you mean declarative security using #RolesAllowed annotation this is not supported on all CDI beans, is only supported by EJBs and Servlets.
As JAX-RS will run on a webapp, you can use declarative security based on url-patterns and HTTP methods using security-constraints in web.xml
You can also implement programmatic security in the JAX-RS methods (or in a filter), using the SecurityContext.
#Context
SecurityContext securityContext;
#GET
public Response get() {
if (securityContext.isUserInRole("ROLE")) {
....
}
....
}
Although not and standard feature, Wildfly JAX-RS implementation, RestEasy, can be configured to support #RolesAllowed annotations. See:
https://docs.jboss.org/resteasy/docs/4.4.2.Final/userguide/html/Securing_JAX-RS_and_RESTeasy.html
I know that EntityManager instantiated by myself is not thread-safe.
I know that EntityManager injected via #PersistenceContext in EJB behaves like hread-safe, because EJB container serializes access to EJB beans.
I know that in EJB injected EntityManager is really a proxy.
I know that when I inject EntityManager via #PersistenceContext to #Dependent CDI bean and inject that bean to EJB, it behaves like thread-safe because of covering EJB (I believe that in this case EntityManager is proxy too).
But:
What happens when I inject EntityManager via #PersistenceContext to CDI bean and use this bean directly for example in Servlet? I believe that this EntityManager is a proxy, so does this proxy guarantee thread safety?
Edit: Similar question Java CDI #PersistenceContext and thread safety does't solve my problem, because accepted answer shows EJB examples, not CDI examples.
Edit: I checked source code of WildFly application server and it looks that WildFly uses thread-safe proxy in CDI. This proxy selects real EntityManager when needed. Real EntityManagers are kept in special structure - stack of maps of EntityManagers in ThreadLocal.
https://www.javacodegeeks.com/2013/06/jpa-2-entitymanagers-transactions-and-everything-around-it.html says:
The biggest benefit of using Transaction Scoped Entity Manager is that
it is stateless. This also makes the Transaction Scoped EntityManager
threadsafe and thus virtually maintenance free
also pro JPA book says:
a transaction-scoped entity manager is stateless, meaning that it can
be safely stored on any Java EE component
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)
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.