将我的依赖项放入我的JAR中

时间:2018-03-01 18:33:28

标签: java maven maven-shade-plugin

我可以打包一个我写过的JAVA项目。将Gson库用于JSON功能的一个。我对JAVA很新,所以我可能会犯一个愚蠢的错误,但这就是我所假设的:

在我的源代码中:

import com.google.gson.Gson;

然后像这样使用这个导入:

Gson gson = new Gson();
String json = gson.toJson(result);

在我的Maven pom.xml中,我在依赖项部分中包含以下内容:

<dependencies>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-lambda-java-core</artifactId>
    <version>1.0.0</version>
  </dependency>
  <dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.2</version>
    <scope>compile</scope>
  </dependency>
</dependencies>

正如我所说,它 打包到JAR文件而没有错误(使用Maven进行打包)但我的JAR文件在AWS上用作无服务器功能,所以我相信我需要的东西要做的是将 Gson 依赖项作为我的JAR文件的一部分(可能是错误的)。这似乎得到了我在AWS上遇到的错误的支持:

aws error

完成了一些谷歌搜索后,看起来Maven的“阴影”插件可能就是这张票。我将它添加到我的pom.xml中,如此:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.1.0</version>
    <configuration>
        <artifactSet>
            <includes>
              <include>com/google/gson/**</include>
            </includes>
        </artifactSet>
      </configuration>
      <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
          </execution>
       </executions>
 </plugin>

但是查看生成的JAR文件,我发现没有区别。我需要做些什么才能让它发挥作用?

可以在此处找到完整的POM文件:pom.xml

3 个答案:

答案 0 :(得分:1)

不幸的是,我没有足够的声誉来评论,所以我必须回答&#34;。但是你还在pom.xml中使用maven-jar-plugin吗?这可能会导致功能上出现一些重叠。

如果有,您可能希望将其删除,并考虑将这些内容添加到configuration的{​​{1}}部分,以确保您已宣布maven-shade-pluginmainClass跑是。 <createDependencyReducedPom>false</createDependencyReducedPom> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>main.java.***.ClassName</mainClass> </transformer> </transformers>

答案 1 :(得分:1)

如果您有从运行时容器提供的依赖项,则应该为这些依赖项设置范围。

  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-lambda-java-core</artifactId>
    <version>1.0.0</version>
    <scope>provided</scope>
  </dependency>

从插件配置中删除<artifactSet>部分,执行mvn package,然后将创建具有所需依赖关系的jar。

答案 2 :(得分:1)

我不熟悉其他人引用的shade插件。对我来说,你需要一个可执行jar的工件:jar,及其依赖

以下是我使用Maven的方式:

<?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>com.company.groupId</groupId>
    <artifactId>artifact-id</artifactId>
    <version>1.0.0</version>

    <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>3.7.0</version>

                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.1.0</version>

                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>com.company.App</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <id>attach-javadoc</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>3.0.1</version>
                <executions>
                    <execution>
                        <id>attach-source</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-core</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.2</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

您要注意的是构建插件maven-assembly-plugin。这告诉Maven如何组装/打包构建的结果。在其配置中,您定义包含可运行应用程序的主类,该应用程序通常位于public static void main(String[] args)声明的位置。您还定义了一个descriptor-ref,它是一个将附加到jar名称的String。所以,你最终得到artifactId-1.0.0-jar-with-dependencies.jar,以我的POM为例。

为了进一步解释发生的事情,如果没有我推荐的更改,您的POM会告诉Maven只是构建您的代码。作为其中的一部分,您声明了依赖项,您现在有两个依赖项:aws-lambda-java-coregson。如果未提供范围,则默认为compile范围。这告诉Maven在编译程序时获取该依赖项,以便程序可以使用该依赖项的代码。但是,在打包程序的构建工件时,Maven默认情况下不会在最终的jar中包含这些依赖项;它期望当你运行jar时,你将在类路径上拥有这些依赖项。

通过添加程序集构建插件,您将这些指令更改为Maven。有了这个插件,你告诉Maven,当它构建程序时,它需要以这样的方式组装它,即所有声明的依赖项都包含在程序中(读取:汇编),并在程序包的阶段执行。建立;您将在构建工件的lib文件夹中看到这些依赖项。然后,就像我之前提到的那样,descriptorRef是描述性信息,将被附加到构建工件的名称上。

顺便说一句,与您的问题并不真正相关,我建议您查看FasterXML以了解JSON处理和操作。功能更强大,更容易,并得到广泛支持和使用,这意味着它背后有一个很棒的社区。