Apache Maven Assembly插件无法使用OSGi软件包 [英] Apache Maven Assembly Plugin not working with OSGi bundles

查看:113
本文介绍了Apache Maven Assembly插件无法使用OSGi软件包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Maven OSGi多模块项目。当OSGi从单个项目模块中选择模块罐时,该项目运行良好。



然而,使用第二种方法 bundle.getRegisteredServices() (见下面的1.1.A) 当我尝试使用存放在中央文件夹中的bundle时,返回null :/ parent / provider / target / modules)使用 maven-assembly-插件版本:2.6

  framework.getBundleContext()。installBundle(file:D:/ parent / provider /target/modules/OSGiDmHelloWorldProvider-1.0.jar); 
framework.getBundleContext()。installBundle(file:D:/parent/provider/target/modules/OSGiDmHelloWorldConsumer-1.0.jar);

查看1.1.C 输出使用第二种方法。



1.1.A

 code> if(bundle.getRegisteredServices()!= null){
for(ServiceReference<?> serviceReference:bundle.getRegisteredServices())
System.out.println(\tRegistered service:+ serviceReference);
}

为什么我无法使用第二种方法访问捆绑包?



GitHub



我有一个SSCCE在 GitHub HERE 。运行主课将显示我的困境。



提前谢谢。



1.1。 B

  package main; 

import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;

public class App {

public static void main(String [] args)throws BundleException,URISyntaxException {
App app = new App();
app.initialize();
}

private void initialize()throws BundleException,URISyntaxException {
Map< String,String> map = new HashMap< String,String>();

//确保缓存清理
map.put(Constants.FRAMEWORK_STORAGE_CLEAN,Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);

map.put(ds.showtrace,true);
map.put(ds.showerrors,true);

FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFactory.class).iterator()。next();
框架框架= frameworkFactory.newFramework(map);

System.out.println(启动OSGi框架);
framework.init();

loadScrBundle(framework);

framework.getBundleContext()。installBundle(file:D:/parent/provider/target/OSGiDmHelloWorldProvider-1.0.jar);
framework.getBundleContext()。installBundle(file:D:/parent/consumer/target/OSGiDmHelloWorldConsumer-1.0.jar);

for(Bundle bundle:framework.getBundleContext()。getBundles()){
bundle.start();
System.out.println(Bundle:+ bundle.getSymbolicName());
if(bundle.getRegisteredServices()!= null){
for(ServiceReference<?> serviceReference:bundle.getRegisteredServices())
System.out.println(\tRegistered service :+ serviceReference);
}
}
}

private void loadScrBundle(Framework framework)throws URISyntaxException,BundleException {
URL url = getClass()。getClassLoader()。的getResource( 组织/阿帕奇/菲利克斯/ SCR / ScrService.class);
if(url == null)
throw new RuntimeException(找不到类org.apache.felix.scr.ScrService);
String jarPath = url.toURI()。getSchemeSpecificPart()。replaceAll(!。*,);
System.out.println(发现声明性服务实现:+ jarPath);
framework.getBundleContext()。installBundle(jarPath).start();
}
}

1.1.C 发现声明性服务实现:file:/ C:/Users/Revilo/.m2/repository/ org / apache / felix / org.apache.felix.scr / 1.6.2 / org.apache.felix.scr-1.6.2.jar
INFO:org.apache.felix.scr(1):Version = 1.6.2
DEBUG:启动ComponentActorThread
Bundle:org.apache.felix.framework
注册服务:[org.osgi.service.resolver.Resolver]
注册服务:[ org.osgi.service.packageadmin.PackageAdmin]
注册服务:[org.osgi.service.startlevel.StartLevel]
Bundle:org.apache.felix.scr
注册服务:[org .apache.felix.scr.ScrService]
注册服务:[org.osgi.service.cm.ManagedService]
注册服务:[org.apache.felix.scr.impl.ScrGogoCommand]
Bundle:null
Bundle:null


解决方案

我不得不做很多让你r样本重复该问题。



首先,您的反应堆订单在父母中是错误的。这就是为什么你必须做mvn安装所有的时间。

 < modules> 
< module> OSGiDmHelloWorldProvider< / module>
< module> OSGiDmHelloWorldConsumer< / module>
< module> main< / module>
< module> dist< / module>
< / modules>

接下来,如果您在父项中定义依赖关系(例如JUnit),则不需要重新精细化



接下来,将父标签放在pom的顶部是常规的。



我没有看到有理由让你的孩子模块与父母有不同的版本,所以我删除了这个标签,所以他们都有父母的 1.0-SNAPSHOT



接下来,您在OSGiDmHelloWorldProvider依赖项中的组ID不正确(应该是rev)。

 <依赖关系> 
< groupId> rev< / groupId>
< artifactId> OSGiDmHelloWorldProvider< / artifactId>
< version> 1.0-SNAPSHOT< / version>
< / dependency>

在主模块中,有一个不在反应器中的依赖项。我猜这只是对样本的监督。

 <依赖关系> 
< groupId> rev< / groupId>
< artifactId> core< / artifactId>
< version> 1.0-SNAPSHOT< / version>
< / dependency>

所有这些, mvn clean package -DskipTests = true 工作。



您的主类中有一个硬编码的字符串显然对我不起作用。 (您也可以查看免费的 IDEA社区,而不是Eclipse!)

  String baseDir =D:/ standAloneDev / java / workingDir / Sample Projects / Eclipse / Gen / OSGiDmHelloWorld / dist / target / dist-1.0 -SNAPSHOT斌/插件/; 

你应该使这个亲戚。文件baseDir =新文件(dist / target / dist-1.0-SNAPSHOT-bin / plugins /);

  
String baseDirPath = baseDir.getAbsolutePath();

loadScrBundle(framework);

文件提供者=新文件(baseDirPath,OSGiDmHelloWorldProvider-1.0-SNAPSHOT.jar);
文件消费者=新文件(baseDirPath,OSGiDmHelloWorldConsumer-1.0-SNAPSHOT.jar);

framework.getBundleContext()。installBundle(provider.toURI()。toString());
framework.getBundleContext()。installBundle(consumer.toURI()。toString());

无论如何,得到它后,我注意到以下javadoc在 bundle.getSymbolicName ()

 返回此Bundle的符号名称,由Bundle-SymbolicName清单标题指定。捆绑符号名称应该基于与用于java包的反向域名命名约定。 

所以在org.apache.felix.scr-1.6.2.jar的MANIFEST.MF中有

  Bundle-Name:Apache Felix声明式服务
Bundle-SymbolicName:org.apache.felix.scr

您没有这样做,因为您没有创建清单并将其添加到jar。 / p>

您需要添加执行阶段,并告诉jar插件才能使用清单:

 code>< plugin> 
< artifactId> maven-jar-plugin< / artifactId>
< configuration>
< archive>
< manifestFile> $ {project.build.outputDirectory} /META-INF/MANIFEST.MF</manifestFile>
< / archive>
< / configuration>
< / plugin>
< plugin>
< groupId> org.apache.felix< / groupId>
< artifactId> maven-bundle-plugin< / artifactId>
<执行>
< execution>
< id> bundle-manifest< / id>
< phase> process-classes< / phase>
< goals>
< goal>清单< / goal>
< / goals>
< / execution>
< / executions>
< extensions> true< / extensions>
< configuration>
<指令>
< Bundle-SymbolicName> OSGiDmHelloWorldProvider< / Bundle-SymbolicName>
< Export-Package> com.bw.osgi.provider.able< / Export-Package>
< Bundle-Activator> com.bw.osgi.provider.ProviderActivator< / Bundle-Activator>
< Bundle-Vendor> Baptiste Wicht< / Bundle-Vendor>
< / instructions>
< / configuration>
< / plugin>


I have a Maven OSGi multi-module project. The project runs perfectly well when the OSGi picks the module jars from the individual project modules. (view 1.1.B below).

However, using a second approach, bundle.getRegisteredServices() (view 1.1.A below) returns null whenever I try using bundles deposited into a central folder (D:/parent/provider/target/modules) using the maven-assembly-plugin version : 2.6:

framework.getBundleContext().installBundle("file:D:/parent/provider/target/modules/OSGiDmHelloWorldProvider-1.0.jar");
framework.getBundleContext().installBundle("file:D:/parent/provider/target/modules/OSGiDmHelloWorldConsumer-1.0.jar");

View 1.1.C below for console output using the second approach.

1.1.A

if (bundle.getRegisteredServices() != null) {
    for (ServiceReference<?> serviceReference : bundle.getRegisteredServices())
        System.out.println("\tRegistered service: " + serviceReference);
}

Why can't I access the bundles with the second approach?

GitHub

I have a SSCCE on GitHub HERE. Running the main class will show my predicament.

Thank you all in advance.

1.1.B

package main;

import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;

public class App {

    public static void main(String[] args) throws BundleException, URISyntaxException {
        App app = new App();
        app.initialize();
    }

    private void initialize() throws BundleException, URISyntaxException {
        Map<String, String> map = new HashMap<String, String>();

        // make sure the cache is cleaned
        map.put(Constants.FRAMEWORK_STORAGE_CLEAN, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);

        map.put("ds.showtrace", "true");
        map.put("ds.showerrors", "true");

        FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFactory.class).iterator().next();
        Framework framework = frameworkFactory.newFramework(map);

        System.out.println("Starting OSGi Framework");
        framework.init();

        loadScrBundle(framework);

        framework.getBundleContext().installBundle("file:D:/parent/provider/target/OSGiDmHelloWorldProvider-1.0.jar");
        framework.getBundleContext().installBundle("file:D:/parent/consumer/target/OSGiDmHelloWorldConsumer-1.0.jar");

        for (Bundle bundle : framework.getBundleContext().getBundles()) {
            bundle.start();
            System.out.println("Bundle: " + bundle.getSymbolicName());
            if (bundle.getRegisteredServices() != null) {
                for (ServiceReference<?> serviceReference : bundle.getRegisteredServices())
                    System.out.println("\tRegistered service: " + serviceReference);
            }
        }
    }

    private void loadScrBundle(Framework framework) throws URISyntaxException, BundleException {
        URL url = getClass().getClassLoader().getResource("org/apache/felix/scr/ScrService.class");
        if (url == null)
            throw new RuntimeException("Could not find the class org.apache.felix.scr.ScrService");
        String jarPath = url.toURI().getSchemeSpecificPart().replaceAll("!.*", "");
        System.out.println("Found declarative services implementation: " + jarPath);
        framework.getBundleContext().installBundle(jarPath).start();
    }
}

1.1.C

Starting OSGi Framework
Found declarative services implementation: file:/C:/Users/Revilo/.m2/repository/org/apache/felix/org.apache.felix.scr/1.6.2/org.apache.felix.scr-1.6.2.jar
INFO : org.apache.felix.scr (1):  Version = 1.6.2
DEBUG: Starting ComponentActorThread
Bundle: org.apache.felix.framework
    Registered service: [org.osgi.service.resolver.Resolver]
    Registered service: [org.osgi.service.packageadmin.PackageAdmin]
    Registered service: [org.osgi.service.startlevel.StartLevel]
Bundle: org.apache.felix.scr
    Registered service: [org.apache.felix.scr.ScrService]
    Registered service: [org.osgi.service.cm.ManagedService]
    Registered service: [org.apache.felix.scr.impl.ScrGogoCommand]
Bundle: null
Bundle: null

解决方案

I had to do a lot to get your sample to duplicate the question.

First off your reactor order is wrong in the parent. That is why you have to do mvn install all the time.

<modules>
    <module>OSGiDmHelloWorldProvider</module>
    <module>OSGiDmHelloWorldConsumer</module>
    <module>main</module>
    <module>dist</module>
</modules>

Next, if you define a dependency (e.g. JUnit) in the parent you don't need to redfine it in the children.

Next, it is conventional to put the parent tag at the top of the pom.

I don't see a reason to have your child modules have a different version to the parent so I removed the tag so they all have 1.0-SNAPSHOT from the parent.

Next, you have the wrong group id in the OSGiDmHelloWorldProvider dependency (it should be rev).

    <dependency>
        <groupId>rev</groupId>
        <artifactId>OSGiDmHelloWorldProvider</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

In the main module you have a dependency that isn't in the reactor. I am guessing this is just an oversight of the sample.

    <dependency>
        <groupId>rev</groupId>
        <artifactId>core</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

After all that, mvn clean package -DskipTests=true works.

You have a hard-coded string in your Main class that obviously doesn't work for me. (You also might want to look at the free IDEA Community instead of Eclipse!)

String baseDir = "D:/standAloneDev/java/workingDir/Sample Projects/Eclipse/Gen/OSGiDmHelloWorld/dist/target/dist-1.0-SNAPSHOT-bin/plugins/";

You should make this relative. e.g.

File baseDir = new File("dist/target/dist-1.0-SNAPSHOT-bin/plugins/");
String baseDirPath = baseDir.getAbsolutePath();

loadScrBundle(framework);

File provider = new File(baseDirPath, "OSGiDmHelloWorldProvider-1.0-SNAPSHOT.jar");
File consumer = new File(baseDirPath, "OSGiDmHelloWorldConsumer-1.0-SNAPSHOT.jar");

framework.getBundleContext().installBundle(provider.toURI().toString());
framework.getBundleContext().installBundle(consumer.toURI().toString());

Anyway, after getting it going I noticed the following javadoc on bundle.getSymbolicName().

Returns the symbolic name of this bundle as specified by its Bundle-SymbolicName manifest header. The bundle symbolic name should be based on the reverse domain name naming convention like that used for java packages.

So in the MANIFEST.MF of org.apache.felix.scr-1.6.2.jar you have

Bundle-Name: Apache Felix Declarative Services
Bundle-SymbolicName: org.apache.felix.scr

You don't have this in yours as you are not creating a manifest and adding it to a jar.

You need to add an execution phase and tell the jar plugin to use the manifest:

        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <executions>
                <execution>
                    <id>bundle-manifest</id>
                    <phase>process-classes</phase>
                    <goals>
                        <goal>manifest</goal>
                    </goals>
                </execution>
            </executions>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Bundle-SymbolicName>OSGiDmHelloWorldProvider</Bundle-SymbolicName>
                    <Export-Package>com.bw.osgi.provider.able</Export-Package>
                    <Bundle-Activator>com.bw.osgi.provider.ProviderActivator</Bundle-Activator>
                    <Bundle-Vendor>Baptiste Wicht</Bundle-Vendor>
                </instructions>
            </configuration>
        </plugin>

这篇关于Apache Maven Assembly插件无法使用OSGi软件包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆