Hot questions for Using Enterprise JavaBeans in inject

Question:

My configuration is: Wildfly 8.2.0, Weld

Is it possible to inject in bean and not in its interface in CDI ?

@Stateless
class Bean implements IBean {
...
}    

interface IBean {
...
}

@SessionScoped
class Scoped {
   @Inject
   Bean bean; //Fail

   @Inject
   IBean iBean; //OK
}

EDIT:

More Info in my previous question: Stateless EJB implements interface injection failed


Answer:

Yes you can, but as EJB inject the business view the only business view you are exposing is the @Local view which is the default when you implement an interface (IBean in your case is a local business interface). So, if you want to inject the bean itself, you need to tell the container that you are using the no-interface view.

In your example, if you still want to implement your interface and inject Bean you should use the @LocalBean annotation which means that the bean exposes a no-interface view:

@Stateless
@LocalBean // <-- no-interface view
class Bean implements IBean {
...
}  

interface IBean {
....
}

@SessionScoped
class Scoped {
   @Inject
   Bean bean; //Should be OK
}

Or, If you don't want to implement any interface, then the bean defines by default a No-Interface view:

@Stateless
class Bean {
...
}  

@SessionScoped
class Scoped {
   @Inject
   Bean bean; //OK
}
See also:

Question:

After reading these,

  • Where to use EJB 3.1 and CDI?
  • How do CDI and EJB compare? interact? and some other articles.

I'm still confused over the following things, please correct me if i am wrong.

  1. All classes within the same package as the bean.xml is a CDI bean except for classes annotate as session/message/singleton.
  2. Only EJB can be injected using @EJB(within another EJB), while both CDI bean and EJB bean can be injected using @inject(within EJB bean or CDI bean).
  3. class annotate as @Stateless(for example) that is injected using @Inject is still a EJB bean, not a CDI bean, and will still be managed by EJB container with all the goodness of pooling and transactional.

Thanks alot. :)


Answer:

I would make the following corrections:

  1. All classes within the same archive as the beans.xml is a CDI bean, including EJBs.

  2. Only EJB can be injected using @EJB (within another EJB or any other EE managed object including CDI beans), while both CDI bean and EJB bean can be injected using @inject (within EJB bean or CDI bean).

  3. A class annotated as @Stateless (for example) that is injected using @Inject is still an EJB bean, and it may also be a CDI bean if in a bean deployment archive; regardless, it will still be managed by EJB container with all the goodness of pooling and transactional.

Notably, a CDI managed bean is anything that can be @Injected into another CDI bean and can itself use @Inject, which is true for all EJBs, and @EJB can be used to inject an EJB into any other EE managed bean (EJB, servlet, CDI managed bean, etc.).

Question:

I have something like this setup below. This is a simplified version but I think it gets the basic idea across. I am using Jersey 2.16, Java 1.8, and Glassfish Open Source 4.1

public interface IReportService {
    String addNewReport(Report report);
}

@Path("reports")
public class ReportResource implements IReportService {
    /**
    * Service layer.
    */
    @EJB
    private transient ReportService service;

    @POST
    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    @Produces(MediaType.TEXT_PLAIN)
    @Override
    public String addNewReport(final Report report) {
       return service.addNewReport(report);
    }
}

@Stateless
@LocalBean
public class ReportService implements IReportService {

   @EJB
   private IReportPersistence reportPersistence;

   @Context
   SecurityContext secContext;

   public String addNewReport(final Report report) {
       report.setUserName(secContext.getUserPrincipal().getName());
       reportPersistence.persist(report);
    }
}

But when I deploy and try to hit the web-service I get a NullPointer exception from the security context. It just seems that the Context is not being injected at all. I checked and it's the secContext variable itself, not just the return from getUserPrincipal() that is null. There are no warning or exceptions in the Glassfish log besides my NullPointer (which results in a 500 error returned to the web client).


Answer:

The problem is that you are using the SecurityContext in the wrong place. You have to use it inside your REST resource class.

You can try the following:

@POST
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces(MediaType.TEXT_PLAIN)
@Override
public String addNewReport(final Report report, @Context SecurityContext sc) {
   report.setUserName(sC.getUserPrincipal().getName());
   return service.addNewReport(report);
}

For more details have a look at the Jersey Documentation - Chapter 16. Security.

Inside of EJBs you have to use the EJBContext (or the SessionContext).

Question:

Currently, I'm using PersistenceContext to inject an EntityManager. The EM is injected perfectly.

@Stateless
public StatelessSessionBean implements StatelessSessionBeanLocal {

    @PersistenceContext(unitName = "MyPersistenceUnit")
    private EntityManager em;

    @Override
    public Collection<MyObject> getAllObjects(){
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriqQuery<MyObject> query = cb.createQuery(MyObject.class);
        query.from(MyObject);
        return em.createQuery(query).getResultList();
    }
}

Now I try to decorate the bean, and suddenly the em doesn't get injected. I get a NullPointerException.

@Decorator
public StatelessSessionBeanDecorator implements StatelessSessionBeanLocal {

    @Inject
    @Delegate
    @Any
    StatelessSessionBeanLocal sb

    @Override
    public Collection<MyObject> getAllObjects(){
        System.out.println("Decorated method!");
        return sb.getAllObjects();
    }
}

I know EJB and CDI are 2 completely different managers, so the one doesn't know about the other. I'm expecting that @PersistenceContext is an EJB injection point, while @Inject is a CDI one. What should I do to solve this and get the EntityManager to be injected like it should?


Answer:

The best practice for persistence context and CDI is to make them CDI bean to avoid these kind of issue.

public class MyProducers {
    @Produces
    @PersistenceContext(unitName = "MyPersistenceUnit")
    private EntityManager em;
}

After that you'll be able to inject the EntityManager in CDI way. Taking your EJB it'll be :

@Stateless
public StatelessSessionBean implements StatelessSessionBeanLocal {

    @Inject
    private EntityManager em;

    @Override
    public Collection<MyObject> getAllObjects(){
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriqQuery<MyObject> query = cb.createQuery(MyObject.class);
        query.from(MyObject);
        return em.createQuery(query).getResultList();
    }
}

This way, you'll be able to decorate your CDI bean with no issue.

If you have multiple EntityManagers you can use CDI qualifiers to distinguish them

Question:

I'm trying to implement Java EE's managed executor ManagedExecutorService to submit callable tasks, where each task makes a call to an injected bean method.

I'm using the Instance class to make the container aware of the task object, but when get() is executed the following exception is thrown:

Caused by: javax.ejb.EJBException: org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001334: Unsatisfied dependencies for type MyTask with qualifiers @Default

I'm running this on WildFly 14.

The injected bean:

@Stateless
public class MyBean {

    public void print() {
        System.out.println("MyBean printed");
    }
}

The task:

@Stateless
public class MyTask implements Callable<String> {

    @Inject
    MyBean myBean;

    @Override
    public String call() throws Exception {

        System.out.println("MyTask called");
        myBean.print();
        return "Task called";

    }
}

The task invoker:

@Stateless
public class TestBean {

    @Inject
    Instance<MyTask> myTaskInstance;

    @Resource
    private ManagedExecutorService executor;

    public void test() throws InterruptedException, ExecutionException {

        List<Callable<String>> tasks = new ArrayList<>(); 
        MyTask task = myTaskInstance.get();  // <------- Exception is thrown here
        tasks.add(task);
        MyTask task2 = myTaskInstance.get();
        tasks.add(task2);

        List<Future<String>> taskResults = null;
        taskResults = executor.invokeAll(tasks);

        List<String> results = new ArrayList<>(); 

        for(Future<String> taskResult : taskResults) {
                results.add(taskResult.get());
        }

    }
}

Why is the exception thrown and how to fix this problem? Is there a library missing in the classpath?


Answer:

The problem is that with MyTask as an EJB implementing Callable, you've removed the MyTask class itself from the "bean type" of this bean, which means it can't be injected into @Inject MyTask xxx "client", according to the rules in the CDI 2.0 spec:

18.2.2. Bean types of a session bean

The unrestricted set of bean types for a session bean contains all local interfaces of the bean and their superinterfaces. If the session bean has a no-interface view, the unrestricted set of bean types contains the bean class and all superclasses. In addition, java.lang.Object is a bean type of every session bean.

That's why Weld doesn't find a valid MyTask bean to satisfy the injection into your TestBean client.

You can give the MyTask EJB a no-interface view by adding the @LocalBean annotation, e.g.:

@Stateless
@LocalBean
public class MyTask implements Callable<String> {

Or, you can remove the implements Callable and refactor like:

public class MyTask {

    @Inject
    MyBean myBean;

    MyCallable callable = new MyCallable();

    public Callable getCallable() {
        return callable;
    }

    private class MyCallable implements Callable<String> {
        @Override
        public String call() throws Exception {

            System.out.println("MyTask called");
            myBean.print();
            return "Task called";
        }
    }
}    

public class TestBean {

    // ...

    MyTask task = myTaskInstance.get(); 
    tasks.add(task.getCallable())

    // ...
}

See here for a quick reference on the no-interface view, as well as this post for more discussion.

Question:

I have a simple case where I have a REST Service MyService that should get injected with a bean beanB of type BeanB which implements interface BeanBInterface. The error I get is the classic WELD-001408 one shown below:

org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type BeanBInterface with qualifiers @BeanBQualifier
  at injection point [BackedAnnotatedField] @Inject @BeanBQualifier public com.example.MyService.beanB
  at com.example.MyService.beanB(MyService.java:0)

The REST Service:

import javax.ws.rs.Path;
import javax.inject.Inject;

@Path("/")
public class MyService {
    @Inject 
    @BeanBQualifier(BeanBQualifier.Type.PROD)
    public BeanBInterface beanB;

    public MyService() {}
}

Bean Interface:

public interface BeanBInterface {
}

Bean Implementation:

import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.enterprise.inject.Produces;

@Startup
@Singleton
@BeanBQualifier(BeanBQualifier.Type.PROD)
public class BeanB implements BeanBInterface {
    private String name = "B";

    public BeanB() {}

    public String getName() {return name;}

    public void setName(String name) {this.name = name;}
}

The Bean Qualifier

import javax.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE})
public @interface BeanBQualifier {
   Type value();
   enum Type{PROD, TEST}
}

Beans.xml (tried in META-INF/beans.xml and also tried in WEB-INF/beans.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee  http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"

    bean-discovery-mode="annotated">
</beans>

I also tried a bean-discovery-mode="all" with no luck.

If I make the declaration of beanB to use the concrete class BeanB rather than its interface in MyService it works (but that defeats the purpose of an interface):

If I add an @Produces factory method to MyService to construct the bean it also works but this defeats the purpose of letting the container instantiate my beans for me:

@javax.enterprise.inject.Produces
public static BeanB get() {
    return new BeanB();
}

but if this @Produces factory method returns the interface instead it won't work:

@javax.enterprise.inject.Produces
public static BeanBInterface get() {
    return new BeanB();
}

Answer:

EJBs have some weird rules about what interfaces are actually exposed as implemented. Only interfaces marked as @Local/@Remote will be exposed. If you want to use the bean with the interface and with the class you need to add @LocalBean to the ejb.

In short: add @Local to the interface or @Local(BeanBInterface.class) to BeanB

Question:

My app is being deployed on to IBM WebSphere. I have a simple service and I'd like to know how dependency injection works in this case.

// stateless EJB
@Stateless
public class UserService {

    private UserDAO userDAO;

    // btw, UserDAO is stateless EJB as well
    @Inject
    public UserService(UserDAO userDAO) {
        this.userDAO = userDAO;    
    }

    // biz methods ...
}

It fails with the following error:

[ERROR ] CWWKZ0002E: An exception occurred while starting the application my-app. The exception message was: com.ibm.ws.container.service.state.StateChangeException: com.ibm.ws.cdi.CDIException: com.ibm.wsspi.injectionengine.InjectionException: com.ibm.ejs.container.EJBConfigurationException: EJB class com.demo.app.UserService must have a public constructor that takes no parameters

I remember there was something in EJB spec that says: the class must have a public constructor that takes no parameters and it makes sense for me that the bean instance is first instantiated by the container and afterward dependency injection is done.

On the other hand, I've found this in WELD docs:

First, the container calls the bean constructor (the default constructor or the one annotated @Inject), to obtain an instance of the bean.

And I am confused a little bit, why my EJB cannot be instantiated.

How is the EJB instance being created and dependencies injected when we have constructor injection point?

Any ideas? :)


Answer:

So what happens is that you do not meet the requirements for initializing EJB beans.

CDI spec has some limitations on constructors - either no-args or one with @Inject. But there is also this chapter, which specifies that in EE, the set of rules is extended by what EJB session beans require.

And now we are getting into EJB spec which requires a no-arg constructor on a bean. This should be in chapter Enterprise Bean Class where it states

The class must define a public constructor that takes no arguments.

Now, finally moving on to whether this should work - e.g. can you have an EJB bean using CDI constructor injection? Well, let's have a look at CDI TCK, a set of tests that all implementation and containers have to pass in order to be able to claim they implement CDI. There, we can see this bean and this test using it - so yea, this can work, but you need to have both constructors.

Question:

I am testing out some JMS work on Paraya 5. Specifically 5.181. Below is the code for my simple Stateless bean. @JMSConnectionFactory fails! the JMSContext context variable is always null. However @Resource(lookup = "jms/HelloWorldConnectionFactory") succeeds...Any thoughts as to why? I'd prefer to use JMSContext.

@Stateless
public class HelloWorldMessageSender {

    @JMSConnectionFactory("jms/HelloWorldConnectionFactory")
    protected JMSContext context;

    @Resource(lookup = "jms/HelloWorldConnectionFactory")
    protected ConnectionFactory connectionFactory;

    @Resource(lookup = "jms/HelloWorldQueue")
    protected Queue queue;

    public String send() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS");
        String txt = String.format("Hello world message %s", sdf.format(new Date()));
        if (context != null) {
            System.out.printf("Use JMSContext to produce%n");
            context.createProducer().send(queue, txt);
        }
        if (connectionFactory != null) {
            System.out.printf("Use ConnectionFactory to produce%n");
            try (
                Connection connection = connectionFactory.createConnection();
                Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                MessageProducer producer = session.createProducer(queue);
            ) {
                TextMessage message = session.createTextMessage();
                message.setText(txt);
                producer.send(message);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return txt;
    }
}

Just as a note, the @Stateless bean is being used inside of a JSF @Named bean. I'm using simple CDI injection to get the @Stateless bean, like this:

@Named(value = "helloWorldMessageController")
@RequestScoped
public class HelloWorldMessageController {

    @Inject
    protected HelloWorldMessageSender sender;

    // ....
}

Answer:

The annotation @JMSConnectionFactory has to be used with @Inject otherwise it doesn't have any effect. It just adds meta data for injection but doesn't cause any injection to happen.

It's clear from the example in the JMS 2.0 specification PDF:

@Inject @JMSConnectionFactory("jms/connectionFactory") private JMSContext context;

On the other hand, @Resource annotation is enough for injection because they are processed by the EJB container which handles them as injection point. So you should either use a single @Resource annotation or both @Inject and @JMSConnectionFactory together.

Question:

Is there any way an injectee(EJB, say) know its own injection point?

@Stateless
public class SomeService {

    @PostConstruct
    private void constructed() {
        // do post construction job
        // according to the injectionPoint
    }

    @Context
    private InjectionPoint injectionPoint; // is this possible?
}

Answer:

If you are injecting your EJB with CDI (using @Inject) and if it has the default scope (no explicit scope or @Dependent).

You can inject its injection point:

@Stateless
public class SomeService {

    @PostConstruct
    private void constructed() {
        // do post construction job
        // according to the injectionPoint
    }

    @Inject
    private InjectionPoint injectionPoint; // this is possible
}

Question:

I am using eclipse with GlassFish 5. I am making a three tier application using swing. First I made a JPA Project and then added EJB Facet. Schema is being successfully created with entity classes.

I am getting a null on my EJB injection and EntityManager Injection.

In my controller I have injected EJB as follows:

public class BookQueries {

    @EJB
    private  BookService bs;

    public BookQueries() {
    /*try {

        Context context = new InitialContext();         
        Object fObj = context
            .lookup("java:global/LMS/BookService!com.lms.service.BookService");
        bs=(BookService)fObj;
    }catch(NamingException e) {
        System.out.println("Naming Exception while lookup of bean object");
    }
    */
}

As you can see in controller constructor I have also tried JNDI lookup but I still get null.Here is my EJB class in which I have Injected EntityManager which also is null.

@Stateless
@LocalBean
public class BookService {

    @PersistenceContext(name = "LMS")
    EntityManager em;

}

Here is my Persistence.xml file

<persistence-unit name="LMS">   
    <jta-data-source>jdbc/lms</jta-data-source>
    <properties>
        <property name="eclipselink.ddl-generation"
                  value="drop-and-create-tables" />
    </properties>
</persistence-unit>

I have previously made Web Dynamic Application on Eclipse and it all works fine there.

Kindly let me know what I am doing wrong. Thank you.


Answer:

First the latter, your BookService should have:

@PersistenceContext(unitName = "LMS") // not 'name'

or you can try without any unitName if there are no other PUs in use.

Then about your BookQueries is it itself a managed bean I cannot see any bean related annotations in it? If it is not then the @EJB stuff will not be initialized. For example, if it is meant to be a Singleton bean add annotations:

@Singleton
@Startup  // makes it to be initialized at app startup

or

@LocalBean

Doing like new BookQueries() does not make it managed and thus no injection or such thing happens. You need to annotate it (or configure it somewhere in control panel of Glassfish or in beans.xml) to be known bean. And then inject it to some managed context (UI class?), for example with @Inject or @Resource quite like you inject BookService.

Also I recommend you to check out if you should use annotations like @Inject or @Resource rather than @EJB.

Question:

I'm using Wildfly 10 and Java 8. I've tried to bind my service like here but I still getting this error. The only differences that I can see are on the pom.xml dependencies, but the 2.0-rc1 version is old.

[io.undertow.request] (default task-2) UT005023: Exception handling request to /api/account: javax.servlet.ServletException: A MultiException has 3 exceptions.  They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=ICuentaService,parent=CuentaServiceRS,qualifiers={},position=-1,optional=false,self=false,unqualified=null,287721117)
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of ar.com.olx.api.rest.CuentaServiceRS errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on ar.com.olx.api.rest.CuentaServiceRS

My API REST class

@Path("/account")
public class CuentaServiceRS {

    @Inject
    private ICuentaService cuentaService;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Cuenta getCuenta() {

        return cuentaService.getCuentas().get(0);

    }

}

pom.xml

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.22.2</version>
</dependency>

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>2.22.2</version>
</dependency>

web.xml

<servlet>
        <servlet-name>altitudeservlet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>ar.com.villat.bind.ApplicationJaxRS</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

My Application JAX-RS class

public class ApplicationJaxRS extends ResourceConfig {

    public ApplicationJaxRS(){
        register(new CustomBinder());
        packages(true, "ar.com.villat");
    }

}

And lastly, my custom binder

public class CustomBinder extends AbstractBinder {

    @Override
    protected void configure() {
        bind(ICuentaService.class).to(CuentaServiceImpl.class);
    }

}

If you need more details, please tell me


Answer:

In the AbstractBinder, it should be bind(Implementation).to(Contract). You have it the other way around. The reason they do it this way is that it's possible for an implementation to have multiple contracts, so you would be able to just chain to calls.

Question:

Our application consists of web pages that interact with backing beans and Stateless EJB services, but there is also a remote client that interacts with the Stateless EJB services.

Many of the services query the DB and then filter the result set based on the current user/caller (for example, users have permission to view only some record types); that is, they use programmatic rather than declarative security.

On the web side, my intuition would be to store the currently logged-in user in a SessionBean, but I want the Stateless EJB services to filter the result set based on the currently logged-in user so that the filtering also applies during remote client calls. I can inject a SessionBean into a Stateless EJB service, but I think SessionBeans use HTTP sessions, and as there is no HTTP session during a remote client call, I don't see how that could work.

I sense that my approach is wrong, and that I should be retrieving the "Principal" from the container; however, due to our application's development lifecycle, container-managed security is not set-up yet, but I am still tasked to implement the business logic responsible for filtering records now rather than later.

My closely-related questions:

  1. Can a SessionScoped bean be injected into a Stateless EJB knowing that the Statelesss EJB will be invoked by remote clients? What is the value of the SessionScoped bean in that case?
  2. Instead of a SessionScoped bean, should my backing beans and Stateless EJB services be retrieving the Principal from the container?
    • If yes, how can I substitute a mock Principal to work on the business logic until container-managed security is set-up?

p.s. I am new to Java EE.

Technology:

  • Java EE 6
  • GlassFish 3.1.2.2
  • "Backing bean" e.g. javax.enterprise.context.SessionScoped
  • "Stateless EJB services", e.g. javax.ejb.Stateless
  • "remote client"; i.e. some non-web clients invoking the Stateless beans directly (through EJB/RMI)

Update:

More detail on the "remote client". I'm not sure how to word this because I'm new to Java EE, but this "remote client" will not be over HTTP. Another application, let's call it application X, will receive XML messages from clients. I think they authenticate the client using certificates. Application X will transform the XML into POJOs and call my Stateless EJB services directly.

In this case, I think I'm right to say that I should not inject a SessionBean into a Stateless EJB service because there will be no HTTP session when the EJB service is called by Application X. Is my understanding correct?

Thank you for your patience. I am aware of my ignorance in these matters.


Answer:

You are not fully clear with your questions. Your question let me assume a lot. So you should break your questions down and provide more details to your issue. First of all you should mention which Java EE version you are using. Anyway here my details with some assumptions to your context.

Assuming you are talking about following Backing beans: http://docs.oracle.com/javaee/5/tutorial/doc/bnaqm.html

"Stateless beans" == Stateless session beans : http://docs.oracle.com/javaee/6/tutorial/doc/gipjg.html#gipin

SessionScoped beans : http://docs.oracle.com/javaee/6/tutorial/doc/gjbbk.html

"remote client interaction": http://docs.oracle.com/javaee/6/tutorial/doc/gipjf.html#girfl

In the case of the major question, you should keep in mind to separate the Http session from your Stateful session bean: Stateful Session Bean and HTTP Session

So if you try to couple Http Session with a Stateful session bean you have to provide the http session details into a area where both http session and stateful session bean can access the data and also hold a reference to it.

This assumes also, that your remote EJB service will not create a http session first. So you will not have a valid reference to a HTTP session via remote EJBs.

If you are using a HTTP based "remote client interaction", why are you not creating a http session on the first request?

HttpServletRequest.getSession(true)

will ensure what you will always get a valid session

If you are using some other HTTP bases frameworks like jax-rs there are also options to get a http session there.

Update 1

Can a SessionScoped bean be injected into a Stateless EJB knowing that the Statelesss EJB will be invoked by remote clients? What is the value of the SessionScoped bean in that case?

You can use the backing beans as POJOs in your EJBs, but not as http session scoped beans. If you need them from remote EJB you have to initialize them first, before using. Means, the have no value on remote EJB calls.

Instead of a SessionScoped bean, should my backing beans and Stateless EJB services be retrieving the Principal from the container?

Also here the question is not fully clear. You can configure your container (glassfish) to use have manual user, roles and realms. So this is your local mock for the Security and you can retrieve the Principal from the container. http://docs.oracle.com/javaee/6/tutorial/doc/bnbxj.html#bnbxs

Independently: I would recommend you to read the Oracle tutorial about Java EE. It is pretty good. Taking some dollars I would recommend Java EE 7 Essentials

Question:

I wonder what happens with the injected EJB-Proxy, when the SessionScoped CDI bean was passivated and then activated. Is there a null ref? Or is the EJB "reinjected"? Thanks for clarification.


Answer:

Section 6.6.3. (Passivation capable dependencies) of CDI spec states that the container guarantees Stateless beans are Passivation capable whether you declare your stateless bean serializable or not.

Section 6.6.5 of the specs states that an error occurs at deployment if a passivating scope ('@SessionScoped' for example) declares a dependency to a non-passivation capable dependency.

How the container handles the reactivation is implementation dependent. It can make the stateless bean serializable, or the proxy serializable and the reference to the bean, when the proxy is deserialized is updated.

Question:

I want to deploy my war archive on JBoss, but I got this error :

    11:26:08,539 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-8) MSC000001: Failed to start service jboss.deployment.unit."lab4-war.war".INSTALL: org.jboss.msc.service.StartException in service jboss.deployment.unit."lab4-war.war".INSTALL: JBAS018733: Failed to process phase INSTALL of deployment "lab4-war.war"
    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:166) [wildfly-server-8.2.0.Final.jar:8.2.0.Final]
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948) [jboss-msc-1.2.2.Final.jar:1.2.2.Final]
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881) [jboss-msc-1.2.2.Final.jar:1.2.2.Final]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_65]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_65]
    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_65]
Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: JBAS014544: No EJB found with interface of type 'pro.alexfly.lab4.dao.UserDAO' for binding pro.alexfly.lab4.controller.AdminPanelController/userDAO
    at org.jboss.as.ejb3.deployment.processors.EjbInjectionSource.getResourceValue(EjbInjectionSource.java:90)
    at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.addJndiBinding(ModuleJndiBindingProcessor.java:215)
    at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor$1.handle(ModuleJndiBindingProcessor.java:184)
    at org.jboss.as.ee.component.ClassDescriptionTraversal.run(ClassDescriptionTraversal.java:54)
    at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.processClassConfigurations(ModuleJndiBindingProcessor.java:152)
    at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.deploy(ModuleJndiBindingProcessor.java:145)
    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:159) [wildfly-server-8.2.0.Final.jar:8.2.0.Final]
    ... 5 more

I try to google it and fix it on the same error solutions in Internet, but I could not fix it. I get this error more and more.

My DAO interface :

/**
 * @Author is flystyle
 * Created on 05.06.16.
 */
public interface IRequestDAO {
    Integer createRequest(final Request source);
    List<Request> list(final Date date);
    List<Request> list();
    List<Request> list(final Station begin, final Station end);
    Request getRequestById (final int id);
    List<Request> getRequestsByUserId (final int userId);

    void removeRequestById(final int id);
    void removeRequestByUser(final User user);

    @Deprecated
    void removeAllRequests();

}

My UserDAO class :

@Stateless // look I have this annootation!
public class UserDAO implements IUserDAO {

    private SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

    public User verifyEnter(String name, String pass) {
        Session session = sessionFactory.openSession();
        Transaction tr = null;
        tr = session.beginTransaction();

        String sql = "SELECT * FROM rails_user WHERE user_name = :an AND user_pass = :ap";
        SQLQuery query = session.createSQLQuery(sql);
        query.addEntity(User.class);
        query.setParameter("an", name);
        query.setParameter("ap", pass);
        User res = (User) query.uniqueResult();
        tr.commit();
        session.close();
        return res;
    }

    public Admin adminEnter(String name, String pass) {
        Session session = sessionFactory.openSession();
        Transaction tr = null;
        tr = session.beginTransaction();

        String sql = "SELECT * FROM rails_admin WHERE admin_name = :an AND admin_pass = :ap";
        SQLQuery query = session.createSQLQuery(sql);
        query.addEntity(Admin.class);
        query.setParameter("an", name);
        query.setParameter("ap", pass);
        Admin res = (Admin) query.uniqueResult();
        tr.commit();
        session.close();
        return res;
    }

    public Integer register(String name, String surname, String pass) {
        Session session = sessionFactory.openSession();
        Transaction transaction = null;
        transaction = session.beginTransaction();
        User user = new User();
        user.setName(name);
        user.setSurname(surname);
        user.setPass(pass);
        Integer id = (Integer) session.save(user);
        transaction.commit();
        session.close();
        return id;
    }

    public List getAllUsers() {
        Session session = sessionFactory.openSession();
        Transaction tr = null;
        tr = session.beginTransaction();

        String sql = "SELECT * FROM rails_user";
        SQLQuery query = session.createSQLQuery(sql);
        query.addEntity(User.class);
        List res = query.list();
        tr.commit();
        session.close();
        return res;
    }

    public User getUserById(int id) {
        Session session = sessionFactory.openSession();
        Transaction tr = null;
        tr = session.beginTransaction();

        String sql = "SELECT * FROM rails_user WHERE user_id = :id";
        SQLQuery query = session.createSQLQuery(sql);
        query.addEntity(User.class);
        query.setParameter("id", id);
        User res = (User) query.uniqueResult();
        tr.commit();
        session.close();
        return res;
    }

    public void banUser(int id) {
        Session session = sessionFactory.openSession();
        SQLQuery q = session.createSQLQuery("DELETE FROM rails_user WHERE request_id = :id");
        q.addEntity(User.class);
        q.setParameter("id", id);
        q.executeUpdate();
    }

    public boolean verifyAdminEnter(String name, String pass) {
        Session session = sessionFactory.openSession();
        Transaction tr = null;
        tr = session.beginTransaction();

        String sql = "SELECT * FROM rails_admin WHERE admin_name = :an AND admin_pass = :ap";
        SQLQuery query = session.createSQLQuery(sql);
        query.addEntity(Admin.class);
        query.setParameter("an", name);
        query.setParameter("ap", pass);
        Admin res = (Admin) query.uniqueResult();
        tr.commit();
        session.close();
        if (res.getName().equals(name) && res.getPass().equals(pass))
            return true;
        return false;
    }

}

My Admin Controller class :

@ManagedBean(name = "rails_admin_panel")
@SessionScoped
public class AdminPanelController implements AdminAction{

    private List<User> allUsers;
    private List<Request> allRequests;

    @EJB
    private UserDAO userDAO = new UserDAO();
    @EJB
    private RequestDAO requestDAO = new RequestDAO();

    public void viewAllUsers() {
        allUsers = userDAO.getAllUsers();
    }

    public void viewAllRequests() {
        allRequests = requestDAO.list();
    }

    public void deleteRequest(int id) {
        requestDAO.removeRequestById(id);
    }

    public void deleteUser(int id) {
        userDAO.banUser(id);
    }

    public List<Request> getAllRequests() {
        return allRequests;
    }

    public List<User> getAllUsers() {
        return allUsers;
    }
}

Can you help me?

P.S. War Packaging


Answer:

During start app server cannot find interface pro.alexfly.lab4.dao.UserDAO because you have no one. To fix it:

  • Try to use you interface IUserDAO here:
@EJB
private UserDAO userDAO = new UserDAO();
  • Do not create your own instance manually, it should be injected by JBoss container.
  • Check that your interfaces have @Local annotation.

Question:

What happens if in the same session I instantiate more than one SessionScoped Bean or EJB (first time injected through the container and the second time created via "new")? Will it throw an Error? If not, which of them will be used during injection? The same also for AppllicationScoped and RequestScoped?!

P.S. Classes do not have any annotation do give them an explicit name.


Answer:

To have a truly managed bean, you let the CDI handle the lifecycle including the creation. There are exceptions, but let's not get into that now.

For your case, the object created via new will simply not be a managed bean and CDI will not know about it (unless it is a result of some producer method or such). You should figure out why is it created at all instead of just injecting the existing one?

The same also for AppllicationScoped and RequestScoped?!

For each injection point of a normal scoped bean, CDI will look into an underlying "bean store" and see if the bean you want was already created and stored there. If so, it just returns you that one (or, well, the proxy to it). If not, it will create a new one and store it there for future references.

So the short answer is, you won't have two instances of the same normal scoped bean created by CDI.

Question:

I have an ear which contains 2 war files and each war contains stateless ejb and jersey rest classes. The interfaces locate in commons.jar file. The EAR structure looks like this:

EAR
 -- /lib/commons.jar

 -- rest-1.war
      -- stateless-ejb-1.java
      -- jersey-rest-1.java

 -- rest-2.war
      -- stateless-ejb-2.java
      -- jersey-rest-2.java

I am trying to use stateless-ejb-1 from stateless-ejb-2 with @Inject annotation but I get a CDI deployment failure:WELD-001408: Unsatisfied dependencies error during deployment time. When I use @EJB in stateless-ejb-2 then the ear is deployed but I get a remote lookup error while calling jersey-rest-2.

This are my method call chains:

  • jersey-rest-1 > stateless-ejb-1: works fine
  • jersey-rest-2 > stateless-ejb-2 > stateless-ejb-1: I get an ejb-1 lookup error

I do not want to use remote ejb call because everything is packaged in the same ear (I would like to use @Inject instead of @EJB) but it does not work.

I guess that if I pack stateless-ejb-1.java to a jar and put it under EJB/lib than it will work. But I do not want to create a new module in my project just to pack this one file to separated jar file. What is the solution?


Answer:

You need to move stateless-ejb-1 into an ejb-jar module in the EAR.

Classes in different WAR files are never visible to each other, even when built into an EAR file.

Question:

I am trying to figure out how object instantiation works in Java EE. I have noticed that I get a NullPointerException if I try to access a member that is supposed to be injected through @EJB if the Class defining the member has been instantiated explicitly by me rather than the container. My conclusion is that even if a bean is marked to be managed it is not if one doesn't let the container instantiate it. Can we make the container manage such objects?

Let's say that we have the following setup, would it be possible to instantiate (explicitly) ClassB in ClassC and have ClassB invoke a method from ClassA without throwing a NullPointerException?

@Stateless
public class ClassA {
    public void bar() {
        // Does something fun
    }
}

@Stateless 
public class ClassB {
    @EJB
    private ClassA A;

    public void foo() {
        A.bar(); // throws NullPointerException if ClassB 
                 // is explicitly instantiated works fine
                 // if injected with @EJB
    }
}

public class ClassC {
  //@EJB // Only way to go? Can we choose an implementation of ClassB?
    private ClassB B;

    public ClassC() {
        this.B = new ClassB(); // Bad idea? Possible??
        this.B.foo(); 
    }
}

The reason I'm looking in to it is because I in my, equivalent of, ClassA need to use an EntityManager to persist some data, at the same time my ClassB is actually an interface so I need to be able to decide at runtime which implementation to instantiate in ClassC. Maybe there are other ways of doing this?


Answer:

I have noticed that I get a NullPointerException if I try to access a member that is supposed to be injected through @EJB if the Class defining the member has been instantiated explicitly by me rather than the container.

This is obvious as the dependencies are injected by the container. So if you are creating the instance and not setting any value for the dependency, then the dependency will be null. On the other hand, when instances are created by the container, it also sets the values of its dependencies.

My conclusion is that even if a bean is marked to be managed it is not if one doesn't let the container instantiate it.

Yes, that is correct. When you create the instance, the instance is therefore, not managed.

Let's say that we have the following setup, would it be possible to instantiate (explicitly) ClassB in ClassC and have ClassB invoke a method from ClassA without throwing a NullPointerException?

No, when you create the instance, the dependencies will be null.

The reason I'm looking into it is because I in my, equivalent of, ClassA need to use an EntityManager to persist some data, at the same time my ClassB is actually an interface so I need to be able to decide at runtime which implementation to instantiate in ClassC. Maybe there are other ways of doing this?

If you need to inject a specific implementation, the you can do that by specifying bean name.

@EJB(beanName="DefaultService")
private Service defautService;

@EJB(beanName="SpecificService")
private Service specificService;

Refer to this link: http://www.adam-bien.com/roller/abien/entry/injecting_different_implementations_into_an

Alternatively, if you're using CDI you can use @Qualifier

Question:

I am using wildfly 10.1.0 and JavaEE 7

I've got this interface:

public interface TestEjb {
    String something();
}

and this Ejb class implementing it:

@LocalBean
@Stateless
public class TestEjbImpl implements TestEjb {

    @Override
    public String something() {
        return "Hello world";
    }
}

When I am injecting it to my @Path annotated jax-rs class using

@Inject
private TestEjb testEjb;

It gives an error saying "WELD-001408: Unsatisfied dependencies for type TestEjb with qualifiers @Default"

But when I inject it like

@Inject
private TestEjbImpl testEjb;

it works fine. And which is surprising both ways work with no problems in jboss-eap-6.4. But why?


Answer:

First of all, you are mixing CDI injection with EJB injection. Rather use @EJB (instead of @Inject) when injecting your EJB.

@LocalBean has a no-interface view. So, you have an interface with no view annotation and a bean with a no-interface view annotation. The EJB Container understands it as a no interface view.

The best way will be to annotate the TestEjb interface with @Local view and remove the @LocalBean from the TestEjbImpl implementation in order for your solution to work.

Interface

@Local
public interface TestEjb {
    String something();
}

EJB

@Stateless
public class TestEjbImpl implements TestEjb {

    @Override
    public String something() {
        return "Hello world";
    }
}

Injection time

@EJB
private TestEjb testEjb;

I hope this helps.

Further reading...

Question:

I have an EAR application with three modules:

  • beans are in "app-ejb" module
  • remote interfaces are in "app-remote"
  • web services are in "app-war"
  • app-ejb and app-war use app-remote as library.

all are packaged in "app.ear".

This is working fine, but now I have to use the same beans outside the EAR application, and injection is not working.

I have in app-ejb:

@Stateless
@LocalBean
public class Services implements ServicesRemote {
  [...]
}

and his remote interface in app-remote:

@Remote
public interface ServicesRemote {
  [...]
}

In my app-war I can inject the remote bean without problem:

@Stateless
@LocalBean
public class UseServices {
  @EJB
  private ServicesRemote services;
  [...]
}

Anyway in my external ejb application, deployed as stand-alone and using the same ejb-remote as library, if I try to inject the same EJB like this:

@Stateless
@LocalBean
public class UseServicesFromAnotherApp {
  @EJB
  private ServicesRemote services;
  [...]
}

Glassfish (4.1) give me an error "Class [ Lcom/[...]/ServicesRemote; ] not found".

Is this expected? How can I inject the remote bean correctly?


Answer:

Injection doesn't work with remote interfaces. Beans that are "injectable", live inside container's JVM and are available for injection to other beans inside the same application. The same holds true for accessing beans in another application in the same container, although applications may live in the same JVM. Since remote methods are originated from another JVM or another application, injection is not possible. You must use JNDI lookup instead to get a reference to a remote bean.

As a matter or personal taste, I would stay away from EJB Remote interfaces, and instead I would use another "remoting" technique such as REST.

Question:

Is it possible to inject an EJB into any class? And who performs the injection - EJB container or the container of the classes that contain EJB annotation?


Answer:

Here is an extract from Java EE Tutorial:

Dependency injection is the simplest way of obtaining an enterprise bean reference. Clients that run within a Java EE server-managed environment, JavaServer Faces web applications, JAX-RS web services, other enterprise beans, or Java EE application clients, support dependency injection using the javax.ejb.EJB annotation.

Applications that run outside a Java EE server-managed environment, such as Java SE applications, must perform an explicit lookup. JNDI supports a global syntax for identifying Java EE components to simplify this explicit lookup.

Question:

I have a workflow class where I'm injecting several EJB's at the top of my class using the @EJB tag:

@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class WorkflowBean {

   @EJB
   private BeanOne beanOne;
   @EJB
   private BeanTwo beanTwo;
   @EJB
   private BeanThree beanThree;
   @EJB
   private BeanFour beanFour;
   @EJB
   private BeanFive beanFive;
   @EJB
   private BeanSix beanSix;

Is there a better, more organized way of injecting these at the top of my code, maybe on one line somehow? The code works perfectly fine, but I think I am going to add a few more beans by the time the code is complete and I feel that it is starting to cause my code to look cluttered.


Answer:

There's nothing inherently wrong with doing it that way, but it can get a bit cluttered.

If you could identify and group together behaviors based on business behavior, it might reduce the number of @EJB annotations. For instance, if beanOne, beanTwo, and beanThree all relate to user management, you could create a userManagement bean, inject them there, and then only inject the one userManagement bean in your workflow bean. It also might help with self-documentation a bit as well.

IMHO, your workflow bean should pretty much just be calling other beans that encapsulate the business logic, instead of trying to define it all here.

Question:

I want to get the reference to some Stateless bean inside my code. The problem is I only know the Interface it is implementing (i do not know the name, classname or any other).

Normally for any other EJB i would use @EJB annotation with an Interface

private @EJB MyInt myInt;

Do anyone know if it is possible to get it via code like for ex:

MyInt myInt = new InitialContext().lookuup(MyInt.class);

?


Answer:

Unfortunately, in the case where you have multiple implementations for the same interface, you need to specify which implementation you want. Thus, you will need the implementation's mapped name or you will need the JNDI name in order to look it up like that. Your Application Server administrator should be able to provide the JNDI name for you.

If you are going to want to swap out implementations at runtime then you cannot use injection. You will have to do a JNDI lookup. We built a little factory to lookup a stateless session bean by getting the JNDI name from a configuration table in our database. This enables you to swap out implementations by changing the JNDI name in the database table. Here is an example of our bean lookup method:

public static Object getBean(String jndiName) throws NamingException {
    Object bean = null;
    Context ctx = new InitialContext();
    bean = ctx.lookup(jndiName);
    return bean;
}   

I hope this helps. :)

Question:

I've got a Factory class in Java with some methods which return some Java Bean. All of these Java Beans have some DAO object as fields which are injected with the annotation @EJB. However in every case these DAO are all Null, so I suppose I've a problem with EJB injection. I use WebLogic for deploy. Any suggestions to resolve the issue?

//Factory class
public class Factory extends AbstractFactory {

    @Override
    public InterfaceService getService() {
        return new ClassBean();
    }
}

//Bean class
@Stateless(mappedName = "ClassBean")
@LocalBean
public class ClassBean implements IBeanService {

    @EJB(beanName = "ClassDAO")
    private ClassDAO classDAO;


    public List<String> getList() throws ExpectedModelException {
        return classDAO.getStringList(); //this one throws NullPointerException
}

Answer:

Never create Enterprise-Beans using new. The creation, caching, deletion,... is done by the container.

You must declare ClassDao as @Stateless or @Singleton, ... and the container will create and find it, hopefully if the names are correct. The Factory is not necessary.

Question:

Problem: I had some unexpected behaviour when injecting a Bean(In a filter) with 2 subclasses which I injected in two other classes (Servlets). Now the injected superclass could hold a reference to a subclass instance at runtime (changeing with each container restart).

I must have made a serious mistake but I can't quite figure out what exactly.

Additional information:

I use Java EE6

Class structure:

In the filter I inject the super class which holds a random instance to one of the subclasses or the superclass:

@EJB
private ClientLogger clientLogger;

The super class been starts like this:

@Stateless
@LocalBean
public class ClientLogger implements HcpEntityBeanLogger<Client> {

private Client client;

public ClientLogger(){
}

....

}

This subclass bean I inject in one of my Servlets:

@Stateless
@LocalBean
public class AdminClientLogger extends ClientLogger {

public AdminClientLogger(){
}
...
}

Solution attempt:

So as far as I understand the subclass which gets last injected will be the instance referenced by clientLogger, but why, why can't I have 3 different instances and use inheritance here?

Edit: I faced this problem again when injecting multiple query beans which all implement the same interface, all of them would hold a reference to the same instance.

The solution was to add beanName wenn injecting the interface with EJB

@EJB(beanName="name of your bean class or name specified in @Stateless(name=".."))

Answer:

You can use the lookup attribute on the @EJB annotation and get the required subclass injected. E.g.

     @EJB(lookup="java:global/rest/AdminClientLogger")
      private ClientLogger clientLogger;

Obviously you would have to change the JNDI lookup path in the example above.

Question:

I have to create project with interface(IGraphRemote), sessionbean(Graph) and client class(AppClient)

I tried to prepare simple project with one method register(int hwork, String album) - hwork its my homework's number, album its my album's number, but it doesn't work and returns an error: java.lang.NullPointerException , so connection wasn't established. How can i fix that ?

My files: IGraphRemote

public interface IGraphRemote {
    public boolean register(int hwork, String album);

}

Graph

@Remote
public class Graph implements IGraphRemote{
   public boolean register(int hwork, String album) {      
       return (hwork == 6
                && album.equals("119962"));
    }  
}

And AppClient

public class AppClient {

    @EJB
    private static IGraphRemote gremote;

    public static void main(String[] args) {

        AppClient ap = new AppClient();             
        System.out.println(ap.gremote.register(6, "119962"));
    }
}

here are my project

Error:

Exception in thread "main" java.lang.NullPointerException
    at AppClient.main(AppClient.java:22)
Java Result: 1

Answer:

It's obvious from your code and also in the stack trace that you try to run a standard j2se application with a main method from within a web application, so how do you expect dependcy injection to happen unless there is some other code create the ejb instance and inject it in the ejb reference. EJB is a J2EE component and it can't be created in standard java application, you need an ejb container with a naming service to manage the EJB lifecycle. You can create a standard j2se client by connecting to the naming service and lookup for the bean, but your EJB MUST be deployed in an ejb container in the first place such as TomEE, Glassfish, websphere,..etc

Question:

Let's say the class MyCoolProcess has the logic of my app which is needed to be called in it's own thread. We'll create a thread, call it and continue with the application. This class is a EJB; annotated with @Stateless

Now we have the MyController class; which is going to call a new thread.

Code:

public class MyController {

  @EJB
  MyCoolProcess p;

  public Response foo() {
    Thread t = new Thread() {
      public void run() {
        p.run();
      }
    };
    t.start();
    // continues ...
  }

 }

@Stateless
public class MyCoolProcess {

  public void run() {
    // heavy task
  }
}

That is working fine; the point is... before that solution I've tried with the Runnable interface. Which was I wanted at first time. The approach would be:

public class MyController {

  @EJB
  MyCoolProcess p;

  public Response foo() {
    Thread t = new Thread(p);
    t.start();
    // continues ...
  }

 }

@Stateless
public class MyCoolProcess implements Runnable {

  @Override
  public void run() {
    // heavy task
  }
}

That doesn't work. Actually, the server cannot start. Crashes trying to inject the dependencies. I'm not be able to implement the interface Runnable if I'm a EJB isn't it? WHY

And... is there any way to do the Runnable way instead the anonymous class?


Answer:

From the EJB spec:

The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt to start, stop, suspend, or resume a thread, or to change a thread’s priority or name. The enterprise bean must not attempt to manage thread groups.

See Adam's Blog.

Question:

I am trying to use a stateful ejb from a servlet, but from what I understood I shouldn't use @EJB injection to do that, and do a lookup instead.

The problem is, so far the only way I managed to achieve this is by using this anotation on the servlet:

@EJB(name="LoginRemote", beanInterface = LoginRemote.class)
LoginRemote loginHandler;

then the lookup:

loginHandler = (LoginRemote) new InitialContext().lookup("java:comp/env/LoginRemote");

Otherwise I always get a javax.servlet.ServletException: javax.naming.NameNotFoundException error.

Is this acceptable or should I avoid the @EJB injection completely?

Thanks


Answer:

No, you don't want to inject an instance into the servlet. Instead, you can use the @EJB annotation on the servlet class itself to declare a reference without injecting:

@EJB(name="LoginRemote", beanInterface = LoginRemote.class)
public class MyServlet {

You can use @EJBs if you want to declare multiple references in the same servlet.

(Note that when using the annotation on a field as in your example, the beanInterface parameter is redundant with the field type, but it is required when using the class-level annotation class.)

Question:

I have two application deployed on glassfish - application A and B.

Both are deployed as war package, application B uses some components from application A.

Now in application A I have an interface:

public interface BusinessInterface() extends SomeOtherInterface {
    void someAction();
}

I have 3 implementations of this interface - two in application A, one in application B: BusinessInterfaceA1, BusinessInterfaceA2, BusinessInterfaceB

As long as all of them are CDIBeans, everything is fine - I'm using custom @Qualifier annotations (@BusinessInterfaceA1, @BusinessInterfaceA2) and @Default annotation for B's implementation to distinguish them.

But now I need both application's A implementations to be Stateful EJBs and this is where it becomes funny.

When I just add @Statefull annotation on both implementations, a I got something like this:

javax.servlet.ServletException: org.jboss.weld.exceptions.WeldException: WELD-000049

details:

java.lang.IllegalStateException: Unable to convert ejbRef for ejb BusinessInterfaceA1 to a business object of type interface SomeOtherInterface

How can I fix it? I need all implementations to be avaliable in a way I could inject them like

@Inject @SomeAnnotation private BusinessInterface businessInterface;

Answer:

It is bug in Glassfish 3.1. The workaround is, to mark implementation with all required interfaces, e.g.:

@Statefull/@Stateless
public class BusinessInterfaceImpl implements BusinessInterface, SomeOtherInterface {
   // implementation
}

Even BusinessInterface extends SomeOtherInterface, and from Java specs its useless to do that, but as a workaround for that bug it works.

Another solution is to use Glassfish 4.0

Question:

I got Java EE project. In the ejb module I have this class

@LocalBean
@Stateless
public class TestBean implements Test{

@PersistenceContext(unitName = "-----")
EntityManager em = null;

public Manager findByName(String name) {
    Manager manager = em.createNamedQuery("Manager.findByName", Manager.class).
            setParameter("name", name).getSingleResult();

    return manager;
}

}

In web module I have this class:

public abstract class BaseActionBean implements ActionBean  {

private MyActionBeanContext context;

@EJB
public TestBean wrapper;


public MyActionBeanContext getContext() {
    return context;
}

public void setContext(ActionBeanContext context) {
    this.context = (MyActionBeanContext) context;
}
}

In web.xml file I have this:

<init-param> 
        <param-name>Extension.Packages</param-name> 
        <param-value>
           com.samaxes.stripes.inject
        </param-value>
    </init-param>

But when I want to use this wrapper I got 'null'. stipes version 1.5.7 stripes-injection-enricher-1.0.3(this libraries added to web module) How can I inject to my EJB module? please help


Answer:

I included stripes jar in ejb module and then wrote mappedName to ejb class

@EJB(mappedName = "java:global/project-name/project-name-ejb/TestBean")
public TestBean testBean;

Now it works

Question:

I'm using Domain-Driven Design (I think!) and I have a requirement to access some global properties. I have my @Singleton thus:

@Singleton
public class MyProperties {
    private Properties props;

    @PostConstruct
    private void initialize()
    {
        try {
            props.load(new FileInputStream("my.properties"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public String getProperty(String propertyName)
    {
        return props.getProperty(propertyName);
    }
}

I would like to do this:

@Entity(name="MYENTITY")
public class MyEntity {
    @Inject private MyProperties props;
    void doSomething()
    {
        String myProp = props.getProperty("my-prop");
        // ...etc...
    }
}

However, this doesn't work - props is null, and anyway sites tell me not to do that, and I should use a Service Locator instead, but that all smells of using JNDI lookup which EJB 3.x kills off.

My plan might be to try this sort of thing:

@WebListener
public class MyServletContextListener implements ServletContextListener{
    @Inject private MyProperties props;
    private MyServletContextListener theInstance;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        theInstance = this;
    }

    static public MyServletContextListener theInstance() { return theInstance; }
    public MyProperties getProperties() { return props; }
}

Does this make sense, or am I barking up the wrong tree, or do I just have some silly bug in my code?

EDIT: Note that I am using vanilla Java EE with CDI, JPA, etc, no Spring.

EDIT2: I see that CDI Best Practises say one should add the @Vetoed annotation to all persistent entities. Currently my application flow control is from a @MessageBean through a series of @Entitys - is this a design smell?


Answer:

First, any your entities are NOT in spring application context, so, any beans of spring can not inject into your entities! Second, If you really want to do this, please add:

<context:spring-configured />

into your spring configuration, then add @Configurable at the MyEntity class!

Question:

I have an EJB application that consists of two beans, ServiceEJB (web tier) and BusinessEJB (business tier), where BusinessEJBis injected in ServiceEJB.

ServiceEJBreceives HTTP requests from the browser, calls a method in BusinessEJB, gets the result, and sends the HTTP response.

Also, ServiceEJB has access to the HttpSession object, where the userId of the user that logged in is stored. BusinessEJBdoes NOT have access to the HttpSession object.

The application needs to log messages (using sl4j/logback, for example). It could log the message in ServiceEJBor BusinessEJB methods, and when it logs a message, it has to include the userId of the session in the log entry.

Since BusinessEJB doesn't have the userId, it needs to get it from ServiceEJB. The question is what is the best way to achieve that. What I DON'T want to do is to add a userId field to each method in BusinessEJB as a parameter, as there are many ServiceEJBs and BusinessEJBs in the application (and other beans called by BusinessEJB that also generate log entries), and I don't want to pollute the application with the userId field. Instead, I could have a userId field at the EJB level, but how to populate them? Is there a way to achieve this with annotations? Any suggestions will be welcome.

@Produces({MediaType.APPLICATION_JSON})
@Consumes({MediaType.APPLICATION_JSON})
@Stateless
public class ServiceEJB {

    @Context
    HttpServletRequest httpRequest;

    @Inject
    private BusinessEJB bean;

    private String userId;

    @Path("someurl")
    public Response someMethod1() {
       final HttpSession session = httpRequest.getSession();
       // get the userId from the session

       String s = bean.someMethod2();

       // return Response
    }
}

@Stateless
public class BusinessEJB {

  private String userId;

  public String someMethod2() {
     // ....  log an entry with userId
     return "something";
  }   
}

Answer:

A few pointers/comments:

  1. If you integrate with application server security, then the user name is available at any component. EJBs can get it by calling getCallerPrincipal() on the injected variant of the EJBContext, here the javax.ejb.SessionContext:

    @Resource
    private SessionContext sessionCtx;
    

    Servlets can retrieve the principal from the HttpServletRequest.getUserPrincipal(). JAX-RS components (the ServiceEJB) can retrieve it from the javax.ws.rs.core.SecurityContext.getUserPrincipal().

    Is there any reason why you are NOT integrating with the application server security?

  2. If you have a good reason NOT to integrate with application server security, I would propose a variation of the solution from the previous answer. The variation is to set the user data from a filter applied to all resources (either servlet filter or JAX-RS ContainerRequestFilter), so that you do not have to worry about setting it in multiple places.

  3. If you ONLY NEED THE USER ID FOR LOGGING, I'd suggest you take a look at the concept of Mapped Diagnostic Contexts (MDC) in slf4j. With it you can set the user id early at the beginning of the request and make it available to all logging statements thereafter.

Question:

I have read many posts both online and SO, but I am still not clear on to which annotation to use for injecting an EJB.

Can anyone please guide when to use which annotation for injecting an EJB (and possibly pros and cons):

1) @EJB 2) @Resource 3) @Inject

This might be a basic question, I did look for answers, but I am not still clear on this.


Answer:

I have never seen anywhere that you could use @Resource for injecting an EJB. It might work in some servers but it is unlikely to be portable.

The question of @EJB vs @Inject is more complicated.

CDI and @Inject were added to the Java EE 6 Specification. There it was possible to @Inject EJBs into a CDI bean, but not in too many other (if any) places.

The Java EE 7 Specification unified this substantially to the point where you can use @Inject or @EJB interchangeably in most (if not all) places. In essence all of the "sub" specifications such as the EJB spec itself, the servlet spec, JAX-WS, JAX-RS, etc had to be updated to support the use of @Inject as well as @EJB. However if you need to specify any of the attributes available on the @EJB annotation then these are not available on @Inject.

Therefore, feel free to use @Inject anywhere if you're running in a Java EE 7 compliant environment and you don't have a need for any of the @EJB attributes, otherwise use @EJB.

Question:

Having multiple implementations of a @Local Interface:

@Local
public interface LocalInterface {
}

@Stateless
public class FirstLocalImpl implements LocalInterface {
}

@Stateless
public class SecondLocalImpl implements LocalInterface {
}

and an @EJB Injection in a third bean:

public class Foo {
   @EJB
   LocalInterface local;
}

Which implementation is chosen to be injected into Foo::local and how is the order defined? Note that no ejb-jar.xml is specified.


Answer:

You will get a detailed error at deployment time, telling you that there are two implementations of the same interface. To solve this you have to specify the bean name:

@EJB(beanName="FirstLocalImpl")
LocalInterface local;

Question:

I would like to save the data of an injected stateful bean at various intervals: change - save - change- save... I'm using core serialization and the problem is that all the byte arrays are the same. i believe the proxy is serialized because if I deserialize one of the arrays later I get the current state of the bean.

Example of serialization not capturing changes in the bean:

@Stateful
@RequestScoped
public class State implements Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    StatelessBean bean; // assume it's needed

    private List<String> list = new ArrayList<>();

    public void add() {
        list.add("S");
    }
}

And this is a JAX-RS class:

@Stateless
@Path("t1")
public class ChickensResource {

    @Inject
    State state;

    @GET
    @Path("/test")
    public String test() {
        state.add();
        byte[] b0 = serialize(state);
        System.out.println(b0.length + " " + Arrays.toString(b0));
        state.add();
        byte[] b1 = serialize(state);
        System.out.println(b1.length + " " + Arrays.toString(b1)); // prints same as b0
        System.out.println(b0.length + " " + Arrays.toString(b0)); // prints same thing
    }

    public static <T extends Serializable> byte[] serialize(T s) {
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
             ObjectOutputStream oos = new ObjectOutputStream(bos))
        {
            oos.writeObject(s);
            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

What I want to do is only save the list in State as that's the relevant data. I also tried JSON serialization and it gave an IOException, but I'm trying core serialization.

Using JavaEE7 and Wildfly 10.1.


Answer:

For various reasons, serializing a CDI bean directly is dangerous:

  • You may have a proxy, not the actual object; same holds true for the dependencies of that object
  • Serialization implies that the data will be deserialized at a time. But CDI beans are managed by CDI and CDI has no way to "attach" a deserialized object into its set of managed objects.

But the purpose of this question is to somehow save the state of a CDI bean in a way that it can be restored later. This can be accomplished by using another object that holds the state of the CDI bean. This other object is not managed by CDI, i.e. created with new, and is serializable. Each CDI bean that needs to persist its state has the pair of setState(state)/getState() methods - they could even be part of an interface. You probably want each object to propagate setState(state)/getState() to its collaborators too.

See the Memento design pattern. This is also implemented in the JSF state saving/restoring mechanism, if you are familiar with it.


Some example code (there are other valid ways to do it), starting with the state interface:

interface HasState<S extends Serializable> {
    S getState();
    void setState(S state);
}

Then the service itself, that has a collaborator, and the relevant state object:

class SomeServiceState implements Serializable {
    private String someData;
    private Long someId;
    private List<String> list;
    private CollaboratorState collaboratorState;
    // accessors
}

@RequestScoped
public class SomeService implements HasState<SomeServiceState> {

    // COLLABORATORS
    @Inject
    Collaborator collaborator; // assume it's needed

    // INTERNAL STATE
    private String someData;
    private Long someId;
    private List<String> list = new ArrayList<>();

    public void add() {
        list.add("S");
    }

    // ...

    public SomeServiceState getState() {
        SomeServiceState state = new SomeServiceState();
        state.setSomeData(someData);
        state.setSomeId(someId);
        state.setList(new ArrayList<>(list)); // IT IS PROBABLY SAFER TO COPY STATE!
        // SEE HOW STATE GETS EXTRACTED RECURSIVELY:
        state.setCollaboratorState(collaborator.getState());
        return state;
    }

    public void setState(SomeServiceState state) {
        someData = state.getSomeData();
        someId = state.getSomeId();
        list = new ArrayList<>(state.getList());
        // SEE HOW STATE GETS APPLIED RECURSIVELY:
        collaborator.setState(state.getCollaboratorState());
    }
}

The collaborator and its state follow the same pattern:

class CollaboratorState implements Serializable {
    private String anyName;
    // accessors
}

@RequestScoped
class Collaborator implements HasState<CollaboratorState> {
    // you get the point...
}

And an example usage, following the code from the question:

@Stateless
@Path("t1")
public class ChickensResource {

    @Inject
    SomeService someService;

    @GET
    @Path("/test")
    public String test() {
        someService.add();
        byte[] b0 = serialize(someService.getState());
        // ...
    }

    public static <T extends Serializable> byte[] serialize(T s) {
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
             ObjectOutputStream oos = new ObjectOutputStream(bos))
        {
            oos.writeObject(s);
            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

EDIT: If the client of a service needs to know that a service has state, then the client and service might be more coupled than it would be desired. A way out is to modify HasState to deal with opaque objects:

interface HasState {
    Object getState();
    void setState(Object state);
}

The state of the client contains a list for the state of each collaborator:

class SomeServiceState implements Serializable {
    private String someData;
    private Long someId;
    private List<String> list;
    private List<Object> collaboratorsState;
    // accessors
}

The client adds a collaborator to the state only if it extends HasState:

    public Object getState() {
        SomeServiceState state = new SomeServiceState();
        state.setSomeData(someData);
        state.setSomeId(someId);
        state.setList(new ArrayList<>(list));
        if( collaborator instanceof HasState ) {
            state.getCollaboratorsState().add(collaborator.getState());
        }
        return state;
    }

Question:

I have a JavaEE application with Stateless EJBs that I use for business logic (EjbBusiness) and database access (EjbDAO). I need to run a unit test on EjbBusiness, but the DAO method always returns zero.

In the example below I have both classes and the unit test. I mock the EjbDAO method that connects to the database, to return a testing SQL connection:

@Stateless
public class EjbDAO {


    public Connection getConnFromPool() {
        Connection conn = null; // in production this would return a connection
        return conn;
    }


    public int add2(int i) {
        Connection conn = getConnFromPool();
        System.out.println("in EjbDAO: " + i);
        return i + 2;
    }

}


@Stateless
public class EjbBusiness {


    @Inject
    private EjbDAO dao;


    public int add2(int i) {
         int j = dao.add2(i);
         System.out.println("in EjbBusiness: " + j);
         return j;

    }

}

Since I mock one of the methods of EjbDAO, I annotate it with @Spy in UnitTest:

@RunWith(MockitoJUnitRunner.class)
public class UnitTest {

    @InjectMocks
    private EjbBusiness biz;

    @InjectMocks
    @Spy
    private EjbDAO dao;

    @Before
    public void setup() {
        dao = Mockito.mock(EjbDAO.class);
        biz = Mockito.mock(EjbBusiness.class);
        MockitoAnnotations.initMocks(this);
    }


    @Test
    public void testBean() {

        // this would return the testing connection
        Mockito.doReturn(null).when(dao).getConnFromPool();

        int i = biz.add2(3);

        assertThat(5).isEqualTo(i);
    }
}

Problem is that the assertion doesn't work, as biz.add2(3) returns zero instead of 5. Also, the System.out.println in both beans is not printed. How to declare/mock the beans for the test to work?


Answer:

Use @InjectMocks only when you calling actual method otherwise don't use it. And also don't use @InjectMocks and Mockito.mock() or @Mock together.

In your code you are using @InjectMocks on dao object and you are also creatign mock for that. And use Mockito.mock() when you want to stub the method calls instead of calling actual methods.

System.out.println() is not working in your code because you created mocks for objects biz and dao. Actual methods (i.e add2() because of this you are getting 0 as output) not executed when you call with mock objects.

For more info on when to use @InjectMocks refer this

@RunWith(MockitoJUnitRunner.class)
public class UnitTest {

    @InjectMocks
    private EjbBusiness biz;

    @Mock
    private EjbDAO dao;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    }


    @Test
    public void testBean() {

        // this would return the testing connection
        Mockito.doReturn(null).when(dao).getConnFromPool();
        Mockito.doCallRealMethod().when(dao).add2(Mockito.anyInt());

        int i = biz.add2(3);

        assertThat(i).isEqualTo(5);
    }
}

Question:

In our application we have CDI (@ApplicationScoped annotation) and EJB (@Stateless annotaion) beans that structured like this:

MyInterface
    MyAbstractClass
       MyBean (CDI or EJB)

I'm using below to get all the beans (CDI and EJB) in my application that implements MyInterface:

@Inject
Instance<MyIterface> beans;

Here I see two weird things:

  • I'm getting only CDI beans and not EJB beans.
  • When creating EJB bean that implements directly the MyInterface interface, without extending MyAbstractClass, than in this case this bean getting injected by the inject above.

How can I get all the beans, CDI and EJB, with the inject above?


Answer:

Quote from section 4.9.2.1 of EJB 3.2 specification:

@Stateless
public class A implements Foo { ... }

@Stateless
public class B extends A implements Bar { ... }

Assuming Foo and Bar are local business interfaces and there is no associated deployment descriptor, session bean A exposes local business interface Foo and session bean B exposes local business interface Bar, but not Foo.

Session bean B would need to explicitly include Foo in its set of exposed views for that interface to apply. For example:

@Stateless
public class A implements Foo { ... }

@Stateless
public class B extends A implements Foo, Bar { ... }

In your example, MyBean defined as EJB does not expose MyInterface, and, as a result, is not injected at Instance<MyInterface>.

There are two ways to handle it:

  • declare EJBs as implementing MyInterface;
  • annotate EJBs with @Local(MyInterface.class)

Warning for the approach with @Local - this EJB will satisfy only those injection points which use one of the interfaces provided as a parameter to the annotation. You won't be able to inject it at

@Inject
MyBean bean;

Also, you won't be able to cast the injected proxy to any other type.

Question:

This test works:

@RunWith(MockitoJUnitRunner.class)
public class Test1 {

    @InjectMocks private MyBean bean;       

    @Test
    public void shouldWork() {      
        bean.test("ABC");       
    }
}

@Stateless
public class MyBean {

    public String test(String s) {
        System.out.println("This is a test " + s);
        return s;
    }
}

Now, I want to inject a new EJB MyBean2 in MyBean and retest. To do that, I mock MyBean2 in Test1 as well. This is the new test:

@RunWith(MockitoJUnitRunner.class)
public class Test1 {

    @Mock MyBean2 bean2;        
    @InjectMocks MyBean bean;       

    @Test
    public void shouldWork() {
         bean.test("ABC");      
    }

}


@Stateless
public class MyBean {

    @Inject
    MyBean2 bean2;

    public String test(String s) {
        return s + bean2.test2();
    }
}


@Stateless
public class MyBean2 {
    public String test2() {
        return "DEF";
    }
}

But when I run this I get NullPointerException when bean tries to invoke the bean2 method, probably because Mockito is not recognizing the injected bean as EJB.

How to make this work?


Answer:

Take a look into the Javadoc of @InjectMocks. It states that you have to call an init of the mocks in use by calling in your case:

@RunWith(MockitoJUnitRunner.class)
public class Test1 {
    @InjectMocks
    MyBean bean;
    @Mock
    MyBean2 bean2;

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void shouldWork() {
        when(bean2.test2()).thenReturn("mocked return");
        assertThat(bean.test("ABC")).isEqualTo("ABCmocked return");
    }
}

Question:

I am working on a project where I have separated EJB such that they only carry out the business logic but not performing the queries. Then I also have the DAOs that performs the queries. For me to use the DAOs, I inject the DAOs in the EJB and with a method annotated @PostConstruct, I set the EntityManager in the DAO with the EntityManager injected in the bean like bellow:

public class ClazzDao implements ClazzDaoI{

  private EntityManager em;

  public void setEm(EntityManager em){
     this.em = em;
  }

  public List<Entity> list(){
      return em.createQuery("FROM Entity e").getResultList();
  }

}

And the EJB

@Stateless    
public class ClazzBean implements ClazzBeanI{
  @PersistenceContext
  private EntityManager em;

  @Inject
  private ClazzDaoI clazzDao;

  @PostConstruct
  private void init(){
    clazzDao.setEm(em);
  }

  public BigDecimal sendEmailToMembers(){

     List<Entity> members = clazzDao.list();
     //do some stuff with data like say send emails...

  }

}

Is there a way that I can make the DAOs use the entity manager injected in the EJB without setting it at the @PostConstruct of the EJB?


Answer:

You can use inject capability only in container managed beans. You dao class is outside of container management no way to inject the EntityManager into this object. Put you class into container management (EJB/CDI) if you need injection capability. By the way avoid to use unnecessary interfaces use non interface view instead.

Question:

I'm a newbie to EJB. I want to know is can inject EJB in method of other bean session, if not why? as code below:

@Local
interface car {
    public void drive();
}

@Stateless
public class Toyota implements Car {
   @Override
   public void drive() {
       @EJB 
       Color color;
       ...
   }
}

The code example is welcome.


Answer:

No, you cant inject into method. You may only use @EJB at class level, field or setter like this:

@Stateless
@EJB(name="myBeanRef", beanInterface=MyBean.class)   // this creates only reference - you will need to initialize it for example via initialConetxt.lookup()
public class EJBTests{
    @EJB (name="ejb/bean1")  // this injects bean named ejb/bean1
    MyBean1 bean1;

    MyBean2 bean2;

    ....
    @EJB (name="ejb/bean2")   // this injects bean using setter method
    public void setEcho(MyBean2 bean2) {
       this.bean2 = bean2;
    }
}

For more details check 7.1 @EJB – injecting an EJB from the EJB 3.1 specification.

Question:

I am trying to inject an object in my EJB like this:

@Stateless
@Path("/auth")
public class Login {

@Inject
UsernamePasswordCredentials credentials;

The problem is the UsernamePasswordCredentials has a child class and both classes have the same qualifiers which causes an ambiguous dependencies. How do I specify that I want to inject an instance of the parent class and not the child class? Error message looks like this:

Ambiguous dependencies for type UsernamePasswordCredentials with qualifiers @Default

Managed Bean [class org.picketlink.idm.credential.UsernamePasswordCredentials] with qualifiers [@Any @Default],

Managed Bean [class org.picketlink.idm.credential.TOTPCredentials] with qualifiers [@Any @Default]


Answer:

You could use the programmatic lookup mechanism to restrict the actual type of the needed bean:

@Inject
Instance<UsernamePasswordCredentials> credInst;

public UserNamePasswordCredentials getCredentials() {
  return credInst.select(UsernamePasswordCredentials.class).get();
}

Beyond that, I'm not a Picket Link expert, but I think you are doing something wrong with the framework. Picket Link CDI integration was very well crafted so I'm a bit puzzled you could encounter such an issue in a standard usage.

Question:

I am newbie with EJB and Injections...

I am currently using Vaadin framework with CDI

I have been trying to using injection but i have not could do it...

In my Vaadin UI class MyVaadinUI i have tried...

CDIUI("")
@SuppressWarnings("serial")
public class MyVaadinUI extends UI {


@EJB
UserController userController;

@Override
protected void init(VaadinRequest request) {

  System.err.println("desde controller "+userController.getAll().size());

}

}

UserController

@Stateless
public class UserController {

    @EJB
    IUserDAO userDao;

   public List<User> getAll() {

        return userDao.findAll();
    }


}

and it works!!

but when I do not inject UserController, it does not work... In other words when I instance the class UserController the injection in this class does not work...

Code does not work

     CDIUI("")
    @SuppressWarnings("serial")
    public class MyVaadinUI extends UI {


    @Override
    protected void init(VaadinRequest request) {
           UserController userController = new UserController();
      System.err.println("desde controller "+userController.getAll().size());

    }

}

Somebody can explain me why?

Thanks

Nicolas


Answer:

Only in injected objects will have its dependencies injected. If you create an object with new all field having @inject, @ejb or @resource will not be injected. In your case you create UserController like this:

UserController userController = new UserController();

and so this field will not be injected:

@EJB
IUserDAO userDao;

And therefore getAll() will throw a NullPointerException.

I use vaadin and cdi for projects. I'd recommend to use injection for almost everything or not at all. I inject my uis, views, own components... (and do not create them with new) so it is possible to inject ejb beans or other things into them. If you are using it only sometimes you are ending up with am mixture of injection and normal object creation and will have to pass around injected objects to other object you instantiated yourself. In another project of mine this happened and got really problematic for future changed in the code.

Question:

How do I actually instantiate the JPA controller below?

I'm fuzzy on how a Netbeans created JPA controller is actually used. I certainly appreciate the Netbeans wizard in this case, it's interesting -- I'm trying to understand how it works and why it works this way.

The ejb module can just inject from Glassfish along these lines:

@PersistenceUnit(unitName="JSFPU") //inject from your application server
EntityManagerFactory emf;
@Resource //inject from your application server
UserTransaction utx; 

and then, to instantiate the controller, something like this:

    PersonEntityJpaController pejc = new PersonEntityJpaController(utx, emf); //create an instance of your jpa controller and pass in the injected emf and utx
    try {
        pejc.create(pe); //persist the entity 

Where can I find more information about how to inject the PU from, in this case, Glassfish, as well as how @Resource works? I don't at all mind reading Glassfish for JavaEE docs from Oracle, or other reference material.

The controller Netbeans generated:

package db;

import db.exceptions.NonexistentEntityException;
import db.exceptions.RollbackFailureException;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.transaction.UserTransaction;

public class ClientsJpaController implements Serializable {

    public ClientsJpaController(UserTransaction utx, EntityManagerFactory emf) {
        this.utx = utx;
        this.emf = emf;
    }
    private UserTransaction utx = null;
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Clients clients) throws RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            em.persist(clients);
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Clients clients) throws NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            clients = em.merge(clients);
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = clients.getId();
                if (findClients(id) == null) {
                    throw new NonexistentEntityException("The clients with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            Clients clients;
            try {
                clients = em.getReference(Clients.class, id);
                clients.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The clients with id " + id + " no longer exists.", enfe);
            }
            em.remove(clients);
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Clients> findClientsEntities() {
        return findClientsEntities(true, -1, -1);
    }

    public List<Clients> findClientsEntities(int maxResults, int firstResult) {
        return findClientsEntities(false, maxResults, firstResult);
    }

    private List<Clients> findClientsEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Clients.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Clients findClients(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Clients.class, id);
        } finally {
            em.close();
        }
    }

    public int getClientsCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Clients> rt = cq.from(Clients.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}

the class which will create and call methods on the controller; it is intended to provide a single queue for the web module to pop elements (in this, int's) from:

package db;

import javax.ejb.Singleton;

@Singleton
public class MySingletonQueue implements RemoteQueue {

    private int next = 3;   //dummy
    private ClientsJpaController cjc;  //instantiate how?

    @Override
    public int getNext() {
        return next;  //get next int from perhaps another class or method...
    }

}

for context, the bean which the web page instantiates with EL:

package dur;

import db.RemoteQueue;
import java.io.Serializable;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@Named
@SessionScoped
public class MySessionBean implements Serializable {

    @EJB
    private RemoteQueue mySingletonQueue;

    private static final long serialVersionUID = 1L;
    private static final Logger log = Logger.getLogger(MySessionBean.class.getName());

    public MySessionBean() {
    }

    public int getNext() {
        log.info("getting next int from remote EJB");
        return mySingletonQueue.getNext();
    }

}

http://forums.netbeans.org/viewtopic.php?t=47442&highlight=jpa+controller+constructor


Answer:

Answer is simple:

package db;

import javax.ejb.Singleton;


import javax.annotation.PostConstruct;
import javax.ejb.Singleton;

@Singleton
public class MySingletonQueue implements RemoteQueue {

    private int next = 3;
    private ClientsJpaController cjc;

    @PersistenceUnit
    private EntityManagerFactory emf;

    @Resource
    private UserTransaction utx; 

    @PostConstruct
    public void initBean() {
        // Instantiate your controller here
        cjc = new ClientsJpaController(utx, emf);
    }

    // rest of the class ...

}

But keep in mind that although it will work, what you are doing is extremely messy and unmaintainable and is considered a bad practice.

Update

Some advice:

  1. You should inject an entity manager to your ClientsJpaController (also consider renaming it to ClientDAO)
  2. Do not manage transactions in a server environment, lets server do that. Your code would be simplified to just a few lines.
  3. Your entity Clients is in plural form, it should be singular because it represents single client, doesn't it?
  4. You definitely should not do something like: catch (Exception ex) {, because it is a root of all exceptions. Catch only the most specific exception instead.

So, for example, your edit function can be shortened to:

  public Client edit(Client client) {
    return em.merge(client);
  }

You should definitely take a look at some EJB/ JPA book or read some decent guide.

Question:

In Java CDI there is great functionality on gathering all managed beans, that share a supertype. Let's say I what to gather all managed instances of MyInterceptor, I just have to write:

@Inject
@Any
Instance<MyInterceptor> myInterceptors;

Similar functionality I was able to obtain when I was working on EJB, although solution there was way less pretty (I needed to call BeanManager).

Can similar functionality I can obtain working on @Component's managed by Spring context?

[Edit] Why is not a duplicate of What is the Spring equivalent for CDI's Instance, or Guices Provider From my understanding, in the above question, there is a hidden assumption, that I have both contexts: Spring and CDI, which may not be always the case (especially in Java SE applications). Furthermore, I have a bad experience in mixing contexts, they often claim that they are compatible, but it isn't always the case. You can get trapped in unexpected problems, like this: https://blog.akquinet.de/2017/01/04/dont-get-trapped-into-a-memory-leak-using-cdi-instance-injection/


Answer:

If you specify the the field as a List with a generic type MyInterctptor you should be able to achieve what you are looking for. Ex:

@Autowired
List<MyInterceptor> interceptors;

More info can be found here: https://dzone.com/articles/load-all-implementors

Question:

My question is the following: Assume that you have a class Person which has 2 instances Adam and Jacobs. So, you have 2 another classes called School and University. My task is to define by injecting that Jacobs is studying in the school and Adam is an university student as well.

How to do it using Spring Framework? Code written answer is welcome :))


Answer:

I think what you're trying to do is to inject different instances of the same type in different components. You can do that by using spring @Qualifiers. I sketch a solution to the problem you shared.

Having the Person class.

public class Person
{
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

And a configuration for each person.

@Configuration
public class DemoConfig {

    @Bean
    public Person adam() {
        return new Person("Adam");
    }

    @Bean
    public Person jacobs() {
        return new Person("Jacobs");
    }
}

The School class.

@Component
public class School {

    private Person jacobs;

    public School(@Qualifier("jacobs") Person jacobs) {
        this.jacobs = jacobs;
    }

    public String personName() {
        return jacobs.getName();
    }
}

The university class is similar to the School class but changing the qualifier name to "adam".

Here is a test to your requirements.

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {

    @Autowired
    private School school;

    @Autowired
    private University university;

    @Test
    public void testPersonDependencies() {
        assertThat(school.personName()).isEqualTo("Jacobs");
        assertThat(university.personName()).isEqualTo("Adam");
    }
}

Question:

I have the following classes:

public class ScoringService {

    @Inject
    public ServiceOne service1;

    @Inject
    public ServiceTwo service2;

    @Inject
    public DecisionHandler dh;

    public void scoreData() {

        Data d1 = service1.getData();
        Data d2 = service2.getData();
        Data newData = process(d1, d2)

        dh.handle(newData);
    }

}

public class DecisionHandler {

    @Inject
    public ServiceOne service1;

    public void handle(Data newData) {
        service.updateData(newData);
    }
}

ServiceOne and ServiceTwo are @Stateless annotated EJBs.

I know that container makes pools for that Stateless EJB and also proxies for injections and stuff. So in my case is it possible that there will be two different instances of ServiceOne in both instances of ScoringService and DecisionHandler? And therefore there will be overgenerated ServiceOne instances? I mean the ScoringService with injected DecisionHandler in it will be called for one purpose and there is no need two hold two instances of ServiceOne.

I made the DecisionHandler a separate class to disassemble complex logic concentrated in one ServiceClass. Also I can make the DecisionHandler as a plain class with a method and instantiate it during call. How should I understand that I should make it an EJB?

I become to think that it some outdated stuff for only Client-Server model with thick cliend to help making calls to the servers EJBs through remote calls and it SHOULDN'T be used in projects with web or self-running computing programs. Is that true?


Answer:

So in my case is it possible that there will be two different instances of ServiceOne in both instances of ScoringService and DecisionHandler?

if you are talking about @Stateless then it is up to the container (application server). You are not supposed to take any assumption on the number of EJBs serving clients. So you can have one or two, it is unpredictable.

I made the DecisionHandler a separate class to disassemble complex logic concentrated in one ServiceClass. Also I can make the DecisionHandler as a plain class with a method and instantiate it during call. How should I understand that I should make it an EJB?

If your application server is JEE compliant (i.e. not Tomcat) and your application is middle/big sized and you need transaction, scalability, and you want a class to act as a stand alone component with specific business logic, then you probably need an EJB. Besides, have you tried to run your classes ? Because if they are not managed by the container, the @Inject is not working.

I become to think that it some outdated stuff for only Client-Server model with thick cliend to help making calls to the servers EJBs through remote calls and it SHOULDN'T be used in projects with web or self-running computing programs. Is that true?

Unfortunately, most people think the current specification for EJB is still 2.x, while instead 3.x is out since 2009. EJB in their current specification are scalable, transactional...they have many benefits rather than disadvantages, and they fit perfectly in a web context.

However just because you have mentioned remote call: @Remote interface have a little overhead to think about and some design decision to be made (coarse grained vs fine grained interface).

[Update]

Regarding scalability, these are few fragments from the official EJB 3.1 specification, there are many more:

Just in the introduction

Applications written using the Enterprise JavaBeans architecture are scalable, transactional, and multi-user secure.

Then...

A typical EJB container provides a scalable runtime environment to execute a large number of session objects concurrently.

Question:

I am trying to figure out CDI and the best method that suits my needs. I have an service(TcpServiceImpl) that interacts with plain tcp communication. Now this service has some points where it needs to inform somebody that something happened. For this informations I have the Interface TcpConnection which needs to be CDI injected to the correct implementation. Another problem is that the service TcpServiceImpl itself is injected in a job (TcpConnectionJob) that executes periodically and calls the service to do things. This means that the service TcpServiceImpl will exist multiple times. Each having another tcp connection it handles and having another device that needs another driver/protocol to be injected in the Interface TcpConnection.

Let me show the three Elements taking part in this scenario:

Here is the Interface that will get multiple implementations:

public interface TcpConnection
{

  /**
   * Connected.
   *
   * @throws NGException the NG exception
   */
  public void connected() throws NGException;

  /**
   * This method will send the received data from the InputStream of the connection.
   *
   * @param data the received data
   * @throws NGException the  NG exception
   */
  public void received( byte[] data ) throws NGException;

  /**
   * Usable for the protocol to send data to the device.
   *
   * @param data the data to send to the device ( Will be converted to byte[] with getBytes() )
   * @throws NGException the  NG exception
   */
  public void send( String data ) throws NGException;

  /**
   * Usable for the protocol to send data to the device.
   *
   * @param data the data to send to the device ( Will be send as is )
   * @throws NGException the NG exception
   */
  public void send( byte[] data ) throws NGException;

  /**
   * This method will inform the protocol that the connection got closed.
   *
   * @throws NGException the NG exception
   */
  public void closed() throws NGException;
}

Also here is a example snippet of when this will be called in my existing service:

public class TCPServiceImpl implements TCPService, Runnable
{
/** The callback. */
private TcpConnection callback;
private void disconnect()
{
  connection.disconnect();
  if ( !getStatus( jndiName ).equals( ConnectionStatus.FAILURE ) )
  {
     setStatus( ConnectionStatus.CLOSED );
  }
  /* TODO: Tell driver connection is closed! */
  callback.closed();
}
}

Below is the class that calls the service,which then needs to dynamically inject the correct implementation for the interface.

public class TcpConnectionJob implements JobRunnable
{
  /** The service. */
  private TCPService service;

  public void execute()
  {
    service.checkConnection( connection );
  }
}

The service injection callback has to be linked to the implementation of the correct "protocol" or "driver" that will translate the data or handle the logic for the device. There will be multiple driver implementations of the interface acting different and I need to inject the correct one. A qualifier for this decision could be the name of the device. Now I looked at the following links:

Understanding the necessity of type Safety in CDI

How to programmatically lookup and inject a CDI managed bean where the qualifier contains the name of a class

How to use CDI qualifiers with multiple class implementations?

Question:

But I am still unsure about which way/method to use and what is the correct way. Any help would be appreciated.

My first thought was about copying my interface to an Qualifier Interface and appending this one with the possibility to enter the qualifier. Is that a good idea?


Answer:

Use CDI events and do not obther with callbacks. Some resources:

https://docs.oracle.com/javaee/7/tutorial/cdi-adv005.htm

http://www.adam-bien.com/roller/abien/entry/java_ee_6_observer_with

http://www.next-presso.com/2014/06/you-think-you-know-everything-about-cdi-events-think-again/

Question:

disclaimer: I am rather new to the whole concept of EJB

I am trying to make a simple enterprise application that makes use of the EJB dependency injection mechanism. The objects that I am trying to inject are of different (non-generic) classes that both implement the same (generic) interface and are also exposed as being of that interface's type to their containing class. The problem is that EJB does not know what class to use to instantiate said objects in their containing class. How would I go about resolving this problem?

(apologies for bad code formatting)

The classes that i'm trying to inject are:

@Stateless
public class HumidityRepository implements ITimeStampedDataRepository<Humidity>, Serializable {

@PersistenceContext(unitName = "WeatherPU")
private EntityManager em;

@Override
public List<Humidity> getAll() {
    Query q = em.createQuery("allHumidity");
    System.out.println(q.getResultList());
    List<Humidity> result = q.getResultList();
    return result;
}

@Override
public List<Humidity> getAllOnDate(LocalDate date) {
    Query q = em.createQuery("onDateHumidity")
            .setParameter("date", date);
    System.out.println(q.getResultList());
    List<Humidity> result = q.getResultList();
    System.out.println(result);
    return result;
}

@Override
public List<Humidity> getAllAfter(LocalDate date, LocalTime time) {
    Query q = em.createQuery("afterHumidity")
            .setParameter("date", date)
            .setParameter("time", time);
    List<Humidity> result = q.getResultList();
    return result;
}

@Override
public void remove(LocalDate date, LocalTime time) {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

@Override
public void store(Humidity data) {
    em.persist(data);
}

}

and:

@Stateless
public class TemperatureRepository implements ITimeStampedDataRepository<Temperature>, Serializable {

@PersistenceContext(unitName = "WeatherPU")
private EntityManager em;

@Override
public List<Temperature> getAll() {
    Query q = em.createQuery("allTemperature");
    System.out.println(q.getResultList());
    List<Temperature> result = q.getResultList();
    return result;
}

@Override
public List<Temperature> getAllOnDate(LocalDate date) {
    Query q = em.createQuery("onDateTemperature")
            .setParameter("date", date);
    System.out.println(q.getResultList());
    List<Temperature> result = q.getResultList();
    System.out.println(result);
    return result;
}

@Override
public List<Temperature> getAllAfter(LocalDate date, LocalTime time) {
    Query q = em.createQuery("afterTemperature")
            .setParameter("date", date)
            .setParameter("time", time);
    List<Temperature> result = q.getResultList();
    return result;
}

@Override
public void remove(LocalDate date, LocalTime time) {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

@Override
public void store(Temperature data) {
    em.persist(data);
}
}

Their common interface is:

public interface ITimeStampedDataRepository<T extends TimeStampedData> {

    public List<T> getAll();

    public List<T> getAllOnDate(LocalDate date);

    public List<T> getAllAfter(LocalDate date, LocalTime time);

    public void remove(LocalDate date, LocalTime time);

    public void store(T data);

}

Finally, their containing class is:

@Dependent
public class Service implements IService {

    @EJB
    private ITimeStampedDataRepository<Humidity> humidityRepository;
    @EJB
    private ITimeStampedDataRepository<Temperature> temperatureRepository;

    ...

}

Answer:

You have two options:

1.Give a name to your EJBs:

@Stateless(name="BeanNameOne")
public class TemperatureRepository implements.....

@Stateless(name="BeanNameTwo")
public class HumidityRepository implements.....

and tell which EJB to inject in the client.

@EJB(beanName="BeanNameOne")
private ITimeStampedDataRepository<Temperature> temperatureRepository;
@EJB(beanName="BeanNameTwo")
private ITimeStampedDataRepository<Humidity> humidityRepository;

2.refer to the unqualified name

@EJB(beanName="TemperatureRepository ")
private ITimeStampedDataRepository<Temperature> temperatureRepository;
@EJB(beanName="HumidityRepository")
private ITimeStampedDataRepository<Humidity> humidityRepository;

Question:

I just installed Glassfish 4 and I'm trying to implement a web app that includes a long running thread that continuously inserts entities into a DB, that is started when a servlet is called. When the EJB managing the entity is injected into the task, I get an UnsatisfiedResolutionException: WELD-001308: Unable to resolve any beans for Type:... error in the Instance.get() method.

The EJB

@Stateless
public class MeasureEJB {

    @Resource
    ManagedExecutorService managedExecutorService;

    @Inject
    Instance<UpdatingTask> myTaskInstance;


    @PersistenceContext(unitName = "smarthomePU")
    private EntityManager em;

    public List<Measure> findMeasures() {
        Query query = em.createQuery("SELECT b FROM Measure b");
        return query.getResultList();
    }

    public Measure createMeasure (Measure _measure) {
        em.persist(_measure);
        return _measure;
    }

    public void executeBgThread() {
        UpdatingTask myTask = myTaskInstance.get(); <- Here I get the error
        this.managedExecutorService.submit(myTask);
    }
}

The servlet

@WebServlet(description = "Servlet used to start the historizer", urlPatterns = { "/starthistorizer" })
public class StartHistorizer extends HttpServlet {

    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public StartHistorizer() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        measureEjb.executeBgThread();

        response.getWriter().append("Served at: ").append(request.getContextPath());
        request.getRequestDispatcher("/index.jsp").forward(request, response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}

and the task

@Stateless public class UpdatingTask implements Runnable {

private static final String TAG = "smarthome";

@EJB
MeasureEJB measureEjb;

@Override
public void run() {
    // TODO Auto-generated method stub
    BufferedReader br = null;

    try {
        <Insert entities upon sensor messages>
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

}

and finally the error

[2016-09-02T13:19:17.419+0000] [glassfish 4.1] [WARNING] [] [javax.enterprise.web] [tid: _ThreadID=29 _ThreadName=http-listener-1(5)] [timeMillis: 1472822357419] [levelValue: 900] [[
  StandardWrapperValve[com.storassa.javaee.smarthome.StartHistorizer]: Servlet.service() for servlet com.storassa.javaee.smarthome.StartHistorizer threw exception
javax.ejb.EJBException
    at com.sun.ejb.containers.EJBContainerTransactionManager.processSystemException(EJBContainerTransactionManager.java:752)
    at com.sun.ejb.containers.EJBContainerTransactionManager.completeNewTx(EJBContainerTransactionManager.java:702)
    at com.sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx(EJBContainerTransactionManager.java:507)
    at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4566)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2074)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2044)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:220)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
    at com.sun.proxy.$Proxy244.executeBgThread(Unknown Source)
    at com.storassa.javaee.smarthome.__EJB31_Generated__MeasureEJB__Intf____Bean__.executeBgThread(Unknown Source)
    at com.storassa.javaee.smarthome.StartHistorizer.doGet(StartHistorizer.java:36)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001308: Unable to resolve any beans for Type: class com.storassa.javaee.smarthome.UpdatingTask; Qualifiers: [@javax.enterprise.inject.Default()]
    at org.jboss.weld.bean.builtin.InstanceImpl.get(InstanceImpl.java:101)
    at com.storassa.javaee.smarthome.MeasureEJB.executeBgThread(MeasureEJB.java:39)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
    at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
    at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4786)
    at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
    at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:64)
    at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:140)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
    at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:369)
    at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4758)
    at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4746)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
    ... 34 more
]]

Answer:

It is not normally possible to execute EJBs in randomly created threads. This is because they expect to find contextual information such as security and transaction management to be associated with the currently executing thread.

Additionally, it is never a good idea to create unmanaged threads in an enterprise application because you have no way of controlling this use of resources.

The way around this is to make use of Java EE 7's Concurrency Utilities which provides mechanisms for acquiring properly prepared threads from a thread pool that you have configured in your server.

You can read more about this at Java EE 7: Using Concurrency Utilities in Asynchronous Servlets.

Question:

I'm working in a project with Java EE 7 and I need to inject a javax.ejb.@Stateless bean into another. Both beans have a similar structure:

@Stateless
public class OperationRepository extends GenericRepository<Operation> {

    @PersistenceContext
    private EntityManager entityManager;

    public OperationRepository() {
    }
    /*Implementation of abstract methods, getters/setters, etc*/
}

@Stateless
public class MenuRepository extends GenericRepository<Menu> {

    @PersistenceContext
    private EntityManager entityManager;

    @Inject
    private OperationRepository operationRepository;

    public MenuRepository() {
    }

    /*idem OperationRepository*/

    public List<Menu> getMenuFromOperation(...) {
        // Do something where I need operationRepository
    }
}

The GenericRepository<E> is just an abstract class with some common methods and other abstract methods, doesn't matter here.

The problem is that in the getMenuFromOperation() method I get a NullPointerException. Debugging the code I realized that the injected operationRepository is null when requested in the method.

Why does fail the injection point? what am I missing here?

Just to make a little test, I injected manually by instantiating a default OperationRepository in the MenuRepository constructor, but in that case the OperationRepository.entityManager isn't injected (is null)

Thanks in advance for your answers.

Edit #1

As requested by John Ament, here it goes:

  1. All my code is in a single jar file. It's a Maven module that will be deployed together with a web module (a war package) in a Glassfish Server 4.1.
  2. The beans.xml still doesn't exists yet, because the project isn't ready to be deployed (I didn't perform any integration test yet)
  3. The MenuRepository is leveraged from a @Test class because I'm still developing MenuRepository.

The code for the test class is as follows:

public class MenuOperationRepositoryUTest extends BaseTestRepository {
    private MenuRepository menuRepository;
    private OperationRepository operationRepository;

    @Before
    public void initTestCase() {
        initTestDB();

        menuRepository = new MenuRepository();
        menuRepository.setEntityManager(em);
        operationRepository = new OperationRepository();
        operationRepository.setEntityManager(em);
    }

    @After
    public void finalizeTestCase() {
        closeEntityManager();
    }

    /*Some successful tests*/

    @Test
    public void showMenuFromOperation() {
        // Insert some dummy data into the test DB (HSQL)

        // This method needs the injected OperationRepository in MenuRepository
        List<Menu> menu = menuRepository.getMenuFromOperation(...);

        // Assertions
    }
}

And the BaseTestRepository is as follows:

@Ignore
public class BaseTestRepository {

    private EntityManagerFactory emf;
    protected EntityManager em;

    // This is a helper class that contains all the boilerplate to begin transaction 
    // and commit, it's used to insert data in the test DB
    protected DBCommandExecutor dbCommandExecutor;

    protected void initTestDB() {
        // sigeaPU is the name declared in persistence.xml
        emf = Persistence.createEntityManagerFactory("sigeaPU");
        em = emf.createEntityManager();

        dbCommandExecutor = new DBCommandExecutor(em);
    }

    protected void closeEntityManager() {
        em.close();
        emf.close();
    }
}

I think that's all I got so far. Let me know any clue you can get (or guess)


Answer:

Because you're testing out of the CDI container you should also set your dependencies manually in the @Before method of the test class.

menuRepository.setOperationRepository(operationRepository)

Question:

I'm currently struggeling with injecting an EJB and a ManagedBean into a Spring-Handler. My goal is to inject these two beans into this AuthenticationSuccessHandler.

public class LoginAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
}

This handler is called by Spring upon a successful login and doesn't seem to process injection-annotations. The two beans, which should be injected, are of the following structure:

@javax.ejb.Stateless
public class EjbService {
}

@javax.enterprise.context.SessionScoped
@javax.inject.Named("cdiBean")
public class CdiBean implements Serializable {
}

So far I've tried various annotations like the following, but the variables stay null:

public class LoginAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @EJB
    private UserDatabaseService userDatabaseService;

    @Inject
    private UserManagementBean userManagement;
}

Could somebody point me to the right way?


Answer:

Normally, you cannot inject CDI managed Bean into Spring managed Bean. You will need to use direct access to Bean Manager. For Example by using javax.enterprise.inject.spi.CDI class.

then you can do something like that:

public static <T> T getInstance(Class<T> type, Annotation... qualifiers) {
    Set<Bean<?>> beans = getBeanManager().getBeans(type, qualifiers);
    Bean<?> bean = getBeanManager().resolve(beans);

    if(bean == null){
        throw new UnsatisfiedResolutionException();
    }

    @SuppressWarnings("unchecked")
    T instance = (T) getBeanManager().getReference(bean, type,
            getBeanManager().createCreationalContext(bean));
    return instance;
}

public static BeanManager getBeanManager() {
    return CDI.current().getBeanManager();
}

Question:

Is there any way to inject @Named bean to Singleton?

Here's the class that needs to be injected

@Named
@Stateful
@ConversationScoped
public class PlaySessionBean implements Serializable {
    @PersistenceContext(unitName = "test-persistence-unit", type = PersistenceContextType.EXTENDED)
    private EntityManager entityManager;
....
}

The bean is used for view utility (generated by Forge)

The problem is that I need to access the PlaySessionBean from @Startup @Singleton

@Startup
@Singleton
public class StartupBean {
  private static final Logger LOGGER = Logger.getLogger(StartupBean.class.getName());

  private EntityManager entityManager;
  private static EntityManagerFactory factory =
      Persistence.createEntityManagerFactory("wish-to-paris-persistence-unit");
  private List<PlaySession> playSessions;

  @PostConstruct
  public void run() {
    this.entityManager = factory.createEntityManager();
    CriteriaQuery<PlaySession> criteria =
        this.entityManager.getCriteriaBuilder().createQuery(PlaySession.class);
    this.playSessions =
        this.entityManager.createQuery(criteria.select(criteria.from(PlaySession.class)))
            .getResultList();
    this.entityManager.close();
  }
 ....

But it always failed and complained that PlaySession is not an Entity

Is there a way to inject the Named Stateful bean to Singleton? If not, is there any workaround for it?

Thanks


Answer:

You are mixing CDI scoping with EJB states. I would rather that you choose either CDI or EJB but not mix the 2. For one, transaction management is different between the 2 architectures. Also, the life cycle of each objects are completely different.

If you are going to use EJB and call the respective session bean, you can annotate your @Stateful Session Bean as a @LocalBean since your session bean as no interface inheritance.

Example:

@Stateful
@LocalBean
public class PlaySessionBean implements Serializable {

}

Then on your @Startup Singleton bean, you can simply reference it by:

@EJB
private PlaySessionBean playSessionBean;

The EJB Session Bean will still be stateful.

Question:

I don't understand the difference between lookup parameter and name parameter of the @Resource annotation. I read all the documentation about the annotation and its field etc.

I know how name can be used to inject or bind a resource, but the problem is that did not find any example that explain the difference between lookup and name.

Can anyone give me a such example or tell me the difference between them ?


Answer:

name is a "virtual" reference name in the java:comp/env namespace. At some level, that reference needs to point to a "physical" resource that has been defined. The standard way to do that is with the lookup attribute, but products will also have a way to "bind" the the resource reference, so in many products, the product-specific binding is functionally equivalent to the name. (The product-specific binding is still important because you don't want to rely on developers to hard-code data source names from the operational environment, etc.)

For example, you might have @Reference(name="jdbc/myDS", lookup="jdbc/oracleDS"), which means java:comp/env/myDS will be defined as an indirect lookup to the jdbc/oracleDS data source that was bound to the default JNDI namespace.

For another example, you might have @DataSourceDefinition(name="derbyDS") and @Resource(name="jdbc/myDS", lookup="java:comp/env/derbyDS"). The former defines an actual data source (again relative to java:comp), and the latter defines an indirect lookup to it.

Question:

Is it secure to pass a Injected EntityManager created on an EJB, to a method that will return an Object, and after, persist that Object on a Web Session for web clients use it?

Like in this example: the EJB

@Stateless(mappedName = "MyService")
@LocalBean
public class MyService implements MyServiceLocal {

@PersistenceContext(unitName="primary")
private EntityManager em;

    /**
     * Default constructor. 
     */
    public MyService() {   
    }


    @Override
    public Service newServiceX(User user) {
        return new ServiceX(user,em); // here, passing the EntityManager
    }

}

After, I persist this Service in a web client (using struts): The base action

    public class YAction extends ActionSupport implements SessionAware{
    @Inject
    private MyServiceLocal service;

    public String execute(){
    Service x = service.newServiceX();
    persistInCookie("ServiceX",x);
    }

    public void persistInCookie(String, Object){
    // persist
    }
    }

And after, using another Action: // another Action that

   class XAction{

   public String useService(){
   getService().doSomething();
   }


   protected Service getService(){
    Service service = (Service) getSessionMap().get("ServiceX");
    return service;
}

}

the POJO class ServiceX using the EntityManager:

public class ServiceX extends Service{

EntityManager em;

public ServiceX(User user, EntityManager em){
this.em = em;
}

public void doSomething(){
// do something with the EntityManager passed by the EJB
}

}

First, the action that would be call is the Y action to persist the Service on the Session, next, the X action will return the Service persisted on the Session and try to use it.

I believe that the EJB Stateless Session Bean can close My EntityManager and this ServiceX POJO class can't use it. This can happen? I found similar question HERE, but in this question, the EntityManager is passed to a helper class. In my case is different because I want to persist this Object on a session cookie, and use later.


Answer:

I don't think It is a good idea to store a EntityManager in SessionMap. What is more, I don't even think that it is a good idea to perform EntityManager operations outside the EJB container.

Have read about transaction-boundaries in JPA?

By default, EJB container is using CMT (Container Managed Transactions). In this case, container uses entitymanager-per-request pattern which means that the transaction begins and ends when one of the business methods of MyService starts and ends (transaction is committed or rollbacked in case of RuntimeException). For whole transaction time, EntityManager is connected with the same PersistenceContext. After the transaction is ended the container closes EntityManager which means that the EntityManager is disconnected with recent PersistenceContext:

// transaction begins
Service x = service.newServiceX();
// transaction ends

This might be crucial if you were going to do some update/insert operations outside the transaction.

Now, when you call EntityManager operation (like find) outside the transaction, for every each operation the EntityManager will create new PersistentContext. This may cause some issues, as two entities that represent the same record will be treated as different entities:

// each operation occurs in a separate persistence context, and returns 
// a new detached instance
Magazine mag1 = em.find(Magazine.class, magId);
Magazine mag2 = em.find(Magazine.class, magId);
assertTrue(mag2 != mag1);

Some more articles to read:

Persistent Context

Transactions and Concurrency

Entity Lifecycle Management

Question:

I have an EAR app (to deploy on Weblogic 12c), that has a "persist" componenent. The "persist" component uses JPA (implementation: EclipseLink) to persist the objects.

The bean that uses the entityManager is declared as @Stateless and the entity manager is injected though the @PersistenceContext annotation.

The problem is, i have an NullPointerException each time i try to access the entityManager (meaning, he has not been correctly injected).

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class MyBean implements MyBeanLocal {    

    @PersistenceContext(unitName = "MyPersistenceUnit", type = PersistenceContextType.EXTENDED)
    EntityManager entityManager;

    public void insert(MyObject object) {
        try {
            entityManager.persist(object); //NullPointerException here
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

persistence.xml

<?xml version="1.0"  encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
              http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">

    <persistence-unit name="MyPersistenceUnit"
        transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>MyDataSource</jta-data-source>
        <class>com.myclasses.MyObject</class>>
    </persistence-unit>

</persistence>

I use a factory to get an instance of MyBean:

public class MyBeanFactory
{
    public static MyBean create()
    {
        return new MyBean();
    }
}

And i use it like this in regular code:

MyBeanLocal bean = MyBeanFactory.create();

MyBeanLocal is the interface for MyBean and it goes like that

@Local(MyBeanLocal.class)
public interface MyBeanLocal {
    public void insert(MyObject object);
}

I tried to inject the MyBean instance through the @EJB annotation, and it fails (NullPointerException whenever i try to use the MyBean supposedly injected instance)

When my application is deployed on the Weblogic server, i don't see neither MyBean, nor MyPersistenceUnit in it (i see the MDBs from other componenents), though i can see MyPersistenceUnit under Deployments > "MyDomain" > Configuration/Settings > Persistence. MyDataSource is okay and connected.

There is the startup log for the weblogic server.

####<15 juil. 2015 09 h 52 CEST> <Notice> <Security> <MyUsername> <AdminServer> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1436946746252> <BEA-090082> <Security initializing using security realm myrealm.> 
####<15 juil. 2015 09 h 52 CEST> <Notice> <WebLogicServer> <MyUsername> <AdminServer> <[STANDBY] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1436946771648> <BEA-000365> <Server state changed to STANDBY.> 
####<15 juil. 2015 09 h 52 CEST> <Notice> <WebLogicServer> <MyUsername> <AdminServer> <[STANDBY] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1436946771650> <BEA-000365> <Server state changed to STARTING.> 
####<15 juil. 2015 09 h 53 CEST> <Warning> <EJB> <MyUsername> <AdminServer> <[ACTIVE] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1436946795598> <BEA-012035> <The Remote interface method: public abstract boolean com.myclasses.UtilityRemote.send(com.mytypes.ReqType,java.lang.String) in EJB UtilityBean contains a parameter of type com.mytypes.ReqType which is not serializable. Though the EJB IMMJMSUtilityBean has call-by-reference set to false, this parameter is not serializable and hence will be passed by reference. A parameter can be passed using call-by-value only if the parameter type is serializable.> 
####<15 juil. 2015 09 h 53 CEST> <Notice> <Log Management> <MyUsername> <AdminServer> <[ACTIVE] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1436946808540> <BEA-170027> <The server has successfully established a connection with the Domain level Diagnostic Service.> 
####<15 juil. 2015 09 h 53 CEST> <Notice> <WebLogicServer> <MyUsername> <AdminServer> <[STANDBY] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1436946809347> <BEA-000365> <Server state changed to ADMIN.> 
####<15 juil. 2015 09 h 53 CEST> <Notice> <WebLogicServer> <MyUsername> <AdminServer> <[STANDBY] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1436946809503> <BEA-000365> <Server state changed to RESUMING.> 
####<15 juil. 2015 09 h 53 CEST> <Notice> <Server> <MyUsername> <AdminServer> <[ACTIVE] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1436946809774> <BEA-002613> <Channel "Default[1]" is now listening on 127.0.0.1:7001 for protocols iiop, t3, ldap, snmp, http.> 
####<15 juil. 2015 09 h 53 CEST> <Warning> <Server> <MyUsername> <AdminServer> <DynamicListenThread[Default]> <<WLS Kernel>> <> <> <1436946809774> <BEA-002611> <The hostname "MyUsername.MyProxy.com", maps to multiple IP addresses: 172.23.247.5, 0:0:0:0:0:0:0:1.> 
####<15 juil. 2015 09 h 53 CEST> <Notice> <Server> <MyUsername> <AdminServer> <[ACTIVE] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1436946809775> <BEA-002613> <Channel "Default[2]" is now listening on 0:0:0:0:0:0:0:1:7001 for protocols iiop, t3, ldap, snmp, http.> 
####<15 juil. 2015 09 h 53 CEST> <Notice> <Server> <MyUsername> <AdminServer> <[ACTIVE] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1436946809775> <BEA-002613> <Channel "Default" is now listening on 172.23.247.5:7001 for protocols iiop, t3, ldap, snmp, http.> 
####<15 juil. 2015 09 h 53 CEST> <Notice> <WebLogicServer> <MyUsername> <AdminServer> <[ACTIVE] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1436946809776> <BEA-000331> <Started the WebLogic Server Administration Server "AdminServer" for domain "test" running in development mode.> 
####<15 juil. 2015 09 h 53 CEST> <Notice> <WebLogicServer> <MyUsername> <AdminServer> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1436946810276> <BEA-000360> <The server started in RUNNING mode.> 
####<15 juil. 2015 09 h 53 CEST> <Notice> <WebLogicServer> <MyUsername> <AdminServer> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1436946810280> <BEA-000365> <Server state changed to RUNNING.> 

I suspect that the problem is that this bean is not correctly processed by the weblogic server, but i have no idea how to fix it.

If anyone could help me, i'd be thankful. Ask me for more code/config/context if you need to.


Answer:

The problem here is how you're getting hold of the EJB reference - if you construct the instance yourself using "new", what you'll get is just a POJO rather than an EJB - this means you won't have access to any EJB services like dependency injection and transaction management.

To get hold of a genuine EJB, you should look up your bean in the initial context:

 MyBeanRemote bean = (MyBeanRemote) new InitialContext().lookup("MyBean/remote");

Question:

So I have a service I am hooking by instantiating it through a factory that creates a proxy so it can process some annotations I have on the service. So my question is this...is there a way with JavaEE to have my dependency injection instantiate the instances of said service through the factory instead of however EJB's are normally instantiated by the server.

And otherwise...is there another way I could direct the Servlet or EJB container to process annotations for me? Like a bolt in of sorts that could have the code for handling the reflective analysis of the annotated class/method/fields?

I am sorry if this question is hard to understand, I'm having a hard time figuring out how to ask it. Here is an example of a factory one might use to instantiate a service (through a proxy).

package com.trinary.test.service;

import java.lang.reflect.Proxy;

import com.trinary.security.owasp.proxy.OWASPMethodValidatorProxy;

public class TestServiceFactory {
    Class<?>[] interfaces = {TestService.class};

    public TestService createESignService() throws IllegalArgumentException, InstantiationException, IllegalAccessException {
        return (TestService)Proxy.newProxyInstance(
                this.getClass().getClassLoader(), 
                interfaces,
                new OWASPMethodValidatorProxy<TestService>(TestServiceImpl.class));
    }
}

I would love it if in a servlet I might do something like this:

package com.trinary.test.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.trinary.test.service.TestService;

public class TestServlet extends HttpServlet {
    private static final long serialVersionUID = -1778574173539761350L;

    @EJB protected TestService testService;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        System.out.println("PATH: " + req.getPathInfo());
        // ...

        resp.setContentType("text/html");
        resp.getWriter().append("<html><h1>TESTY TEST!</h1></html>");
    }
}

In the above you can see how I might be injecting test service into my servlet. But I would like the EJB container to instantiate new instances of TestService using the factory instead of however the container usually does it. Is there a way to do this?


Answer:

There's no way to directly intercept @EJB at the injection point, but you could intercept the method call on the actual bean using an EJB interceptor. If you can switch to CDI @Inject in the client, then you could use a CDI interceptor. At that point, you could use a CDI producer method to have more control over the object injected into the servlet.

Question:

i try to inject my singleton startup bean, which initializes the CustomerDataModel, into a vaadin class.

@Startup
@Singleton
public class StartupBean {
   @Resource(lookup = "java:global/customerDatabase")
   private String customerDatabasePath;

   @Resource(lookup = "java:global/addressDatabase")
   private String addressDatabasePath;

   private CustomerDataModel dataModel = null;

   public StartupBean() {

   }

   @PostConstruct
   private void startup() {
       File customerDatabase = new File(customerDatabasePath);
       File addressDatabase = new File(addressDatabasePath);

       dataModel = new DataModelImpl(customerDatabase, addressDatabase);
   }

   @PreDestroy
   private void shutdown() {

   }

   public CustomerDataModel getDataModel() {
       return dataModel;
   }
}

Here is my vaadin class which needs a fully initialized startup bean

@DependsOn("StartupBean")
@Stateless
public class Workspace extends UI {
   @EJB
   private StartupBean startupBean;

   @WebServlet(value = "/*", asyncSupported = true)
   @VaadinServletConfiguration(productionMode = false, ui = Workspace.class)
   public static class Servlet extends VaadinServlet {
   }

   @Override
   protected void init(VaadinRequest request) {
   if(startupBean == null) {
      System.out.println("error");
   }

I tried it with @EJB and @Inject, neither works. I always get a nullpointer at startupBean. I also have a bean.xml at WEB-INF

i tried it according to http://java.dzone.com/articles/cdi-di-p1 and http://docs.oracle.com/javaee/6/tutorial/doc/gipvi.html

Does anyone know what i am doing wrong?


Answer:

The problem is that your Workspace object (extends Vaadin UI) cannot be a stateless EJB. One instance of those is used by one single user. Instead your should start using Vaadin CDI and annotate it with @CDIUI. Then you can inject the EJB to your CDI managed (~ session scoped) Vaadin UI.

Question:

I'm using Glassfish 4 to deploy an application. It used to have an EJB where the SessionContext is injected via a @Resource annotation.

@Stateless
@DeclareRoles({"StandardRole1", "StandardRole2"})
public class MyClass implements MyInterface {

    @Resource
    private SessionContext ctx;

    @Override
    public String getPrincipalName() {
        return ctx.getPrincipal().getName();
    }
}

This worked fine like it should. Now I need to get extra allowed roles to extend the application. The new roles aren't always the same, so adding the roles to the MyClass bean is no option. What I've come up with is this:

@Stateless
@DeclareRoles({"StandardRole1", "StandardRole2"})
public class NormalRoles implements RolesInterface {

    @Resource
    private SessionContext ctx;

    @Override
    public String getPrincipalName() {
        return ctx.getPrincipal().getName();
    }
}

@Decorator
@DeclareRoles({"NewRole1", "NewRole2"})
public abstract NewRoles implements RolesInterface {

    @Inject
    @Delegate
    @Default
    private RolesInterface defaultBean;

    @Resource
    private SessionContext ctx;

    @Override
    public String getPrincipalName() {
        return ctx.getPrincipal().getName();
    }
}

@Stateless
public class MyClass implements MyInterface {

    @Inject
    private RolesInterface rolesBean;

    @Override
    public String getPrincipalName() {
        return rolesBean.getPrincipalName();
    }
}

Now when I try to run this, I get a NullPointerException on return ctx.getPrincipal().getName(); from the NewRoles decorator. Problem --> the SessionContext doesn't get injected.

I've had this problem before with a PersistenceContext posted here. I've tried to solve it in in that way, so doing something like this:

public class Producers {

    @Produces
    @Resource
    private SessionContext em;
}

And then use the @Inject annotation instead of the @Resource in the decorators. This doesn't work either.

Is there a way I can use @Resource in a decorator or do something similar?


Answer:

SessionContext is a resource that is linked to EJB and a Decorator is not an EJB but a CDI bean so it's normal that you get a null SessionContext. You could try getting your SessionContext via Jndi like it is describe here: http://javahowto.blogspot.fr/2006/06/4-ways-to-get-ejbcontext-in-ejb-3.html

Question:

I have EJB bean

Interface:

package com.xlab.ice.ejb.sessionbean;
import javax.ejb.Remote;

@Remote
public interface Session {
    public String getMessage();
}

Bean:

package com.xlab.ice.ejb.sessionbean;
import javax.ejb.Stateless;

@Stateless
public class SessionBean implements Session {
    public SessionBean() {
    }
    public String getMessage() {
        return "Hello!";
    }
}

It is successfully deployed into Glassfhish 4. But I cannot access it via simple client:

package com.xlab.ice.ejb.sessionbean;
import javax.ejb.EJB;

public class Client {

    @EJB
    private static SessionBean sessionBean;

    public void getMsg() {
        System.out.print(sessionBean.getMessage());
    }

    public static void main(String[] args) {
        new Client().getMsg();
    }
}

When I'm trying to run it via: appclient -client SessionBeanClient.jar I'm getting error. Here is stack trace - http://pastebin.com/JuHRcQp5

What I'm doing wrong?


Answer:

You are trying to access the ejb through a standalone client.

This requires specific jndi manual lookup, for which if you are starting off with ejb, would be best place to start off before getting the inns of ejb.

That said:

You need to know the host and CORBA port on which the ejb is deployed.

create an inital context and do a manual lookup.

See this stackoverflow question on how to go about it.

Cant access EJB from a Java SE client - Lookup Failed Error

Question:

I have a websphere application server for my project in RAD and i am treying to inject objects with ejb.Here are my files

LoginServlet

@WebServlet("/login")
public class LoginServlet extends HttpServlet {  

    @EJB UserService userService;

    public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  

        response.setContentType("text/html");  
        PrintWriter out = response.getWriter();  

        String username=request.getParameter("username");  
        String password=request.getParameter("password");  

        String a = userService.authorize(username, password);

            if(username.equals("qwe"))
            {  
                RequestDispatcher rd=request.getRequestDispatcher("servlet2");  
                rd.forward(request, response);  
            }  
            else
            {  
                out.print("Sorry UserName or Password Error!");  
                RequestDispatcher rd=request.getRequestDispatcher("/index.html");  
                rd.include(request, response);  

            }  
        }  

    }  

UserService (also tried @ejb instead of @Inject for the dao)

@Stateless
@Interceptors(ApplicationEntityManagerInterceptor.class)
public class UserService{

    @Inject 
    protected UserDAO userDAO;


    public String authorize(String username,String password)
    {
        return this.userDAO.authenticate(username, password);   
    }

}

UserDAO

@Stateless
@Interceptors(ApplicationEntityManagerInterceptor.class)
public class UserDAO extends GenericDAOJpaImpl<User, String>
{

    public String authenticate(String username,String password)
    {
         Map<String, Object> params = new HashMap<String, Object>();
         params.put("username", username);
         params.put("password", password);          
         User user= findSingleByNamedQueryAndNamedParams(User.AUTHENTICATE, params);
         return "TRUE";
    }

}

The interceptor

public class ApplicationEntityManagerInterceptor
{
    @AroundInvoke
    public Object joinTransaction(InvocationContext context) throws Exception
    {
        Object emAux = context.getParameters()[0];
        if(emAux instanceof EntityManager){
        EntityManager em = (EntityManager) emAux;
        em.joinTransaction();
        }
        return context.proceed();
    }

}

And inside web.xml

<ejb-local-ref>
    <ejb-ref-name>gr.mess.web.servlets.LoginServlet/userService</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>
    <local>gr.mess.services.UserService</local>
    <injection-target>
        <injection-target-class>gr.mess.web.servlets.LoginServlet</injection-target-class>
        <injection-target-name>userService</injection-target-name>
    </injection-target>
</ejb-local-ref>

My problem is that the userService is created normaly but the DAO object inside the service is null.What should i do.I created this based on another project but that project works normally and i dont get it.In the other project the DAO is not any xml for any kind of configuration

UPDATE the GenericDAOJpaImpl @Stateless @Interceptors(ApplicationEntityManagerInterceptor.class) public class GenericDAOJpaImpl {

protected Class<T> entityClass;

@PersistenceContext(unitName = "TEST_SQL")
protected EntityManager em;

public GenericDAOJpaImpl() {
    ParameterizedType genericSuperclass = (ParameterizedType) getClass()
         .getGenericSuperclass();
    this.entityClass = (Class<T>) genericSuperclass
         .getActualTypeArguments()[0];
}

public T create(T t) ..
public T load(PK id) ..
public T update(T t)..
public void delete(T t) ..
public T save(T t) ..
public Class<T> getEntityClass()..
public Query createNamedQuery(String name)..
@SuppressWarnings("unchecked")..
public List<T> findByNamedQuery(final String name, Object... params)..
public T findSingleByNamedQuery(final String name, Object... params)..
public List<T> findByNamedQueryAndNamedParams(final String name, final Map<String, ? extends Object> params)..
..

Update 2: I fixed my problem by doing the following creating a META-INF folder on the ear this time and adding three xml files named application.xml beans.xml and ibm-application-bnd.xml and adding the @Inject annontation above the userDAO


Answer:

You are using CDI injection here. - what version of CDI/JEE/WebSphere are you using here? - Do you have a beans.xml file in META-INF of the jar or is CDI scanning implict (Depends on WAS/CDI version and setup) ? - Does "UserDAO"qualifies as a CDI bean (ie what is the GenericDAOJpaImplclass?

You could add some tracing info in a method annoted with @PostConctruct in UserDAO to see if it is created by the CDI container

Question:

I´m trying to inject EJB into Spring 4 application context. I've read several manuals and tutorial and I have end to an end. I do not why Spring cannot get the Remote Bean by JDNI name. When I launch the app with WildFly 10 I get a 404 error.

My Bean definitions are: JNDI bindings for session bean named 'CursoServiceBean' in deployment unit 'subdeployment "gestion-docente-ejb.jar" of deployment "gestion-docente-ear-1.0.0-SNAPSHOT.ear"' are as follows:

java:global/gestion-docente-ear-1.0.0-SNAPSHOT/gestion-docente-ejb/CursoServiceBean!
com.formacion.ipartek.curso.CursoServiceRemote
java:app/gestion-docente-ejb/CursoServiceBean!
com.formacion.ipartek.curso.CursoServiceRemote
java:module/CursoServiceBean!
com.formacion.ipartek.curso.CursoServiceRemote
java:jboss/exported/gestion-docente-ear-1.0.0-SNAPSHOT/gestion-docente-ejb/CursoServiceBean!
com.formacion.ipartek.curso.CursoServiceRemote
java:global/gestion-docente-ear-1.0.0-SNAPSHOT/gestion-docente-ejb/CursoServiceBean
java:app/gestion-docente-ejb/CursoServiceBean
java:module/CursoServiceBean

bean id ="cursoServiceRemote"  class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean">
   property name="jndiName" value="java:module/CursoServiceBean!com.formacion.ipartek.curso.CursoServiceBean" />
   property name="jndiEnvironment">
        props>
           prop key="java.naming.factory.initial">com.sun.jndi.ldap.LdapCtxFactory</prop>
           prop key="java.naming.provider.url">ldap://localhost:9990</prop>
           prop key="java.naming.security.principal">*******/prop>
           prop key="java.naming.security.authentication">simple/prop> 
           prop key="java.naming.security.credentials">******/prop>
        /props>
    /property>
   property name="businessInterface" value="com.formacion.ipartek.curso.CursoServiceRemote" />
</bean>
<bean id="cursoServiceImp" class="com.ipartek.formacion.service.CursoServiceImp">
    property name="cursoServiceRemote" ref="cursoServiceRemote" />
</bean>

Please help.


Answer:

Though jdni:jee I was able to inject the EJB bean into Spring.

<jee:jndi-lookup id="cursoServiceRemote" jndi-name="java:app/gestion-docente-ejb/CursoServiceBean" />

<bean id="cursoServiceImp" class="com.ipartek.formacion.service.CursoServiceImp">
    <property name="cursoServiceRemote" ref="cursoServiceRemote" />
</bean>

Question:

I want to inject the entityManager from Hibernate on an Hibernate Interceptor Class. I'm using EJBs and JBoss. The transaction is JTA and the provider is the org.hibernate.ejb.HibernatePersistence.

I tried to do it like that:

@Stateless(name = "HistoricInterceptor")
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class HistoricInterceptorImpl extends EmptyInterceptor implements HistoricInterceptor {

@PersistenceContext(name = "windi")
private EntityManager em;

// overriden methods, etc

}

But the reference to entityManager is always null.

Is this behaviour expected? How can I access an entityManager from within an Interceptor class?


Answer:

I had given up on that exact solution. Instead, I've created another class that has the EJB Annotations. The interceptor will call that EJB by using a provider class that lookup up EJB classes on the context of the application. There, the entityManager is correctly associated.

Question:

I have an Exception Interceptor that works like this:

public class ExceptionInterceptor
{
    @AroundInvoke
    public Object exceptionHandler(InvocationContext ctx) throws Exception
    {
        try {
            return ctx.proceed();
        } catch (RuntimeException re) {
            // Log Exception Here

            throw re;
        }
    }
}

Is there a way to inject a LogManagerBean so I can do something like this:

public class ExceptionInterceptor
{
    @EJB
    LogManagerBean logManager;

    @AroundInvoke
    public Object exceptionHandler(InvocationContext ctx) throws Exception
    {
        try {
            return ctx.proceed();
        } catch (RuntimeException re) {
            // Log Exception Here
            logManager.error(re);

            throw re;
        }
    }
}

The LogManagerBean is marked @Stateless and @LocalBean.


Answer:

I think it's possible. As in the case of other interceptors. Interceptors is created at the same time as the EJB instance is created, and dependency is injected before calling the first method of EJB.

Question:

I am developing a JavaEE application using EJB container and EJB.

Suppose I have class Student:

class Student{
 private int id;

 private String resume;

 public void clearXss(){
  ///some logic to clear resume from js scripts
 }
}

I have a standalone client and JavaEE server. Client conntects via RMI to EJB container. Client passes objects of Student class.

My question: is it safe to call clearXss on the object method, or it's necessary do an external method? I mean:

class MyBean{
 private void save(Student student){...}

 public void saveStudent(Student student){
  sudent.clearXss();
  save(student);
 }
}

vs

class MyBean{
 private void save(Student student){...}

 private String purifyXss(String string){...}

 public void saveStudent(Student student){
  student.setResume(purifyXss(student.getResume()))
  save(student);
 }
}

What I am afraid of is to call security methods of objects we get from untrusted client. That's why this is primary security question.


Answer:

It's not simple question. On one hand you are fair enough worried about code injection at server side. On other hand as far as I know in RMI technology client object will be serialized only class data without methods on client side and restored (deserialized) on server side with server version of the class, and then both variants are safe against method injection on server side.

Question:

I have a javax.sql.DataSource that I want to use in multiple servlets. I don't like the idea of specifying:

@Resource(name="live-connection", lookup="java:/live-connection", description="Live DB Connection")
private DataSource liveDataSource_;

in every servlet as it seems to me that the framework will have to be looking up the DataSource for every servlet and if the name of the DataSource changes, every servlet will have to change too.

My idea is to declare a Singleton EJB that can then be declared in each servlet:

@Startup
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class DataSources {  
    @Resource(name="live-connection", lookup="java:/live-connection", description="Live DB Connection")
    private DataSource liveDataSource_;

    public synchronized Connection getLiveConnection() throws SQLException {
        return liveDataSource_.getConnection();
    }
}

Is this a reasonable way of solving the issue? I feel it's a bit heavy handed for something I would have thought would be a common issue.


Answer:

In general it's ok IMO. But please don't let the bean return the connection but directly the DataSource. Some AppServers like WebSphere will automatically close the connection when the bean context is left again.

Another solution would be to use @Resource(name="myds") instead of lookup. If all your Servlets are in one Web Application then you can define one resource-ref with res-ref-name myds in your web.xml and resolve it to the real lookup name only at that place.

Question:

I am trying to upgrade to Glassfish 4 for an application that uses a combination of EJBs and Spring beans. This worked fine on Glassfish3.

When i try to deploy I get errors of this type:

org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type SomethingLogic with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject private com.my.application.server.service.SomethingServiceSession.somethingLogic

At first, I got these in non-spring beans when trying to @Inject a Spring bean (EJBs/webservices/servlets). After changing all @Inject's to @Autowired, the non-spring classes no longer give the error, but I start getting the same errors on the purely Spring beans (so @Inject of a Spring bean to another Spring bean gives the error.)

This leads me to believe that Glassfish will try to look for a EJB when encountering @Inject, no matter if it's in the context of EJB or not, and no matter if the bean to be injected is a EJB or a Spring bean.

Is this the case, and how do I avoid this?


Answer:

Managed to solve my problem, by adding bean-discovery-mode="none" to my various beans.xml files.