Description
We have a multi-module project with the following structure:
batch.jar (created using Spring boot)
--persistenceContext.xml (containing definition SqlSessionFactoryBean - see bellow)
--package1/package2/Mapper1.xml (specific mapper for batch module)
--package1/package2/Mapper1.java (specific mapper for batch module)
--lib/persistence-module.jar
--lib/persistence-module.jar/package3/package4/Mapper2.xml (common mapper re-used by multiple modules)
--lib/persistence-module.jar/package3/package4/Mapper2.java (common mapper re-used by multiple modules)
--lib/persistence-module.jar/package3/package5/typehandler/DateTimeHandler.java (common typehandler re-used by multiple modules)
relevant parts of the persistenceContext.xml (placed in the OUTER jar file):
<!-- define the SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="typeHandlersPackage" value="package3.package5.typehandler" />
</bean>
<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="package1.package2, package3.package4" />
</bean>
The mapper scanning works without any problems (even for the Mapper2, which is placed in the inner jar file).
But typehandler scanning does not work correctly - the custom type handler DateTimeHandler.java is not found by myBatis in this configuration. I think the problem is on line 202 in org.apache.ibatis.io.DefaultVFS.java:
url = new URL(url.getFile());
This causes the URL in the form of "jar:file:batch.jar!/lib/persistence-module.jar/package3/package5/typehandler" is transformed to "file:batch.jar!/lib/persistence-module.jar/package3/package5/typehandler" and Exception is thrown on attempt to read from this URL on line 288 (isJar method).
Workaround I had to use was to duplicate the DateTimeHandler.java and put it to the outer jar (batch.jar) as well + change the spring context so now the scanned type handler package is the one in the outer jar. But this solution is of course not ideal and I definitely consider this as a bug (especially because rest of the mybatis configuration - i.e. the mapper scanning is working normally even for the mappers placed in the INNER jar).
Also I think the "swallowing" of the Exception in DefaultVFS.isJar() without any logging is not very good and it took me some time debugging the sources before finding the cause of this problem (and obviously the comment "Failure to read the stream means this is not a JAR" is not correct).
Activity
michalaron commentedon Jan 5, 2015
We are using version 3.2.8
s17t commentedon Jan 9, 2015
I tried to upgrade from 3.2.3 to 3.2.8 and I have missing typehandler errors too. My project's structure is similar. I tried 3.2.7 and 3.2.4 also but same errors occurred.
I reverted back to 3.2.3 and now works.
harawata commentedon Apr 5, 2015
There seems to be no logical change in org.apache.ibatis.io.DefaultVFS since 3.2.3.
I'm not familiar with Spring Boot, could someone provide an example .jar or a project?
making commentedon May 19, 2015
👍
kazuki43zoo commentedon Jun 25, 2015
Hi @harawata,
I created a verifying application for this issue.
https://github.com/kazuki43zoo/spring-boot-mybatis-sample/tree/master
And workaround is ...
https://github.com/kazuki43zoo/spring-boot-mybatis-sample/tree/workaround
kazuki43zoo/spring-boot-mybatis-sample@adf9b24
workaround mybatis/mybatis-3#325
harawata commentedon Jun 26, 2015
@kazuki43zoo
Thank you very much for your time! I will look into it.
#325 Added vfsImpl setting to make VFS implementation configurable.
#325 Added documentation for vfsImpl.
harawata commentedon Aug 18, 2015
According to the Spring Boot documentation, Java does not provide any standard way to load nested jar files and Spring Boot uses its own mechanism for it.
As these application server specific behavior should be handled with a custom VFS implementation, I have added a new setting 'vfsImpl' to make the VFS implementation configurable.
This change should be available in the latest 3.4.0-SNAPSHOT.
I also sent a PR to Kazuki's repo as a demo of this fix.
Comments are welcome.
To @s17t
As the issue reported here is reproducible with MyBatis 3.2.3 as well, it may be different from your problem.
I suggest you to open a new ticket with the details (attaching a demo project would be helpful).
16 remaining items