Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CDI @Inject does not work properly in EAR using MyBatis #1688

Closed
zappee opened this issue Jun 18, 2017 · 6 comments
Closed

CDI @Inject does not work properly in EAR using MyBatis #1688

zappee opened this issue Jun 18, 2017 · 6 comments
Assignees

Comments

@zappee
Copy link

zappee commented Jun 18, 2017

CDI @Inject does not work properly in EAR


I have an EAR application which contains an EJB and WAR. EJB module reads data from database with MyBatis + MyBatis-CDI, WAR modules uses EJB. I did not do anything special in my code but it seems that CDI does does not work properly, mybatis-cdi throws an exception.

My first idea was there is a bug in mybatis-cdi so I have opened a bug ticket on mybatis-cdi. The guys there checked my issue and they pointed out that my ear works on Wildfly 10 without any issue. After that I also deployed my demo EAR application to Wildfly and I could see that it works properly. But I get CDI injection exception when I use Payara. I tried it on Glassfish 4.1.2 and I got the same exception.

I have created two projects to demonstrate the issue and they are uploaded to git.

  1. WEB application (https://github.com/zappee/mybatis-web-demo)
    Simple war inside an ear.
    It works like a charm.

  2. EE application (https://github.com/zappee/mybatis-ee-demo)
    The ear contains a common jar, a stateless ejb and a war file.
    EJB calls MyBatis stuff.
    WAR uses EJB.

In the 2nd scenario/structure CDI does not work properly. As I mentioned same ear works on Wildfly without any modification.

Please read this bug report on mybatis-cdi git.

Expected Outcome

No exception when calling my servlet's url in web browser.

Current Outcome

Caused by: javax.ejb.CreateException: Could not create stateless EJB
	at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:527)
	at com.sun.ejb.containers.StatelessSessionContainer.access$000(StatelessSessionContainer.java:101)
	at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:711)
	... 38 more
Caused by: org.mybatis.cdi.MybatisCdiConfigurationException: There are no SqlSessionFactory producers properly configured.

You can see the full exception here.

Steps to reproduce (Only for bug reports)

Checkout the my demo code from here, build it with maven and deploy the ear to Payara. Then open http://localhost:8080/ee-demo-web/email.

Environment

  • Payara Version: 4.1.2.172 / 4.1.1.171.1
  • Edition: Full
  • JDK Version: 1.8.0_131
  • Operating System: Linux / Ubuntu
  • Database: PostgreSQL
@smillidge
Copy link
Contributor

smillidge commented Jun 19, 2017

This is pretty deep with MyBatis CDI code. Can you demonstrate the issue you believe is happening in a simple test case without MyBatis?

@smillidge smillidge changed the title CDI @Inject does not work properly in EAR CDI @Inject does not work properly in EAR using MyBatis Jun 19, 2017
@smillidge
Copy link
Contributor

One other thing have you tried with JavaEE7 beans.xml?

<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"
       version="1.1" bean-discovery-mode="all">
</beans>

@zappee
Copy link
Author

zappee commented Jun 19, 2017

I got the same exception with JavaEE7 beans.xml.

This issue is only related to mybatis-cdi and I am not able to reproduce the exception without mybatis.

@OndroMih
Copy link
Contributor

It seems that the CDI container isn't able to find beans defined in the EJB JAR when doing injection in the WAR module. It works in WildFly because it bridges all bean managers from all modules into the same space, so the appear to be the same CDI module. It's described in this blog post about CDI in EARs.

The behavior of CDI in EARs isn't specified clearly, so there may be differences across servers. We need to check how Payara Server treats EJB JAR modules with respect to CDI, but I guess that beans in an EJB JAR aren't visible in other EJB or WAR modules. This isn't a bug, because the specification isn't clear about this, but we'll see if we can improve it to make more sense.

On the contrary, injection via @ejb works across all the EAR, so using it doesn't raise errors. What fails in that case is that MyBatis requests a SqlSessionFactory bean via the CDI mechanism, and it fails to load it, because it's again defined in the EJB JAR and requested from WAR.

To fix the problem, you should move all the CDI beans into a shared JAR, e.g. to commons or a new plain JAR. Then they would be visible in all modules in the EAR. You may leave your EJB in the EJB module, but it has to be injected using @ejb not using @Inject.

@lprimak lprimak self-assigned this Jul 6, 2017
@Quix0r
Copy link

Quix0r commented Jul 14, 2017

Note from my own experience:

  1. When I want to make calls from a backing bean (a.k.a. "web controller") to another one, I use @Inject.
  2. When I want to call an EJB's business method from an EJB, I currently use @EJB but maybe change it later to 3).
  3. When I want to call an EJB's business method from a backing bean (WAR project), I use InitialContext and lookup() and the super-long, but portable JNDI names (you can see them in the server.log file btw.).

And maybe this (payara) is not the right place for debugging MyBatis? ;-)

@zappee
Copy link
Author

zappee commented Jul 16, 2017

Sorry for the late reply. As @OndrejM suggested I moved mybatis related stuff to ear/lib/commons.jar and mybatis-cdi has been started to do its job. So it works now.

I updated my demo project on git as well: mybatis-ee-demo.

This is the structure of my EAR:

*.ear
  |- lib
  |    |- my-commons.jar
  |    |    |- @mapper interface
  |    |    |- SqlSessionFactory
  |    |
  |    |- mybatis-3.4.4.jar
  |    |- mybatis-cdi-1.0.0.jar
  |    |- ...
  |
  |- META-INF
  |   |- application.xml
  |    
  |- ejb.jar
  |    |- META-INF
  |    |    |- beans.xml
  |    |
  |    |- log4j.properties
  |    |- mybatis.xml
  |
  |- *.war
       |- WEB-INF
       |    |- beans.xml
       |    |- classes
       |    |- lib

@fturizo fturizo removed the 1:Wait label Feb 15, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants