在 Eclipse Equinox 中扩充遗留 OSGi 包的类路径
Augmenting the classpath of legacy OSGi bundles in Eclipse Equinox
我们正在尝试将现有的 Eclipse IDE 产品从 Java 8 迁移到 Java 11。
我们自己的代码一切正常;但不幸的是,该产品还包括一些来自第三方的(相当旧的)捆绑包。这些包已经构建并在 Java 8 下工作并使用 javax.xml.bind
(JAXB),我们无法访问源代码,因此我们无法为 Java 11 重建它们。
现在的问题是那些包假定 javax.xml.bind
在(Java 运行时库)类路径中(这对于 Java 8 是正确的),所以他们不在他们的清单中有一个 JAXB 的 Import-Package
。当在我们的新 Java 11 产品中执行时,当然,对于 JAXB 类.
,这将在 NoClassDefFoundException
中结束
到目前为止,我的研究得出了两种解决此问题的可能性:
将 JAXB 添加到 Java 类路径,方法是将其作为模块提供,并在 eclipse.ini
.[=18 中添加相应的 --add-modules
参数作为 VM 参数=]
对于每个遗留包,创建一个包含额外 Import-Package
header 的片段,以将 JAXB 导入添加到每个受影响的包。
第一个解决方案对我们来说效果不佳,因为我们自己的包已经在清单中使用 Import-Package
header 来利用 JAXB,它在我们的目标平台中作为 OSGi 可用捆。如果我们向 Java 添加一个 JAXB 模块,我们最终会遇到 classes/packages 在两个模块中可用的问题(OSGi 包中未命名的模块,以及我们通过命令行添加的 JAXB)。
第二个解决方案有效,但缺点是我们需要为 N 个遗留包创建 N 个片段,这增加了很多我们的代码库混乱。
所以我的问题是:Equinox 中是否有任何其他机制可用于制作某些包(我们的遗留包)的 BundleClassloader 已知的某些包 (JAXB) without 必须修改或重建这些遗留包?
捆绑包应始终导入 javax.*
个包。那些包总是错的。
您尝试过 boot delegation 并将 JAXB 添加到 Java 类路径吗?
org.osgi.framework.bootdelegation=javax.xml.bind,javax.xml.bind.*
如果已经有一个 bootdelegation 值,您需要将 javax.xml.bind,javax.xml.bind.*
添加到现有值。
由于您还有导入 javax.xml.bind
包的包,因此您还需要确保系统包导出它们。因此,您将需要配置 org.osgi.framework.system.packages.extra
属性 所有 JAXB 包,包括导入所需的版本。
org.osgi.framework.system.packages.extra=javax.xml.bind;version=1.2.3, ...
在搜索 BJ Hargrave's , we ended up finding this blog entry on vogella by Dirk Fauth 中给出的关键字后。该文章中的变体 3 描述了我们成功应用的方式。
简而言之,
- 为
system.bundle
创建片段并将其设置为 framework
扩展
- 将您需要的库放在该片段的 class 路径上(或配置 POM 让 Maven 为您完成)
- 导出你需要导出的包
MANIFEST.MF
片段(节选):
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: JAXB framework extension
Bundle-SymbolicName: net.winklerweb.jaxbfix
Bundle-Version: 1.0.0.qualifier
Fragment-Host: system.bundle; extension:=framework
Bundle-RequiredExecutionEnvironment: JavaSE-11
Bundle-ClassPath: lib/jakarta.activation-api-1.2.2.jar,
lib/jakarta.xml.bind-api-2.3.3.jar,
lib/jaxb-impl-2.2_1.jar,
.
Export-Package: com.sun.istack,
com.sun.istack.localization,
com.sun.istack.logging,
pom.xml
片段(节选):
<modelVersion>4.0.0</modelVersion>
<groupId>net.winklerweb</groupId>
<artifactId>net.winklerweb.jaxbfix</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>initialize</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<excludeTransitive>false</excludeTransitive>
<includeArtifactIds>jakarta.activation-api,jakarta.xml.bind-api,jaxb-impl</includeArtifactIds>
<failOnMissingClassifierArtifact>false</failOnMissingClassifierArtifact>
<silent>false</silent>
<outputDirectory>lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<versionRange>[1.0.0,)</versionRange>
<goals>
<goal>copy-dependencies</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>true</runOnIncremental>
<runOnConfiguration>true</runOnConfiguration>
</execute>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>jakarta.activation</groupId>
<artifactId>jakarta.activation-api</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.bundles</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2_1</version>
</dependency>
</dependencies>
最后,一些有用的链接解释了我在研究过程中遇到的 OSGi/Equinox class 加载:
我们正在尝试将现有的 Eclipse IDE 产品从 Java 8 迁移到 Java 11。
我们自己的代码一切正常;但不幸的是,该产品还包括一些来自第三方的(相当旧的)捆绑包。这些包已经构建并在 Java 8 下工作并使用 javax.xml.bind
(JAXB),我们无法访问源代码,因此我们无法为 Java 11 重建它们。
现在的问题是那些包假定 javax.xml.bind
在(Java 运行时库)类路径中(这对于 Java 8 是正确的),所以他们不在他们的清单中有一个 JAXB 的 Import-Package
。当在我们的新 Java 11 产品中执行时,当然,对于 JAXB 类.
NoClassDefFoundException
中结束
到目前为止,我的研究得出了两种解决此问题的可能性:
将 JAXB 添加到 Java 类路径,方法是将其作为模块提供,并在
eclipse.ini
.[=18 中添加相应的--add-modules
参数作为 VM 参数=]对于每个遗留包,创建一个包含额外
Import-Package
header 的片段,以将 JAXB 导入添加到每个受影响的包。
第一个解决方案对我们来说效果不佳,因为我们自己的包已经在清单中使用 Import-Package
header 来利用 JAXB,它在我们的目标平台中作为 OSGi 可用捆。如果我们向 Java 添加一个 JAXB 模块,我们最终会遇到 classes/packages 在两个模块中可用的问题(OSGi 包中未命名的模块,以及我们通过命令行添加的 JAXB)。
第二个解决方案有效,但缺点是我们需要为 N 个遗留包创建 N 个片段,这增加了很多我们的代码库混乱。
所以我的问题是:Equinox 中是否有任何其他机制可用于制作某些包(我们的遗留包)的 BundleClassloader 已知的某些包 (JAXB) without 必须修改或重建这些遗留包?
捆绑包应始终导入 javax.*
个包。那些包总是错的。
您尝试过 boot delegation 并将 JAXB 添加到 Java 类路径吗?
org.osgi.framework.bootdelegation=javax.xml.bind,javax.xml.bind.*
如果已经有一个 bootdelegation 值,您需要将 javax.xml.bind,javax.xml.bind.*
添加到现有值。
由于您还有导入 javax.xml.bind
包的包,因此您还需要确保系统包导出它们。因此,您将需要配置 org.osgi.framework.system.packages.extra
属性 所有 JAXB 包,包括导入所需的版本。
org.osgi.framework.system.packages.extra=javax.xml.bind;version=1.2.3, ...
在搜索 BJ Hargrave's
简而言之,
- 为
system.bundle
创建片段并将其设置为framework
扩展 - 将您需要的库放在该片段的 class 路径上(或配置 POM 让 Maven 为您完成)
- 导出你需要导出的包
MANIFEST.MF
片段(节选):
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: JAXB framework extension
Bundle-SymbolicName: net.winklerweb.jaxbfix
Bundle-Version: 1.0.0.qualifier
Fragment-Host: system.bundle; extension:=framework
Bundle-RequiredExecutionEnvironment: JavaSE-11
Bundle-ClassPath: lib/jakarta.activation-api-1.2.2.jar,
lib/jakarta.xml.bind-api-2.3.3.jar,
lib/jaxb-impl-2.2_1.jar,
.
Export-Package: com.sun.istack,
com.sun.istack.localization,
com.sun.istack.logging,
pom.xml
片段(节选):
<modelVersion>4.0.0</modelVersion>
<groupId>net.winklerweb</groupId>
<artifactId>net.winklerweb.jaxbfix</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>initialize</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<excludeTransitive>false</excludeTransitive>
<includeArtifactIds>jakarta.activation-api,jakarta.xml.bind-api,jaxb-impl</includeArtifactIds>
<failOnMissingClassifierArtifact>false</failOnMissingClassifierArtifact>
<silent>false</silent>
<outputDirectory>lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<versionRange>[1.0.0,)</versionRange>
<goals>
<goal>copy-dependencies</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>true</runOnIncremental>
<runOnConfiguration>true</runOnConfiguration>
</execute>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>jakarta.activation</groupId>
<artifactId>jakarta.activation-api</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.bundles</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2_1</version>
</dependency>
</dependencies>
最后,一些有用的链接解释了我在研究过程中遇到的 OSGi/Equinox class 加载: