Skip to content

typeHandlersPackage scanning not working when custom TypeHandler is in other (nested) jar than the SqlSessionFactoryBean definition #325

Closed
@michalaron

Description

@michalaron

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

michalaron commented on Jan 5, 2015

@michalaron
Author

We are using version 3.2.8

s17t

s17t commented on Jan 9, 2015

@s17t

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

harawata commented on Apr 5, 2015

@harawata
Member

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

making commented on May 19, 2015

@making

👍

added a commit that references this issue on Jun 25, 2015
harawata

harawata commented on Jun 26, 2015

@harawata
Member

@kazuki43zoo
Thank you very much for your time! I will look into it.

added 2 commits that reference this issue on Aug 18, 2015

#325 Added vfsImpl setting to make VFS implementation configurable.

#325 Added documentation for vfsImpl.

harawata

harawata commented on Aug 18, 2015

@harawata
Member

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.

<settings>
  <setting name="vfsImpl" value="com.mydomain.vfs.SpringBootExecutableJarVFS" />
</settings>

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).

added this to the 3.4.0 milestone on Aug 18, 2015

16 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementImprove a feature or add a new feature

Type

No type

Projects

No projects

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @making@harawata@s17t@julnamoo@kazuki43zoo

      Issue actions

        typeHandlersPackage scanning not working when custom TypeHandler is in other (nested) jar than the SqlSessionFactoryBean definition · Issue #325 · mybatis/mybatis-3