将Spring Boot应用程序迁移到Java 9-模块

上周,我试图制作一个Spring Boot应用程序 -与Java 9兼容的著名Pet Clinic。 这并不容易。 一路上我不得不放弃很多功能。 总而言之,我得到的唯一好处是改进了字符串内存管理。

本周,我想通过全面拥抱Java 9模块系统来继续进行迁移。

配置模块元数据

Java 9中的模块信息是通过module-info.java文件实现的。 第一步是在源目录的根目录下使用模块名称创建一个这样的文件:

moduleorg.springframework.samples.petclinic{
}

其余的旅程可以是天堂或地狱。 我很幸运从IntelliJ IDEA许可证中受益。 IDE会准确告知它无法读取的类,并使用向导将其放入模块文件中。 最后,它看起来像这样:

moduleorg.springframework.samples.petclinic{
    requiresjava.xml.bind;
    requiresjavax.transaction.api;
    requiresvalidation.api;
    requireshibernate.jpa;
    requireshibernate.validator;
    requiresspring.beans;
    requiresspring.core;
    requiresspring.context;
    requiresspring.tx;
    requiresspring.web;
    requiresspring.webmvc;
    requiresspring.data.commons;
    requiresspring.data.jpa;
    requiresspring.boot;
    requiresspring.boot.autoconfigure;
    requirescache.api;
}

请注意,可以删除maven-compiler-pluginmaven-surefire-plugin中的模块配置。

无辅助配置

如果您碰巧处于不太理想的环境中,则过程如下:

  1. 运行mvn clean test
  2. 分析日志中的错误以获取违规软件包
  3. 找到所述程序包的JAR
  4. 如果JAR是模块,则将模块名称添加到所需模块列表中
  5. 如果不是,请计算自动模块名称,并将其添加到需求模块列表中

例如:

[ERROR] ~/spring-petclinic/src/main/java/org/springframework/samples/petclinic/system/CacheConfig.java:[21,16]
  package javax.cache is not visible
[ERROR]   (package javax.cache is declared in the unnamed module, but module javax.cache does not read it)

javax.cache位于cache-api-1.0.0.jar 。 它不是模块,因为JAR中没有module-info 。 自动模块名称为cache.api 。 根据requires将其写入模块中。 冲洗并重复。

ASM故障

从本文的第一部分开始,我就意识到Spring Boot 1.5不会兼容Java 9。 我们开始做吧。

将Spring Boot升级到2.0.0.M5需要对模块依赖项进行一些更改:

  • hibernate.validatororg.hibernate.validator
  • validation.apijava.validation

当您认为它可能会起作用时:

Caused by: java.lang.RuntimeException
    at org.springframework.asm.ClassVisitor.visitModule(ClassVisitor.java:148)

此问题已被记录 。 此时,显式声明主类可以解决此问题。

<plugin>
    <groupId> org.springframework.boot </groupId>
    <artifactId> spring-boot-maven-plugin </artifactId>
    <configuration>
        <jvmArguments> --add-modules java.xml.bind </jvmArguments>
        <mainClass> org.springframework.samples.petclinic.PetClinicApplication </mainClass>
    </configuration>
    ...
</plugin>

Javassist失败

现在可以使用mvn clean spring-boot:run测试该应用程序了。 不幸的是,我们的方式出现了一个新的例外:

2017-10-16 17:20:22.552  INFO 45661 --- [           main] utoConfigurationReportLoggingInitializer :

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-10-16 17:20:22.561 ERROR 45661 --- [           main] o.s.boot.SpringApplication               :
 Application startup failed

org.springframework.beans.factory.BeanCreationException:
  Error creating bean with name 'entityManagerFactory' defined in class path resource
   [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]:
    Invocation of init method failed; nested exception is org.hibernate.boot.archive.spi.ArchiveException:
     Could not build ClassFile

快速搜索将重定向到Java 9与Javassist之间的不兼容性 。 Javassist是这里的元凶。 通过Hibernate可传递地需要Spring Data JPA依赖项。 要解决此问题,请排除依赖项,然后添加最新版本:

<dependency>
    <groupId> org.springframework.boot </groupId>
    <artifactId> spring-boot-starter-data-jpa </artifactId>
    <exclusions>
        <exclusion>
            <artifactId> javassist </artifactId>
            <groupId> org.javassist </groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId> org.javassist </groupId>
    <artifactId> javassist </artifactId>
    <version> 3.22.0-GA </version>
    <scope> runtime </scope>
</dependency>

幸运的是,版本是兼容的-至少对于我们的用法而言是兼容的。

有用!

我们做到了! 如果到达这一点,您应该轻拍肩膀,啤酒或其他您认为应得的东西。

锦上添花,可以重新添加Dev Tools依赖项。

结论

迁移到Java 9需要使用Jigsaw,无论您是否喜欢。 至少,这意味着痛苦的尝试和错误搜索下一个修复过程, 删除了构建过程中的重要步骤。 对于库/框架开发人员来说,在其内部API中增加访问控制层很有趣,但对于应用程序而言则要少得多。 在此阶段,不值得转向Java 9。

我希望在几个月后再次进行这项实验,并注意到情况有所改善。

这篇文章的完整源代码可以在Github上找到。

翻译自: https://blog.frankel.ch/migrating-to-java-9/2/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值