简体   繁体   English

如何从 package 生成 jar 文件?

[英]How to generate jar file from package?

I have the following project, I am trying to generate jar file from it.我有以下项目,我正在尝试从中生成 jar 文件。

文件夹结构

I tried a ton of methods and I cannot properly generate the jar file, I think the problem is the folders structure, I also have to include the.xlsx as it it part of my program.我尝试了很多方法,但无法正确生成 jar 文件,我认为问题出在文件夹结构上,我还必须将.xlsx 包含在我的程序中。 When I try to clean and build it generates the.jar file but when i try to run it I get an error I also tried to manually specify the main class in the Manifest.txt and compile it.当我尝试清理和构建它时,它会生成.jar 文件,但是当我尝试运行它时出现错误,我还尝试在 Manifest.txt 中手动指定主要的 class 并编译它。

Error: Could not find or load main class NewJFrame
Caused by: java.lang.ClassNotFoundException: NewJFrame

What are the correct steps I should follow?我应该遵循哪些正确步骤? I mention that the "NewJFrame" is the class that has the main inside我提到“NewJFrame”是 class 里面有主要的

The pom structure is: pom结构是:

Pom Structure Pom结构

Add this into your pom file.将此添加到您的 pom 文件中。 And you will have a single far jar which contains all the dependencies you need and everything.您将拥有一个远 jar,其中包含您需要的所有依赖项和所有内容。

<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.1.1</version>

            <configuration>
                <archive>
                  <manifest>
                     <mainClass>fully.qualified.MainClass</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>

Unfortunately, it is not as easy as it sounds... To run a Jar, you need to have:不幸的是,这并不像听起来那么容易......要运行 Jar,您需要:

  • The jar you want to run.您要运行的 jar。 In your case, this is the Jar generated from your IDE command在您的情况下,这是从您的 IDE 命令生成的 Jar
  • A classpath, with all the dependencies.具有所有依赖项的类路径。 Usually, those dependencies are managed by your IDE, which is the reason why you can run your app with the IDE.通常,这些依赖项由您的 IDE 管理,这就是您可以使用 IDE 运行应用程序的原因。 But when you generate a JAR, with Maven for instance, then you no longer have your IDE managing the dependencies for you.但是,当您生成 JAR(例如 Maven)时,您不再需要 IDE 为您管理依赖项。

So let's say you have a basic application with Maven, with NO dependencies, you could do the following:因此,假设您有一个带有 Maven 的基本应用程序,没有依赖项,您可以执行以下操作:

package com.stackoverflow.test;
public class Main {

    public static void main(String[] args) {
        System.out.println("Hello World !");
    }
}

Then, to generate the JAR, you run man package .然后,要生成 JAR,请运行man package To run it, do the following (no need for manifest file):要运行它,请执行以下操作(不需要清单文件):

java -cp target/myApp.jar com.stackoverflow.test.Main

Here, you can see the "-cp" option, which instructs the JVM to load a JAR, in our case, located in target and named myApp.jar, and execute the main method inside the class com.stackoverflow.test.Main . Here, you can see the "-cp" option, which instructs the JVM to load a JAR, in our case, located in target and named myApp.jar, and execute the main method inside the class com.stackoverflow.test.Main .

Easy right?容易吧?

But then, things get more complicated when you start having dependencies.但是,当您开始有依赖关系时,事情会变得更加复杂。 In my following example, I'll assume I have a dependency with a famous library.在下面的示例中,我假设我依赖于一个著名的库。 I'll update my POM accordingly:我将相应地更新我的 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>org.example</groupId>
    <artifactId>launchJar</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
    </dependencies>


</project>

And then, I'll use this API in my code:然后,我将在我的代码中使用这个 API:

package com.stackoverflow.test;

import org.apache.commons.lang3.StringUtils;

public class Main {

    public static void main(String[] args) {
        System.out.println(StringUtils.upperCase("Hello World !"));
    }
}

Once I generated the Jar ( mvn package ) and execute the same command as before, I have your error:一旦我生成了 Jar ( mvn package )并执行与以前相同的命令,我就会遇到您的错误:

java -cp target/myApp.jar com.stackoverflow.test.Main

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils at com.stackoverflow.test.Main.main(Main.java:8)线程“主”中的异常 java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils 在 com.stackoverflow.test.Main.main(Main.Z93F725A07423DFE118C)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang3.StringUtils引起:java.lang.ClassNotFoundException:org.apache.commons.lang3.StringUtils
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)在 java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)在 java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)在 sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)在 java.lang.ClassLoader.loadClass(ClassLoader.java:351)
... 1 more ... 1 更多

The only way to get it to work is by adding my new dependencies to the classpath, in order to run the application.让它工作的唯一方法是将我的新依赖项添加到类路径中,以便运行应用程序。 With maven, in my example, the commons-lang3 dependencies is located in: ~/.m2/repository/org/apache/commons/commons-lang3/3.9/commons-lang3-3.9.jar .对于 maven,在我的示例中, commons-lang3依赖项位于: ~/.m2/repository/org/apache/commons/commons-lang3/3.9/commons-lang3-3.9.jar

In order for my application to run, I execute:为了让我的应用程序运行,我执行:

java -cp ~/.m2/repository/org/apache/commons/commons-lang3/3.9/commons-lang3-3.9.jar:target/myApp.jar com.stackoverflow.test.Main

Note:笔记:

  • To run the application, the classpath order is important (commons-lang before my Jar)要运行应用程序,类路径顺序很重要(我的 Jar 之前的 commons-lang)
  • On Unix/Linux, to separate different JARs, the character is : .在 Unix/Linux 上,要分隔不同的 JARs,字符为: On windows, use ;在 windows 上,使用;

But then, what happens if I have lots of dependencies, will I need to provide them manually?但是,如果我有很多依赖项会发生什么,我需要手动提供它们吗? Fortunately, no:D幸运的是,没有:D

With Maven, you can use a new plugin, which creates a so-called "fat jar", or "jar with dependencies".使用 Maven,您可以使用一个新插件,该插件创建一个所谓的“胖 jar”或“具有依赖项的 jar”。 To do so, just update your POM to add a new plugin:为此,只需更新您的 POM 以添加新插件:

...
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.1.1</version>

                <configuration>
                    <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>
        </plugins>
    </build>
...

Then, with man package you have a new JAR created, called: myApp-with-dependencies.jar.然后,使用man package创建一个新的 JAR,名为:myApp-with-dependencies.jar。 To run it, execute:要运行它,请执行:

java -cp target/myApp-jar-with-dependencies.jar com.stackoverflow.test.Main

You could also customize this plugin to automatically add a MainClass and have a "runnable Jar".您还可以自定义此插件以自动添加 MainClass 并具有“可运行 Jar”。

<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.1.1</version>

                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>com.stackoverflow.test.Main</mainClass>
                        </manifest>
                    </archive>
                </configuration>

                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>

            </plugin>

And then, just run:然后,只需运行:

java -jar target/myApp-jar-with-dependencies.jar

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM