当前位置: 首页 > 知识库问答 >
问题:

Maven:使用指定主类和属性文件的着色插件编译项目

戚育
2023-03-14

作为Maven的新手,我试图用Maven和maven-shade-plugin编译一个项目(因为它似乎是构建一个胖罐子的最佳插件)。我试图指定我的主类来创建一个可运行的jar文件和一些。包含翻译字符串的属性文件。

根据netbean的输出,编译和构建似乎通过了,但我无法按以下方式运行它(假设Maven构建的jar更名为“程序”):

/usr/bin/java -cp program.jar bot.Main
> could not find or load main class bot.Main

这是我的项目文件结构:

这是我的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>
<groupId>com.mycompany</groupId>
<artifactId>mavenproject1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
    <resources>
    <resource>
        <directory>src/main/java/resources</directory>
        <includes>
            <include>**/*.properties</include>
        </includes>
    </resource>
</resources>
<plugins>

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.4.3</version>
    <configuration>
      <archive>
      <manifest>
        <addClasspath>true</addClasspath>
        <classpathPrefix>lib/</classpathPrefix>
        <mainClass>bot.Main</mainClass>
      </manifest>
    </archive>
    <shadedArtifactAttached>true</shadedArtifactAttached>
    <shadedClassifierName>launcher</shadedClassifierName>
    </configuration>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>shade</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

  <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>exec-maven-plugin</artifactId>
      <version>1.2.1</version>
      <executions>
          <execution>
              <goals>
                  <goal>java</goal>
              </goals>
          </execution>
      </executions>
      <configuration>
          <mainClass>bot.Main</mainClass>
      </configuration>
  </plugin>

</plugins>
</build>
<dependencies>
    <dependency>
        <groupId>org.telegram</groupId>
        <artifactId>telegrambots</artifactId>
        <version>2.4.0</version>
        <classifier>jar-with-dependencies</classifier>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.5</version>
    </dependency>
</dependencies>
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>

资源是否正确包含,为什么我不能在不指定主类的情况下使用java-jar命令运行我的程序?它说我“无效或损坏的jar文件”,这应该意味着无法运行。

另外,为什么不开始指定 Main 类路径?

共有1个答案

安浩瀚
2023-03-14

问题出在你的Shade插件的配置上,目前

<configuration>
  <archive>
    <manifest>
      <addClasspath>true</addClasspath>
      <classpathPrefix>lib/</classpathPrefix>
      <mainClass>bot.Main</mainClass>
    </manifest>
  </archive>
  <shadedArtifactAttached>true</shadedArtifactAttached>
  <shadedClassifierName>launcher</shadedClassifierName>
</configuration>

没有

要使用Shade插件构建可执行JAR,您需要将ManifestResourceTransov作为transtors提供。正确的配置是:

<configuration>
  <transformers>
    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
      <mainClass>bot.Main</mainClass>
    </transformer>
  </transformers>
  <shadedArtifactAttached>true</shadedArtifactAttached>
  <shadedClassifierName>launcher</shadedClassifierName>
</configuration>

请注意,使用此配置,着色的JAR不会取代主JAR。shadedartifactAttated设置为true,这意味着着色的JAR将作为次要工件附加到项目中。它将通过其启动器的分类器与主JAR区分开来,即shaded分类器名称参数。

在这个项目上运行< code>mvn clean package之后,您将创建2个jar:

  • mavenproject1-1.0-SNAPSHOT。jar,它是主jar。这个JAR只包含应用程序的编译Java源代码。它不是可执行的,并且不包含其中的所有依赖项类
  • mavenproject1-1.0-SNAPSHOT-launcher。jar是一个带有阴影的附加jar,由阴影插件构建。这个是可执行的,包含依赖项的类

这意味着如果您想以可执行JAR的形式启动应用程序,您必须启动-launcher.jar,而不是另一个

java -jar mavenproject1-1.0-SNAPSHOT-launcher.jar

作为附带说明,两个JAR都将包含您在中的资源

 类似资料:
  • 我对maven不是很有经验,在尝试多模块项目的时候,我开始想如何在父maven POM中为所有子模块指定Java版本。直到今天我一直在用: 但是在研究的时候我发现你也可以在maven编译器插件中指定Java版本,像这样: 然后将其包装到插件管理标记中,以启用子poms对其的使用。所以第一个问题是在属性和maven编译器插件中设置Java版本有什么区别? 我找不到明确的答案,但在研究的过程中,我发现

  • 我正在更新一个Spigot(Minecraft)插件,最新版本的Spigot需要Java16。在我的pom中,我将maven编译器插件目标更改为16,源代码仍然是1.8。现在我得到以下错误: POM: 4.0.0

  • 在这种情况下,我必须读取某个属性文件,然后调用一个外部程序。 > 为了读取属性文件,我使用了属性Maven插件,在验证阶段使用 为了执行外部程序,我使用execmaven插件,调用goal 但是,如果我调用“mvn exec:exec”,则不会调用验证阶段,因此不会读取属性。 在我当前的场景中,我无法将exec:exec与任何特定的阶段联系起来(这是因为所有其他阶段都有非常具体的作业要处理,而我尝

  • 我的问题是maven-shade-plugin似乎在我的项目上运行了两次。 我的父pom文件在这里:http://pastebin.com/EsYaCbzJ(在这里发布太长了) 该项目的pom(好吧,在这种情况下是模块)给我带来麻烦在这里:http://pastebin.com/jdyGXGpL 我正在尝试在 MySQL jdbc 驱动程序中着色。 这是我希望使用的pom.xml代码块。 现在,当

  • 我将创建一些编译概要文件,如下所示: null null

  • 我有一个Maven BOM文件,我将其导入到我的项目pom中: 适用于依赖项,甚至插件。但现在我还想控制pom项目中使用的插件的依赖性版本: 我想在BOM文件中指定Commons-dbcp的版本,而不必将其指定为BOM文件中jetty插件的依赖项。