首页 > 编程语言 >java项目打包(maven+原生)

java项目打包(maven+原生)

时间:2024-03-18 09:04:24浏览次数:27  
标签:原生 MF java jar MANIFEST maven classes Main

一、maven打包

1.1 普通jar

java -jar maven项目打包提示.jar中没有主清单属性


    <build>
        <finalName>${project.artifactId}</finalName><!--修改编译出来的jar包名,仅为{artifactId}.jar-->
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.2.0</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>com.leon.Main</mainClass> <!-- 此处为主入口-->
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
                        
原文链接:https://blog.csdn.net/whq12789/article/details/106568531

1.2 有依赖的jar

How can I create an executable/runnable JAR with dependencies using Maven?

1. 一个jar

最高赞

<build>
  <plugins>
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <configuration>
        <archive>
          <manifest>
            <mainClass>fully.qualified.MainClass</mainClass>
          </manifest>
        </archive>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
      <executions>
        <execution>
          <id>make-assembly</id> <!-- this is used for inheritance merges -->
          <phase>package</phase> <!-- bind to the packaging phase -->
          <goals>
            <goal>single</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

2 把依赖放入其他目录

需要两个plugin结合使用

注意

  1. outputDirectory,就是生成的可运行的jar的依赖的目录
  2. maven-jar-plugin的classpathPrefix,作用是生产的可运行jar的MANIFEST.MF里面的Class-Path
  3. 这个方法,并不用我手动copy lib到项目里面,maven会自己从仓库里面copy
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>theMainClass</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

二、java命令打包

0、代码目录结构

projectDir\
└—— src\com\leon\xxx.java....
└—— lib\xxx.jar
└—— META-INF\MANIFEST.MF
└—— target\classes

  • 4个目录的结构都不是死的,都可以改变,但是以上的结构比较符合一般的项目结构
  • lib下放三方依赖
  • META-INF,一般是hyphen而不是underline,别记错写错。MANIFEST.MF可以写成txt,只要在参数里指定就好

1、javac编译成classes

javac -encoding UTF-8 -classpath .\lib\commons-lang3-3.7.jar -d .\classes src\com\leon\Main.java
option参数 说明
-encoding UTF-8 java文件中文编码
-d .\target\classes 将打包的class文件输出到指定目录
-classpath .\lib\xxx.jar 简写-cp
指定依赖的第三方jar
目录以【.\】开头或者省略【.\】似乎没关系,并不会导致固定死目录(包含本地目录比如D盘)
source file参数
src\......java 应该能简写成目录

2、验证classes的正确性

java -cp target\classes;lib\commons-lang3-3.7.jar com.leon.Main abc
  1. java运行class,首先需要指定自定义的classes的位置,-cp target\classes
  2. java命令的class参数要写【package的路径+class名字】,com.leon.Main
    如下
    这个路径,没有包含目录src,src仅仅是一个目录,它不在java文件的package命令里面
package com.leon;
	public class Main {
	}
  1. 注意 -cp命令没有以【.\】开头

可能的错误

  • java.lang.NoClassDefFoundError: xxx第三方引用
    -cp要指定第三方包,lib\commons-lang3-3.7.jar,多个第三方jar以semicolon分割

3、jar打包

95%内容参考自oracle的官方文档,Packaging Programs in JAR Files

jar的命令格式以jdk的帮助讲解,如下

jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...

jar命令是打包,命令很类似ta

{}参数(只能选一个)

参数 说明
c 打包成成为jar
基本不用
x 解压jar
t 显示jar中的内容
u 更新jar
x或i 没试过

[]参数

重要参数 说明
m 指定MANIFEST文件
f 打包的jar的名字,这个参数不传会output will go to a stdout(什么人或者为啥要go to stdout?)
e 可以指定class的入口。
C 去掉指定的目录层级。看实例。
不重要参数
v 打包时,显示详细的信息
0 不压缩。不压缩的jar据oracle网站说运行更快,压缩体积更小
M jar内不要MANIFEST,为啥不要?

注意:

m与f参数的顺序与[jar-file] [manifest-file]顺序是必须对应的。

正确jar命令

jar cvfm Main.jar META-INF\MANIFEST.MF com\leon\Main.class -C target\classes .

MANIFEST.MF

  • 自定义的MF文件,每行都是键值对的形式,以colon分割
    These lines show that a manifest's entries take the form of "header: value" pairs.
  • 自定义的MF文件可以写成txt,也可以.MF,文件名也可以任意,但是需要通过【m 参数+[manifest-file]】
  • 自定义的MF文件最后一行不会被写入到jar包中的MANIFEST.MF中,所以自定义的MF文件最后一行必须是空行
    来源:
    Modifying a Manifest FileWarning: The text file from which you are creating the manifest must end with a new line or carriage return. The last line will not be parsed properly if it does not end with a new line or carriage return.
  • MF文件需要以UTF-8编码

Main-Class


Main-Class: com.leon.Main

Class-Path

格式 Class-Path: jar1-name jar2-name directory-name/jar3-name

Class-Path: lib\commons-lang3-3.7.jar

  1. 在某个回答上看,不能以\开头(linux是/)。没验证
  2. jar包之间以空格分割
  3. 我看别人打包有以【.】开头的,如下,是为了把当前文件夹也包括进去?
Class-Path: . xxx1.jar xxx2.jar

jar打包正确之后,java -jar却报错“找不到或无法加载主类 xxx”

jar包的正确结构

xxx.jar
└—— com\leon\xxx.java....
└—— META-INF\MANIFEST.MF
如果出现以上错误,很可能是jar包中目录错误,如下
xxx.jar
└—— target\classes\com\leon\xxx.java....
└—— META-INF\MANIFEST.MF

解决办法一 切换目录法

cd进入classes中package目录的上一层,以示例来说,就是target\classes
然后,jar命令打包
然后,把jar放入到合适的位置运行java -jar(主要是与第三方依赖的相对位置要放置准确)

解决办法二 -C参数(推荐)

jar cvfm Main.jar META-INF\MANIFEST.MF com\leon\Main.class -C target\classes .

注意

  1. com\leon\Main.class是位于target\classes中的(这里与src目录无关)
  2. -C参数最后有一个【空格+.
    参考,could not find or load main class with a jar file,中作者Log2的回答,他解释的非常清楚,两种解决办法都有提到。

可能的错误

  • 提示 xxx.jar中没有主清单属性,打开jar
    以下命令会在jar中生成默认MF,位置在xxx.jar\META-INF\MANIFEST.MF,但是里面没有Main-Class
    需要用-m或-e参数指定
    jar -cvf Main.jar .\classes\com\leon\Main.class
    
  • 有m选项,也自定义了MANIFEST.MF,但是jar中的MANIFEST.MF还是没有Main-Class
    看看是不是MF文件只写了一行,没有在后面跟一个空行
  • 报错 java.io.IOException: invalid header field
    前面oracle文档说了,"header: value" pairs,所以,这个报错与MF格式有关

标签:原生,MF,java,jar,MANIFEST,maven,classes,Main
From: https://www.cnblogs.com/leondryu/p/18079568

相关文章

  • java基础
    快捷键:Ctrl+Shift+ESC:任务管理器卸载JDK1.删除java的安装目录2.删除JAVA_HOME3.删除path下关于java的目录4.java-version安装JDK1.baidu搜索JDK8,找到下载地址2.同意协议3.下载电脑对应的版本4.双击安装5.记住安装的路径6.配置环境变量1.添加JAVA_HOME环境变......
  • Java基础知识总结(3)
    冒泡排序冒泡排序是比较基础的排序算法之一,其思想是相邻的元素两两比较,较大的数下沉,较小的数冒起来,这样一趟比较下来,最大(小)值就会排列在一端。整个过程如同气泡冒起,因此被称作冒泡排序。importjava.util.Scanner;/* 外层循环控制轮数,内层循环控制每一轮交换的次数......
  • 「深入理解Java I/O:FilterInputStream」
      咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java之IO流啦,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~前言  JavaI/O是Java编程语言的核心功能之一,提供了丰富的输入输出操作......
  • 解决: java.util.concurrent.CancellationException详解
    解决:java.util.concurrent.CancellationException详解......
  • JAVA面向对象高级:继承:权限修饰符(继承注意事项) 单继承 Object类 方法重写
    权限修饰符(共四个):publilcprivateprotected缺省   单继承:   Object类:所有类的祖宗类。类均继承了Object类  方法重写     方法重写在开发中的应用场景:子类重写Object类中toString方法  ......
  • Java String类的compareTo() 方法
    compareTo()方法用于两种方式的比较:字符串与对象进行比较。按字典顺序比较两个字符串。intcompareTo(Objecto)或intcompareTo(StringanotherString)参数o--要比较的对象。anotherString--要比较的字符串。返回值返回值是整型,它是先比较对应字符的大小(ASC......
  • 疫苗接种管理系统(JSP+java+springmvc+mysql+MyBatis)
    本项目包含程序+源码+数据库+LW+调试部署环境,文末可获取一份本项目的java源码和数据库参考。项目文件图 项目介绍疫苗接种管理系统是一种旨在提高疫苗注射效率、确保接种记录准确性的信息系统。在全球疫情常态化防控的背景下,此类系统对于实现疫苗的快速分发、接种情况追......
  • 养老公寓管理系统(JSP+java+springmvc+mysql+MyBatis)
    本项目包含程序+源码+数据库+LW+调试部署环境,文末可获取一份本项目的java源码和数据库参考。项目文件图 项目介绍随着社会老龄化的加速,养老服务成为社会关注的焦点。养老公寓作为服务老年人群的重要居住形式,其管理水平直接影响到老年人的生活质量和家属的满意度。一个功......
  • java商场会员停车场管理系统的实现
    本系统(程序+源码)带文档lw万字以上 文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:随着城市化进程的加速和汽车保有量的持续增长,停车难已经成为城市中普遍存在的问题。特别是在商场等人流密集区域,如何高效管理会员停车场,提供便捷的停车服......
  • java商场旺铺分析系统
    本系统(程序+源码)带文档lw万字以上 文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:在现代商业运营中,商场作为消费的重要场所,其内部店铺的经营状况直接影响着商场的盈利能力和客流量。为了提升商场的整体竞争力,管理者需要对商场内各个旺铺......