java - 如何运行多个相互依赖的maven模块

标签 java eclipse maven osgi

我有一个多模块 Maven OSGi 项目。我使用 maven- assembly-plugin 将不同的 jar 组织到一个中央文件夹中,OSGi 容器将从该文件夹加载各种项目模块:

dist pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>dist</artifactId>
    <packaging>jar</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>

            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <executions>
                    <execution>
                        <id>distro-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <descriptors>
                                <descriptor>src/main/assembly/bin.xml</descriptor>
                            </descriptors>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <parent>
        <groupId>rev</groupId>
        <artifactId>parent</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
</project>

模块 jar 按照我的意愿放入中央文件夹中。然而,随着时间的推移,我无法真正跟踪模块依赖关系如何相互关联。例如,某个模块可能需要启动另一个模块才能正确执行。我如何保证在 module-B 启动之前,module-A 将首先启动 - 我想以某种代码处理的方式配置它执行顺序?

这是当执行顺序不正确时出现的错误。我认为 bundle 没有安装。

Exception in thread "main" org.osgi.framework.BundleException: Unable to resolve OSGiDmHelloWorldConsumer [2](R 2.0): missing requirement [OSGiDmHelloWorldConsumer [2](R 2.0)] osgi.wiring.package; (&(osgi.wiring.package=com.bw.osgi.provider.able)(version>=1.0.0)(!(version>=2.0.0))) Unresolved requirements: [[OSGiDmHelloWorldConsumer [2](R 2.0)] osgi.wiring.package; (&(osgi.wiring.package=com.bw.osgi.provider.able)(version>=1.0.0)(!(version>=2.0.0)))]
    at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:4111)
    at org.apache.felix.framework.Felix.startBundle(Felix.java:2117)
    at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:998)
    at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:984)
    at main.App.initialize(App.java:46)
    at main.App.main(App.java:22)

下面是引发错误的类public class App {}:

应用程序

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);

        String baseDir = "/D:/Maven-Assembly-Plugin-MM/dist/target/dist-1.0-SNAPSHOT-bin/plugins/";

        framework.getBundleContext().installBundle("file:" + baseDir + "core-1.0.jar");
        framework.getBundleContext().installBundle("file:" + baseDir + "clientfile-plugin-1.0-SNAPSHOT.jar");
        framework.getBundleContext().installBundle("file:" + baseDir + "dist-1.0-SNAPSHOT.jar");

        List<Bundle> bundles = new ArrayList<Bundle>();

        for (Bundle bundle : framework.getBundleContext().getBundles()) {
            bundle.start();
            bundles.add(bundle);

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

        System.out.println("Total Bundles: " + bundles.size());
    }

    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();
    }
}

我该如何解决这个问题?提前谢谢大家。

更新

模块 jar 按照我的意愿放入中央文件夹中。然而,当我在调用 mvn clean install 之后尝试运行项目时,除 felix 模块之外的所有模块(即来自中央 Maven 存储库的所有模块,例如 org.apache.felix)都会出现以下错误。 Framework 和 org.apache.felix.scr 都在 OSGi 容器中运行,除了我自己编写的。

更详细的问题

我已经发布了问题项目的一个非常简短的版本,更详细HERE, Maven-Assembly-Plugin-MMThis, OSGi - Simple Hello World with services ,是我遵循的教程。

eclipse :
导入 > 现有 Maven 项目 > C:\***Path***\Maven-Assembly-Plugin-MM

最佳答案

bundle 加载顺序在 OSGi 应用程序中不重要。

但是 OSGi 服务可能依赖于其他服务。

您可以使用声明性服务等框架来轻松管理依赖项(例如使用 SCR annotations )。

您需要以下插件:

        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-scr-plugin</artifactId>
            <executions>
                <execution>
                    <id>generate-scr-scrdescriptor</id>
                    <goals>
                        <goal>scr</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

以及以下依赖项:

    <dependency>
        <groupId>org.apache.felix</groupId>
        <artifactId>org.apache.felix.scr.annotations</artifactId>
        <!-- only needed at compile time, not at runtime -->
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.felix</groupId>
        <artifactId>org.apache.felix.scr</artifactId>
        <scope>runtime</scope>
    </dependency>

关于java - 如何运行多个相互依赖的maven模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34594941/

相关文章:

java - String.split() 和空值之后的解析

从 Eclipse 启动时创建新的 JFrame 时 Java 将关闭。没有抛出异常

java - 如何创建一个包含两个图像的 JPanel,其中鼠标悬停时仅显示下面图像的一部分?

java - 从 Eclipse 内部运行时如何访问 <tomcat>\bin\*.properties?

C++ (g++) 特殊字符编码 ('\a' 、 '\b' 等)

android - 谷歌 Espresso java.lang.RuntimeException : Could not launch intent Intent { act=android. intent.action.MAIN

java - 打开示例项目上的 Liberty 日志配置异常

java - Eclipse 项目找不到 "org.joda"

java - Tomcat 7.0 : Error creating bean with name 'org. springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor

Java:是否有可能制作一组方法或任何类似的东西?