我可以将第三方 jar 放在 karaf(任何特定文件夹)中以解决传递依赖关系吗?
Can i place third party jars in karaf (any specific folder) to resolve transitive dependencies?
我有各种依赖第三方库的自制项目。
我将它们捆绑到 OSGI 容器中,但无法解决我项目中的深度依赖关系。
现在我正在寻找 karaf 文件夹,我可以在其中放置我的库,以便捆绑包可以直接访问它们而不是安装它们。
此外,我也在使用 maven。
编辑:
遵循您的 'feature' 解决方案后,我能够生成包含传递依赖项的清单,但问题是现在它还寻找非常常见的 java 文件:例如:下面是相当大的依赖项列表:
bsh -- Cannot be resolved
com.fasterxml.jackson.annotation -- Cannot be resolved
com.fasterxml.jackson.core -- Cannot be resolved
com.fasterxml.jackson.databind -- Cannot be resolved
com.fasterxml.jackson.databind.annotation -- Cannot be resolved
com.fasterxml.jackson.databind.module -- Cannot be resolved
com.gargoylesoftware.htmlunit -- Cannot be resolved
com.gargoylesoftware.htmlunit.util -- Cannot be resolved
com.google.protobuf -- Cannot be resolved
com.ibm.uvm.tools -- Cannot be resolved
com.ibm.websphere.uow -- Cannot be resolved
com.ibm.wsspi.uow -- Cannot be resolved
com.jamonapi -- Cannot be resolved
com.jamonapi.utils -- Cannot be resolved
com.jayway.jsonpath -- Cannot be resolved
com.jcraft.jzlib -- Cannot be resolved
com.mysema.query.types -- Cannot be resolved
com.sun.javadoc -- Cannot be resolved and overwritten by Boot Delegation
com.sun.jdmk.comm -- Cannot be resolved and overwritten by Boot Delegation
com.sun.net.httpserver -- Cannot be resolved and overwritten by Boot Delegation
com.sun.tools.javadoc -- Cannot be resolved and overwritten by Boot Delegation
com.sun.xml.fastinfoset.sax -- Cannot be resolved and overwritten by Boot Delegation
com.sun.xml.fastinfoset.stax -- Cannot be resolved and overwritten by Boot Delegation
com.typesafe.config -- Cannot be resolved
groovy.lang -- Cannot be resolved
groovy.xml -- Cannot be resolved
javassist -- Cannot be resolved
javax.activation from org.apache.felix.framework (0)
javax.annotation from org.apache.felix.framework (0)
javax.crypto from org.apache.felix.framework (0)
javax.crypto.spec from org.apache.felix.framework (0)
javax.ejb -- Cannot be resolved
javax.el -- Cannot be resolved
javax.enterprise.concurrent -- Cannot be resolved
javax.enterprise.context -- Cannot be resolved
javax.enterprise.context.spi -- Cannot be resolved
javax.enterprise.event -- Cannot be resolved
javax.enterprise.inject -- Cannot be resolved
javax.enterprise.inject.spi -- Cannot be resolved
javax.enterprise.util -- Cannot be resolved
如果我对你的问题的理解正确,你想要构建你的工件但不包括第 3 方库。您是否尝试过设置您不想捆绑提供的第 3 方库?
例如
<dependency>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
<version>[1.0,]</version>
<scope>provided</scope>
</dependency>
回答您的问题:您可以将所有依赖包放入 $KARAF_HOME/deploy 文件夹中,Karaf 会为您部署它们。
然而,这不是很方便,因为它是一个手动过程,不是由 Maven 驱动的。相反,请查看 Karaf 的 feature repositories. You can use the Karaf maven plugin 概念,为您的包及其(传递)依赖项创建一个功能存储库。如果您需要将您的应用程序作为单个工件发布,您可以使用相同的插件创建一个 KAR 存档,它是一个 zip 文件,其中包含 self-contained 部署单元中的功能存储库和所需的依赖项。
首先将模板 feature.xml 文件放入 src/main/feature
:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.3.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.3.0 http://karaf.apache.org/xmlns/features/v1.3.0"
name="My feature">
<feature name="${project.artifactId}" version="${project.version}" description="Describe feature here">
<!-- Add "self" to the list of dependencies -->
<bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle>
</feature>
</features>
然后设置插件以根据您的 Maven 依赖项填充功能模板:
<plugin>
<groupId>org.apache.karaf.tooling</groupId>
<artifactId>karaf-maven-plugin</artifactId>
<configuration>
<includeTransitiveDependency>true</includeTransitiveDependency>
</configuration>
<executions>
<execution>
<id>generate-features-descriptor</id>
<goals>
<goal>features-generate-descriptor</goal>
</goals>
</execution>
</executions>
</plugin>
构建您的项目将在您的本地 Maven 存储库中创建一个额外的 Maven 工件和您的 bundle jar:xxx-features。xml
您可以使用 feature:repo-add
命令让本地 Karaf 知道您的功能存储库。然后使用 feature:install
命令添加您的功能。这将启动您的包及其所有声明的(传递的)Maven 依赖项。
编辑:
正如您在评论中提到的,您的某些(全部?)依赖项是纯 JAR,而不是 OSGi 包,可能您最好 embedding 将那些 non-OSGi 依赖项放入您自己的包中maven-bundle-plugin。但这可能非常乏味。大多数 non-OSGi JAR 都有包导入,这些导入要么在运行时根本不使用,要么在您的特定使用场景中不使用。为了避免将 OSGi 依赖项列表扩展到传递性 Maven 依赖项列表之外,您必须防止将那些“继承的”包添加到您自己的包的 MANIFEST 中的包导入列表中。例如,我有一个使用 httl 模板库的包,它又依赖于 Javassist。 OSGi 包也不是。因此,我同时嵌入并禁止导入在 httl 或 javassist 代码中声明但在运行时不需要的包:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Embed-Dependency>*;scope=compile|runtime;inline=false;artifactId=httl|javassist</Embed-Dependency>
<Embed-Transitive>false</Embed-Transitive>
<Import-Package>
!com.alibaba.*,
!com.thoughtworks.*,
!javassist.*,
!net.htmlparser.*,
!org.apache.commons.logging.*,
!org.codehaus.jackson.*,
!org.joda.convert.*,
!com.sun.jdi.*,
!javax.servlet.*,
*
</Import-Package>
</instructions>
</configuration>
</plugin>
我有各种依赖第三方库的自制项目。 我将它们捆绑到 OSGI 容器中,但无法解决我项目中的深度依赖关系。 现在我正在寻找 karaf 文件夹,我可以在其中放置我的库,以便捆绑包可以直接访问它们而不是安装它们。
此外,我也在使用 maven。
编辑: 遵循您的 'feature' 解决方案后,我能够生成包含传递依赖项的清单,但问题是现在它还寻找非常常见的 java 文件:例如:下面是相当大的依赖项列表:
bsh -- Cannot be resolved
com.fasterxml.jackson.annotation -- Cannot be resolved
com.fasterxml.jackson.core -- Cannot be resolved
com.fasterxml.jackson.databind -- Cannot be resolved
com.fasterxml.jackson.databind.annotation -- Cannot be resolved
com.fasterxml.jackson.databind.module -- Cannot be resolved
com.gargoylesoftware.htmlunit -- Cannot be resolved
com.gargoylesoftware.htmlunit.util -- Cannot be resolved
com.google.protobuf -- Cannot be resolved
com.ibm.uvm.tools -- Cannot be resolved
com.ibm.websphere.uow -- Cannot be resolved
com.ibm.wsspi.uow -- Cannot be resolved
com.jamonapi -- Cannot be resolved
com.jamonapi.utils -- Cannot be resolved
com.jayway.jsonpath -- Cannot be resolved
com.jcraft.jzlib -- Cannot be resolved
com.mysema.query.types -- Cannot be resolved
com.sun.javadoc -- Cannot be resolved and overwritten by Boot Delegation
com.sun.jdmk.comm -- Cannot be resolved and overwritten by Boot Delegation
com.sun.net.httpserver -- Cannot be resolved and overwritten by Boot Delegation
com.sun.tools.javadoc -- Cannot be resolved and overwritten by Boot Delegation
com.sun.xml.fastinfoset.sax -- Cannot be resolved and overwritten by Boot Delegation
com.sun.xml.fastinfoset.stax -- Cannot be resolved and overwritten by Boot Delegation
com.typesafe.config -- Cannot be resolved
groovy.lang -- Cannot be resolved
groovy.xml -- Cannot be resolved
javassist -- Cannot be resolved
javax.activation from org.apache.felix.framework (0)
javax.annotation from org.apache.felix.framework (0)
javax.crypto from org.apache.felix.framework (0)
javax.crypto.spec from org.apache.felix.framework (0)
javax.ejb -- Cannot be resolved
javax.el -- Cannot be resolved
javax.enterprise.concurrent -- Cannot be resolved
javax.enterprise.context -- Cannot be resolved
javax.enterprise.context.spi -- Cannot be resolved
javax.enterprise.event -- Cannot be resolved
javax.enterprise.inject -- Cannot be resolved
javax.enterprise.inject.spi -- Cannot be resolved
javax.enterprise.util -- Cannot be resolved
如果我对你的问题的理解正确,你想要构建你的工件但不包括第 3 方库。您是否尝试过设置您不想捆绑提供的第 3 方库?
例如
<dependency>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
<version>[1.0,]</version>
<scope>provided</scope>
</dependency>
回答您的问题:您可以将所有依赖包放入 $KARAF_HOME/deploy 文件夹中,Karaf 会为您部署它们。
然而,这不是很方便,因为它是一个手动过程,不是由 Maven 驱动的。相反,请查看 Karaf 的 feature repositories. You can use the Karaf maven plugin 概念,为您的包及其(传递)依赖项创建一个功能存储库。如果您需要将您的应用程序作为单个工件发布,您可以使用相同的插件创建一个 KAR 存档,它是一个 zip 文件,其中包含 self-contained 部署单元中的功能存储库和所需的依赖项。
首先将模板 feature.xml 文件放入 src/main/feature
:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.3.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.3.0 http://karaf.apache.org/xmlns/features/v1.3.0"
name="My feature">
<feature name="${project.artifactId}" version="${project.version}" description="Describe feature here">
<!-- Add "self" to the list of dependencies -->
<bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle>
</feature>
</features>
然后设置插件以根据您的 Maven 依赖项填充功能模板:
<plugin>
<groupId>org.apache.karaf.tooling</groupId>
<artifactId>karaf-maven-plugin</artifactId>
<configuration>
<includeTransitiveDependency>true</includeTransitiveDependency>
</configuration>
<executions>
<execution>
<id>generate-features-descriptor</id>
<goals>
<goal>features-generate-descriptor</goal>
</goals>
</execution>
</executions>
</plugin>
构建您的项目将在您的本地 Maven 存储库中创建一个额外的 Maven 工件和您的 bundle jar:xxx-features。xml
您可以使用 feature:repo-add
命令让本地 Karaf 知道您的功能存储库。然后使用 feature:install
命令添加您的功能。这将启动您的包及其所有声明的(传递的)Maven 依赖项。
编辑:
正如您在评论中提到的,您的某些(全部?)依赖项是纯 JAR,而不是 OSGi 包,可能您最好 embedding 将那些 non-OSGi 依赖项放入您自己的包中maven-bundle-plugin。但这可能非常乏味。大多数 non-OSGi JAR 都有包导入,这些导入要么在运行时根本不使用,要么在您的特定使用场景中不使用。为了避免将 OSGi 依赖项列表扩展到传递性 Maven 依赖项列表之外,您必须防止将那些“继承的”包添加到您自己的包的 MANIFEST 中的包导入列表中。例如,我有一个使用 httl 模板库的包,它又依赖于 Javassist。 OSGi 包也不是。因此,我同时嵌入并禁止导入在 httl 或 javassist 代码中声明但在运行时不需要的包:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Embed-Dependency>*;scope=compile|runtime;inline=false;artifactId=httl|javassist</Embed-Dependency>
<Embed-Transitive>false</Embed-Transitive>
<Import-Package>
!com.alibaba.*,
!com.thoughtworks.*,
!javassist.*,
!net.htmlparser.*,
!org.apache.commons.logging.*,
!org.codehaus.jackson.*,
!org.joda.convert.*,
!com.sun.jdi.*,
!javax.servlet.*,
*
</Import-Package>
</instructions>
</configuration>
</plugin>