Quarkus 和提供的依赖项 (sapjco3.jar)
Posted
技术标签:
【中文标题】Quarkus 和提供的依赖项 (sapjco3.jar)【英文标题】:Quarkus and provided dependencies (sapjco3.jar) 【发布时间】:2021-03-08 05:51:57 【问题描述】:我目前尝试将通过 RFC 连接到 SAP 系统的旧 Java EE 解决方案迁移到使用 Quarkus 的方法。 由于该项目使用 maven,我再次面临 SAP 的 sapjco3.jar 库的问题,该问题阻止了该库被重命名。 如果我像这样将库添加为依赖项
<dependency>
<groupId>com.sap</groupId>
<artifactId>sapjco3</artifactId>
<version>3.1</version>
</dependency>
它将被添加到名为 com.sap.sapjco3-3.1.jar 的 lib 目录中。 不幸的是,这最终导致了异常
java.lang.ExceptionInInitializerError:JCo 初始化失败,出现 java.lang.ExceptionInInitializerError:非法 JCo 存档“com.sap.sapjco3-3.1.jar”。不允许重命名或重新打包原始存档“sapjco3.jar”。
*** 上已经有一些文章描述了该问题,并且还有一个 SAP 说明:https://apps.support.sap.com/sap/support/knowledge/en/2182414
所以我用“旧”方法解决了这个问题,将依赖项设置为提供并使用 maven-dependency-plugin 复制它。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>process-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>sapjco3</includeArtifactIds>
<outputDirectory>$project.build.directory/lib</outputDirectory>
<stripVersion>true</stripVersion>
</configuration>
</execution>
</executions>
</plugin>
不幸的是,这不适用于 quarkus。 如果我使用,正在开发中
mvn quarkus:dev
提供的似乎被忽略了,我仍然收到消息。
JCo 初始化失败,出现 java.lang.ExceptionInInitializerError:非法 JCo 存档“sapjco3-3.1.jar”。不允许重命名或重新打包原始存档“sapjco3.jar”。
如果我打包并尝试将其部署到 docker-container
mvn clean package
如果我将副本更改为 pom.xml 中的另一个阶段,它基本上可以将 jar 文件复制到 lib 目录
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
但我首先收到构建警告:
[警告] [io.quarkus.arc.processor.BeanArchives] 无法索引 com.sap.conn.jco.ext.DestinationDataProvider:ClassLoader 中不存在类 QuarkusClassLoader:部署类加载器
[INFO] [io.quarkus.arc.processor.IndexClassLookupUtils] 在 Jandex 索引中找不到名称的类:com.sap.conn.jco.ext.DestinationDataProvider。请确保该类是索引的一部分。
后来出现以下错误:
java.lang.NoClassDefFoundError: com/sap/conn/jco/ext/DestinationDataProvider
Quarkus 是否有解决方案来处理提供的依赖项并使用 maven 手动复制它们?
【问题讨论】:
【参考方案1】:我在一个项目中使用了与 Quarkus 一起使用的 SAP 库。该解决方案并非特定于 Quarkus(Spring Boot 项目使用相同的解决方案)。
首先,使用系统 scome 定义库,使其名称不会被修改。
<dependency>
<groupId>com.sap</groupId>
<artifactId>sapjco3</artifactId>
<version>3.1</version>
<scope>system</scope>
<systemPath>$project.build.directory/dependency/sapjco3.jar</systemPath>
</dependency>
然后,配置maven-dependency-plugin
,在初始化阶段复制此路径下的库,并将其包含在最终包中。它还包含 sapjco3.jar 库使用的本机库的配置。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>copy-jco-libs-unit-tests</id>
<phase>initialize</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<stripVersion>true</stripVersion>
<outputDirectory>$lib.directory</outputDirectory>
<artifactItems>
<artifactItem>
<groupId>com.sap.conn.jco</groupId>
<artifactId>sapjco3</artifactId>
<version>$sap.jco.version</version>
<overWrite>true</overWrite>
<destFileName>sapjco3.jar</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
<execution>
<id>copy-native-lib-for-unit-tests</id>
<phase>process-sources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<stripVersion>true</stripVersion>
<outputDirectory>$native.lib.directory</outputDirectory>
<artifactItems>
<artifactItem>
<groupId>com.sap.conn.jco</groupId>
<artifactId>sapjco3</artifactId>
<version>$sap.jco.version</version>
<type>$envType</type>
<classifier>$envClassifier</classifier>
<overWrite>true</overWrite>
<destFileName>$native.lib.filename.$envType</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
最后,通过配置文件配置应包含的本机库,需要一个按 OS/CPU 架构的配置文件。这是配置:
<profiles>
<!-- Manage JCO native deps by OS arch -->
<profile>
<id>windows-x86_64</id>
<activation>
<os>
<family>windows</family>
<arch>x86_64</arch>
</os>
</activation>
<properties>
<envClassifier>ntamd64</envClassifier>
<envType>dll</envType>
<native.lib.filename>sapjco3</native.lib.filename>
</properties>
</profile>
<profile>
<id>windows-amd64</id>
<activation>
<os>
<family>windows</family>
<arch>amd64</arch>
</os>
</activation>
<properties>
<envClassifier>ntamd64</envClassifier>
<envType>dll</envType>
<native.lib.filename>sapjco3</native.lib.filename>
</properties>
</profile>
<profile>
<id>linux-x86_64</id>
<activation>
<os>
<name>linux</name>
<arch>x86_64</arch>
</os>
</activation>
<properties>
<envClassifier>linuxx86_64</envClassifier>
<envType>so</envType>
<native.lib.filename>libsapjco3</native.lib.filename>
</properties>
</profile>
<profile>
<id>linux-amd64</id>
<activation>
<os>
<name>linux</name>
<arch>amd64</arch>
</os>
</activation>
<properties>
<envClassifier>linuxx86_64</envClassifier>
<envType>so</envType>
<native.lib.filename>libsapjco3</native.lib.filename>
</properties>
</profile>
<profile>
<id>macosx-x86_64</id>
<activation>
<os>
<name>mac os x</name>
<arch>x86_64</arch>
</os>
</activation>
<properties>
<envClassifier>darwinintel64</envClassifier>
<envType>dylib</envType>
<native.lib.filename>libsapjco3</native.lib.filename>
</properties>
</profile>
<profile>
<id>macosx-amd64</id>
<activation>
<os>
<name>mac os x</name>
<arch>amd64</arch>
</os>
</activation>
<properties>
<envClassifier>darwinintel64</envClassifier>
<envType>dylib</envType>
<native.lib.filename>libsapjco3</native.lib.filename>
</properties>
</profile>
有了这一切,测试工作,mvn quarkus:dev
工作,并且用 mvn clean package
完成的包工作。
注意 Maven 的初始化阶段默认不会启动,您需要调用一次mvn initialize
才能进行库复制。
【讨论】:
这对mvn quarkus:dev
非常有效。不幸的是mvn package
在复制到 target/lib 文件夹时仍然添加 com.sap.sapjco3.jar。我也会尝试为最后一个问题找到解决方案。
应该不是这样,你之前有没有跑过mvn clean
?
因为有一个 systemPath 并且 lib 范围是 system 它不会在打包时下载 lib 并使用系统路径中的那个所以它不会被重命名。
是的,我做了一个 mvn clean。尽管如此,我还是被 maven 强制进行本地安装 mvn install:install-file -DgroupId="com.sap" -DartifactId=sapjco3 -Dversion="3.1" -Dpackaging=jar -Dfile="target/dependency/sapjco3.jar"
,我猜即使在系统范围内,它也是从该本地存储库下载而不是?
使用建议的设置,使用mvn clean
,然后使用mvn initialize
,然后使用mvn quarkus:dev
,最后使用mvn package
。 sapjco3.jar 库在我的公司 Maven 存储库中,因此 maven 下载它,然后将其放入配置的 systemPath 中而不修改其名称。【参考方案2】:
我们一直在努力解决 sapjco3.jar 的命名问题,直到我偶然发现此链接上的脚注:https://help.mulesoft.com/s/article/It-is-not-allowed-to-rename-or-repackage-the-original-archive-sapjco3-jar
将您的工件命名为com.sap.conn.jco.sapjco3.jar
,它将解决命名问题,因为即使添加了版本号,驱动程序也会接受此名称。
不过,您的下一个绊脚石将是本机库......我在 quarkus 环境中没有针对该部分的解决方案,因为我还没有尝试过。
【讨论】:
以上是关于Quarkus 和提供的依赖项 (sapjco3.jar)的主要内容,如果未能解决你的问题,请参考以下文章
通过JAVA连接SAP (sapjco3.jar在Windows和MacOS上的配置)
未找到功能性渠道服务提供者。尝试添加对 grpc-okhttp、grpc-netty 或 grpc-netty-shaded 工件的依赖项