【问题标题】:Running a executable JAR with external dependencies运行具有外部依赖项的可执行 JAR
【发布时间】:2017-08-22 17:18:01
【问题描述】:

我正在构建一个有两个发行版的 java 服务。每个发行版必须构建不同(一个内部有一个 spring-boot 嵌入式码头服务器,另一个没有)。在这两种情况下,我都创建了一个具有依赖项的发行版,除了一个(已经实现)。没有码头的罐子是使用maven-assembly-plugin(类似于这里的Problems running executable jar with dependencies)构建的,另一个使用spring-boot-maven-plugin(见http://docs.spring.io/spring-boot/docs/current/maven-plugin/usage.html)。我的问题是外部依赖项。

我想添加一个对 runtime 的额外依赖,但我不想使用我们的 OSGi

在这两个构建过程中,结果都是一个“可执行”jar,我可以这样运行:

java -jar my.jar

但我不知道如何解决其他依赖项。如果我在 my.jar 中运行上面没有外部依赖项(比如说 external.jar)的命令将失败,即使在同一个文件夹中也是如此。我可以让它在没有码头的情况下像这样用于分发:

java -classpath "./*" my.main.App

但这不适用于 my-with-jetty.jar。我也尝试运行:

java -classpath "./*" -jar my-with-jetty.jar

这根本行不通。

所以我的问题是:

是否有可能为这两种情况打包一个几乎所有依赖项的 jar?

是否可以将 jar 打包为可运行的 jar,这样就不需要提供主类?

当然,如果是的话,怎么做?我想以相同的方式运行两个发行版。

我想要类似的行为:

java -cp "./*" java -jar my.jar conf.cfg

java -cp "./*" java -jar my-rest.jar conf.cfg

谢谢。

【问题讨论】:

    标签: java maven spring-boot jar


    【解决方案1】:

    您需要至少 3 个 maven 项目都在同一个父项下,以便它们一起构建并具有相同的版本。您的所有代码都将在共享项目中,这将包含在两个可运行的 jar 项目中。每个可运行的 jar 项目都会以不同的方式构建。

    您的父 pom 将类似于:

    <?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>
    
      <groupId>foo.bar</groupId>
      <artifactId>parent</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>pom</packaging>
    
      <modules>
        <module>shared-jar</module>
        <module>spring-boot-jar</module>
        <module>jetty-jar</module>
      </modules>
    
    </project>
    

    您的共享 jar 项目将包含所有共享代码

    你的 spring-boot-jar 看起来像:

    <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>
    
        <parent>
            <groupId>foo.bar</groupId>
            <artifactId>parent</artifactId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <artifactId>spring-boot-jar</artifactId>
        <packaging>jar</packaging>
    
        <dependencies>
           <dependency>
              <groupId>foo.bar</groupId>
              <artifactId>shared-jar</artifactId>
              <version>${project.version}</version>
           </dependency>
            .... you will need to add all the spring boot dependencies with versions
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
                <plugin>
                    <artifactId>maven-failsafe-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals>
                                <goal>integration-test</goal>
                                <goal>verify</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    您的 jetty-jar 将使用

        <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>
    
            <parent>
                <groupId>foo.bar</groupId>
                <artifactId>parent</artifactId>
                <version>1.0-SNAPSHOT</version>
            </parent>
            <artifactId>jetty-jar</artifactId>
            <packaging>jar</packaging>
    
            <dependencies>
               <dependency>
                  <groupId>foo.bar</groupId>
                  <artifactId>shared-jar</artifactId>
                  <version>${project.version}</version>
               </dependency>
                .... other dependencies
            </dependencies>
    
     <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
    
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-shade-plugin</artifactId>
                    <version>3.0.0</version>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>shade</goal>
                            </goals>
                            <configuration>
                                <transformers>
                                    <transformer
                                            implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                        <manifestEntries>
                                            <!-- <Main-Class>foo.bar.Application</Main-Class> -->
                                        </manifestEntries>
                                    </transformer>
                                </transformers>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
    
            </plugins>
        </build>
    
        </project>
    

    【讨论】:

    • 对不起,我不明白这个问题,你有 2 个罐子,一个是作为 spring boot 运行的,另一个不是。非spring-boot jar如何运行?
    • 一个提供 MQTT API,另一个提供 REST API。所以实际上两者都可以通过java -jar my.jar 启动
    • 所以他们没有相同的主类?您可以使用不同的主类,也可以使用 spring 配置文件根据 -Dspring.profiles.active 标志在同一个 jar 中公开不同的位。
    • 每个罐子(my.jar 和 my-rest.jar)都有不同的主类,但每个罐子只有一个。可以以java -jar my.jar && java -jar my-rest.jar 开头。但我希望两者都加载一个额外的依赖项extern.jar
    • 所以你有一个共享的jar,需要用不同的主类构建2个jar,但都共享公共jar?两个 jar 都需要从命令行运行?两个jar都需要建在同一个maven项目中?
    猜你喜欢
    • 2011-08-26
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    • 2012-04-21
    • 2014-09-02
    • 1970-01-01
    • 2020-11-16
    • 2012-04-12
    相关资源
    最近更新 更多