如何从包中生成JAR文件?

huangapple go评论92阅读模式
英文:

How to generate jar file from package?

问题

我有以下项目,我正在尝试从中生成jar文件。

如何从包中生成JAR文件?

我尝试了许多方法,但无法正确生成jar文件,我认为问题在于文件夹的结构,我还必须包含.xlsx文件,因为它是我程序的一部分。
当我尝试进行"clean and build"时,它会生成.jar文件,但是当我尝试运行它时,我会收到一个错误消息。
我还尝试过在Manifest.txt中手动指定主类并进行编译。

  1. 错误:找不到或加载主类NewJFrame
  2. 原因:java.lang.ClassNotFoundException: NewJFrame

我应该遵循哪些正确的步骤?
我提到"NewJFrame"是包含主类的类。

Pom的结构如下:

Pom 结构

英文:

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.
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.

  1. Error: Could not find or load main class NewJFrame
  2. 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

The pom structure is :

Pom Structure

答案1

得分: 0

将以下内容添加到您的pom文件中。这样您将会得到一个包含所有所需依赖和其他内容的单独的far(可执行)JAR文件。

  1. <plugin>
  2. <groupId>org.apache.maven.plugins</groupId>
  3. <artifactId>maven-assembly-plugin</artifactId>
  4. <version>3.1.1</version>
  5. <configuration>
  6. <archive>
  7. <manifest>
  8. <mainClass>fully.qualified.MainClass</mainClass>
  9. </manifest>
  10. </archive>
  11. <descriptorRefs>
  12. <descriptorRef>jar-with-dependencies</descriptorRef>
  13. </descriptorRefs>
  14. </configuration>
  15. <executions>
  16. <execution>
  17. <id>make-assembly</id>
  18. <phase>package</phase>
  19. <goals>
  20. <goal>single</goal>
  21. </goals>
  22. </execution>
  23. </executions>
  24. </plugin>

不需要翻译的代码部分已被保留。

英文:

Add this into your pom file. And you will have a single far jar which contains all the dependencies you need and everything.

  1. &lt;plugin&gt;
  2. &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
  3. &lt;artifactId&gt;maven-assembly-plugin&lt;/artifactId&gt;
  4. &lt;version&gt;3.1.1&lt;/version&gt;
  5. &lt;configuration&gt;
  6. &lt;archive&gt;
  7. &lt;manifest&gt;
  8. &lt;mainClass&gt;fully.qualified.MainClass&lt;/mainClass&gt;
  9. &lt;/manifest&gt;
  10. &lt;/archive&gt;
  11. &lt;descriptorRefs&gt;
  12. &lt;descriptorRef&gt;jar-with-dependencies&lt;/descriptorRef&gt;
  13. &lt;/descriptorRefs&gt;
  14. &lt;/configuration&gt;
  15. &lt;executions&gt;
  16. &lt;execution&gt;
  17. &lt;id&gt;make-assembly&lt;/id&gt;
  18. &lt;phase&gt;package&lt;/phase&gt;
  19. &lt;goals&gt;
  20. &lt;goal&gt;single&lt;/goal&gt;
  21. &lt;/goals&gt;
  22. &lt;/execution&gt;
  23. &lt;/executions&gt;
  24. &lt;/plugin&gt;

答案2

得分: 0

很遗憾,事情并不像听起来那么简单... 要运行一个Jar文件,您需要以下内容:

  • 您要运行的Jar文件。在您的情况下,这是从IDE命令生成的Jar文件。
  • 一个类路径,包括所有的依赖项。通常,这些依赖项由您的IDE管理,这也是您可以使用IDE运行应用程序的原因。但是当您生成一个Jar文件,例如使用Maven,您就不再由IDE为您管理依赖项了。

假设您有一个基本的Maven应用程序,没有依赖项,您可以按照以下步骤进行操作:

  1. package com.stackoverflow.test;
  2. public class Main {
  3. public static void main(String[] args) {
  4. System.out.println("Hello World !");
  5. }
  6. }

然后,要生成Jar文件,运行man package。要运行它,执行以下操作(不需要清单文件):

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

这里,您可以看到-cp选项,它指示JVM加载一个Jar文件,在我们的例子中位于target目录下,名为myApp.jar,并在类com.stackoverflow.test.Main中执行主方法。

很简单,对吧?

但是,当您开始使用依赖项时,情况就会变得更加复杂。在我接下来的示例中,我将假设我有一个与著名库有关的依赖项。我将相应地更新我的POM文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>org.example</groupId>
  7. <artifactId>launchJar</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. <dependencies>
  10. <dependency>
  11. <groupId>org.apache.commons</groupId>
  12. <artifactId>commons-lang3</artifactId>
  13. <version>3.9</version>
  14. </dependency>
  15. </dependencies>
  16. </project>

然后,我将在我的代码中使用这个API:

  1. package com.stackoverflow.test;
  2. import org.apache.commons.lang3.StringUtils;
  3. public class Main {
  4. public static void main(String[] args) {
  5. System.out.println(StringUtils.upperCase("Hello World !"));
  6. }
  7. }

一旦我生成了Jar文件(使用mvn package),并执行与之前相同的命令,我就会遇到错误:

  1. 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)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang3.StringUtils
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
... 1 more

唯一使其工作的方法是将新的依赖项添加到类路径中,以便运行应用程序。在我的示例中,使用Maven,commons-lang3 依赖项位于:~/.m2/repository/org/apache/commons/commons-lang3/3.9/commons-lang3-3.9.jar

为了使我的应用程序运行,我执行:

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

注意:

  • 要运行应用程序,类路径的顺序很重要(在我的Jar文件之前是 commons-lang)。
  • 在Unix/Linux上,分隔不同的Jar文件的字符是:。在Windows上,请使用;

但是,如果我有很多依赖项,我需要手动提供它们吗?幸运的是,不需要 如何从包中生成JAR文件?

使用Maven,您可以使用一个新的插件,创建所谓的“fat jar”或“带有依赖关系的jar”。要这样做,只需更新您的POM以添加一个新的插件:

  1. ...
  2. <build>
  3. <plugins>
  4. <plugin>
  5. <groupId>org.apache.maven.plugins</groupId>
  6. <artifactId>maven-assembly-plugin</artifactId>
  7. <version>3.1.1</version>
  8. <configuration>
  9. <descriptorRefs>
  10. <descriptorRef>jar-with-dependencies</descriptorRef>
  11. </descriptorRefs>
  12. </configuration>
  13. <executions>
  14. <execution>
  15. <id>make-assembly</id>
  16. <phase>package</phase>
  17. <goals>
  18. <goal>single</goal>
  19. </goals>
  20. </execution>
  21. </executions>
  22. </plugin>
  23. </plugins>
  24. </build>
  25. ...

然后,使用mvn package您会得到一个新的Jar文件,名为:myApp-with-dependencies.jar
要运行它,执行:

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

您还可以自定义此插件,以自动添加一个MainClass,并创建一个“可运行的Jar”。

  1. <plugin>
  2. <groupId>org.apache.maven.plugins</groupId>
  3. <artifactId>maven-assembly-plugin</artifactId>
  4. <version>3.1.1</version>
  5. <configuration>
  6. <descriptorRefs>
  7. <descriptorRef>jar-with-dependencies</descriptorRef>
  8. </descriptorRefs>
  9. <archive>
  10. <manifest>
  11. <mainClass>com.stackoverflow.test.Main</mainClass>
  12. </manifest>
  13. </archive>
  14. </configuration>
  15. <executions>
  16. <execution>
  17. <id>make-assembly</id>
  18. <phase>package</phase>
  19. <goals>
  20. <goal>single</goal>
  21. </goals>
  22. </execution>
  23. </executions>
  24. </plugin>

然后,只需运行:

  1. <details>
  2. <summary>英文:</summary>
  3. Unfortunately, it is not as easy as it sounds... To run a Jar, you need to have:
  4. - The jar you want to run. In your case, this is the Jar generated from your IDE command
  5. - 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. But when you generate a JAR, with Maven for instance, then you no longer have your IDE managing the dependencies for you.
  6. So let&#39;s say you have a basic application with Maven, with NO dependencies, you could do the following:

package com.stackoverflow.test;
public class Main {

  1. public static void main(String[] args) {
  2. System.out.println(&quot;Hello World !&quot;);
  3. }

}

  1. Then, to generate the JAR, you run `man package`. To run it, do the following (no need for manifest file):

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

  1. Here, you can see the &quot;-cp&quot; 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`.
  2. Easy right ?
  3. But then, things get more complicated when you start having dependencies. In my following example, I&#39;ll assume I have a dependency with a famous library. I&#39;ll update my POM accordingly:

<?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&quot;>
<modelVersion>4.0.0</modelVersion>

  1. &lt;groupId&gt;org.example&lt;/groupId&gt;
  2. &lt;artifactId&gt;launchJar&lt;/artifactId&gt;
  3. &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
  4. &lt;dependencies&gt;
  5. &lt;dependency&gt;
  6. &lt;groupId&gt;org.apache.commons&lt;/groupId&gt;
  7. &lt;artifactId&gt;commons-lang3&lt;/artifactId&gt;
  8. &lt;version&gt;3.9&lt;/version&gt;
  9. &lt;/dependency&gt;
  10. &lt;/dependencies&gt;

</project>

  1. And then, I&#39;ll use this API in my code:

package com.stackoverflow.test;

import org.apache.commons.lang3.StringUtils;

public class Main {

  1. public static void main(String[] args) {
  2. System.out.println(StringUtils.upperCase(&quot;Hello World !&quot;));
  3. }

}

  1. Once I generated the Jar (`mvn package`) and execute the same command as before, I have your error:

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

  1. &gt; Exception in thread &quot;main&quot; java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils at com.stackoverflow.test.Main.main(Main.java:8)&lt;br/&gt;
  2. Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang3.StringUtils&lt;br/&gt;
  3. at java.net.URLClassLoader.findClass(URLClassLoader.java:382)&lt;br/&gt;
  4. at java.lang.ClassLoader.loadClass(ClassLoader.java:418)&lt;br/&gt;
  5. at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)&lt;br/&gt;
  6. at java.lang.ClassLoader.loadClass(ClassLoader.java:351)&lt;br/&gt;
  7. ... 1 more&lt;br/&gt;
  8. 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`.
  9. 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

  1. Note:
  2. - To run the application, the classpath order is important (commons-lang before my Jar)
  3. - On Unix/Linux, to separate different JARs, the character is `: `. On windows, use `;`
  4. But then, what happens if I have lots of dependencies, will I need to provide them manually ? Fortunately, no :D
  5. With Maven, you can use a new plugin, which creates a so-called &quot;fat jar&quot;, or &quot;jar with dependencies&quot;. To do so, just update your POM to add a new plugin:

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

  1. &lt;configuration&gt;
  2. &lt;descriptorRefs&gt;
  3. &lt;descriptorRef&gt;jar-with-dependencies&lt;/descriptorRef&gt;
  4. &lt;/descriptorRefs&gt;
  5. &lt;/configuration&gt;
  6. &lt;executions&gt;
  7. &lt;execution&gt;
  8. &lt;id&gt;make-assembly&lt;/id&gt;
  9. &lt;phase&gt;package&lt;/phase&gt;
  10. &lt;goals&gt;
  11. &lt;goal&gt;single&lt;/goal&gt;
  12. &lt;/goals&gt;
  13. &lt;/execution&gt;
  14. &lt;/executions&gt;
  15. &lt;/plugin&gt;
  16. &lt;/plugins&gt;
  17. &lt;/build&gt;

...

  1. Then, with `man package` you have a new JAR created, called: myApp-with-dependencies.jar.
  2. To run it, execute:

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

  1. You could also customize this plugin to automatically add a MainClass and have a &quot;runnable Jar&quot;.

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

  1. &lt;configuration&gt;
  2. &lt;descriptorRefs&gt;
  3. &lt;descriptorRef&gt;jar-with-dependencies&lt;/descriptorRef&gt;
  4. &lt;/descriptorRefs&gt;
  5. &lt;archive&gt;
  6. &lt;manifest&gt;
  7. &lt;mainClass&gt;com.stackoverflow.test.Main&lt;/mainClass&gt;
  8. &lt;/manifest&gt;
  9. &lt;/archive&gt;
  10. &lt;/configuration&gt;
  11. &lt;executions&gt;
  12. &lt;execution&gt;
  13. &lt;id&gt;make-assembly&lt;/id&gt;
  14. &lt;phase&gt;package&lt;/phase&gt;
  15. &lt;goals&gt;
  16. &lt;goal&gt;single&lt;/goal&gt;
  17. &lt;/goals&gt;
  18. &lt;/execution&gt;
  19. &lt;/executions&gt;
  20. &lt;/plugin&gt;
  1. And then, just run:

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

  1. </details>

huangapple
  • 本文由 发表于 2020年7月27日 18:52:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/63113793.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定