NoSuchElementException in test with Arquillian and embedded container
FuoriDiTesta opened this issue · 10 comments
Hi,
i'm trying to run a junit test of a Mybatis sample, with CDI injection, with arquillian and an embedded container (both TomEE and GlassFIsh).
THe sample seems not working, even if the logs show correct behavoir:
Aug 14, 2018 12:01:03 PM org.mybatis.cdi.MybatisExtension processAnnotatedType
INFO: MyBatis CDI Module - Found class with @Mapper-annotation: QueryMapper
Aug 14, 2018 12:01:03 PM org.mybatis.cdi.MybatisExtension processProducer
INFO: MyBatis CDI Module - SqlSessionFactory producer MybatisFactoryProducers.buildFactory
Aug 14, 2018 12:01:03 PM org.mybatis.cdi.MybatisExtension afterBeanDiscovery
INFO: MyBatis CDI Module - Activated
Aug 14, 2018 12:01:03 PM org.mybatis.cdi.MybatisExtension afterBeanDiscovery
INFO: MyBatis CDI Module - Found a bean, which needs a Mapper interface org.example.code.impl.QueryMapper
Aug 14, 2018 12:01:03 PM org.mybatis.cdi.MybatisExtension afterBeanDiscovery
INFO: MyBatis CDI Module - Managed Mapper dependency: org.example.code.impl.QueryMapper, org.example.code.impl.QueryMapper
Aug 14, 2018 12:01:03 PM org.mybatis.cdi.MybatisExtension afterBeanDiscovery
INFO: MyBatis CDI Module - Managed SqlSession: org.apache.ibatis.session.SqlSession, org.apache.ibatis.session.SqlSession
Aug 14, 2018 12:01:03 PM org.apache.webbeans.config.BeansDeployer validateInjectionPoints
Caused by: java.util.NoSuchElementException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1455)
at java.util.HashMap$KeyIterator.next(HashMap.java:1477)
at org.mybatis.cdi.CDIUtils.getRegistry(CDIUtils.java:120)
at org.mybatis.cdi.SerializableMapperProxy.getMapper(SerializableMapperProxy.java:68)
at org.mybatis.cdi.SerializableMapperProxy.(SerializableMapperProxy.java:53)
at org.mybatis.cdi.MyBatisBean.create(MyBatisBean.java:127)
I prepare a sample that replicate the problem:
sample.zip
There is a possibity to resolve the problem and been able to use Mybatis + CDi even in an embedded container?
Thanks!
With weld, to be honest, no, but if i'm not wrong, Weld doesn't support EJB.... or i'm wrong?
@FuoriDiTesta I have downloaded your sample.zip project. unziped and run mvn test. It does not compile.
MybatisFactoryProducers.java:[6,29] package org.apache.derby.jdbc does not exist
So there is some problem in your configuration.
@FuoriDiTesta after I have fixed your derby dependecy, I tried:
mvn -P arquillian-jbossas-managed test ...... [No Errors]
mvn -P GlassFish test ................................... [No Errors]
mvn -P tomee-embedded test ........................ [No Errors]
So I will close this now. If you provide new evidence this can be reopened. But I recommend you to move to mybatis-cdi-1.1.0 anyway.
@FuoriDiTesta Ok, your sample zip is not running any test, I just figured it now, your class ArquillianMyBatisSample must be named ArquillianMyBatisSampleTest to be executed in tests.
- I fixed the class name and your reported exception appears.
- I have upgraded to mybatis-cdi-1.1.0 and the problem remains.
This requires further investigation.
@FuoriDiTesta, I am not an Arquillian user. Please provide more info/tests to help us encounter the problem. I suspect the problem is not in mybatis-cdi but in your configuration, but because I do not know Arquillian, I can be wrong. One possible test is to setup a project using tomcat embedded without Arquillian.
I have the same problem with Arquillian. I've traced the problem to how @Mapper is injected.
public static SqlSessionManagerRegistry getRegistry(CreationalContext creationalContext) {
final BeanManager beanManager = getBeanManager();
Iterator<Bean<?>> beans = beanManager.getBeans(SqlSessionManagerRegistry.class).iterator();
return (SqlSessionManagerRegistry) beanManager.getReference(beans.next(), SqlSessionManagerRegistry.class,
creationalContext);
}
SqlSessionManagerRegistry.class is not managed by CDI and the call to beanManager returns an empty iterator.
Injecting SqlSessionFactory seems to work. So a work around to this problem is to call sqlSessionFactory.openSession().getMapper( ) to instantiate your DAO class.
SqlSessionManagerRegistry.class is not managed by CDI and the call to beanManager returns an empty iterator.
SqlSessionManagerRegistry actually IS a managed bean:
Few years later, trying to clean things up so I took the download which was a mess as noted here. I fixed the same issues but got it to work. Arquillian requires 'SqlSessionManagerRegistry.class' added or it will not load it. Once it loads it, it works fine with the test product. To save others work if they stumble on this, I have updated the sample project. It should work with simple 'mvn clean install' or however you like. It is tied to the snapshot of this project now though so I could confirm latest changes I've been doing don't break anything.
I'm going to add a note to readme specifically for arquillian as this was first I have ever used it and the issue was considerably hard to figure out.