java项目打包(maven+原生)

一、maven打jar包

1.1 没有第三方依赖的jar

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

<build><finalName>${project.artifactId}</finalName><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>

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 把第三方依赖放入其他目录,自己的代码单独形成jar

需要两个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命令打jar包

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 .\target\classes src\com\leon\Main.java
option参数说明
-encoding UTF-8java文件中文编码
-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命令是打包,命令类似linux tar

{}参数(只能选一个)

参数说明
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网站说运行更快,压缩体积更小
Mjar内不要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 File,Warning: 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包中目录错误

jar包的正确结构

xxx.jar
└—— com\leon\xxx.class…
└—— META-INF\MANIFEST.MF

jar包的错误结构

xxx.jar
└—— target\classes\com\leon\xxx.class…
└—— META-INF\MANIFEST.MF

解决办法一 切换目录法

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

解决办法二 -C参数(推荐)
jar cvfm Main.jar META-INF\MANIFEST.MF com\leon\Main.class -C target\classes .

-C 参数的含义就是要“剥去”jar包中的某些目录层级
注意

  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格式有关

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/754863.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Cesium:绘制一个 3DTiles 对象的外包盒顶点

作者:CSDN @ _乐多_ 本文将介绍如何使用 Cesium 引擎根据模型的中心坐标,半轴信息,绘制一个 3DTiles 对象的外包盒顶点。 外包盒是一个定向包围盒(Oriented Bounding Box),它由一个中心点(center)和一个包含半轴(halfAxes)组成。半轴由一个3x3的矩阵表示,这个矩阵…

学习python笔记:9,with,requests,os,set,list,enumerate,numpy.array

with语句 在Python中&#xff0c;with语句用于确保某段代码执行完毕时&#xff0c;资源&#xff08;如文件对象、网络连接等&#xff09;可以被正确地清理。这通常涉及到使用上下文管理协议&#xff0c;该协议要求一个对象实现__enter__()和__exit__()两个方法。 with语句的基…

常见视频名词及视频格式

常见视频名词 时长&#xff1a;视频时间单位&#xff0c;基本单位&#xff1a;秒&#xff0c;常见格式&#xff1a;00:00:00:00&#xff08;时&#xff1a;分&#xff1a;秒&#xff1a;帧&#xff09; 帧&#xff1a;视频的基础单位 视频也是一帧一帧组成的&#xff0c;他是…

Java安全基础 关键概念过关

Java安全基础 关键概念汇总 文章目录 Java安全基础 关键概念汇总前置知识1.构造器this以及包的使用2.继承3.重写/ 重载 / super4.多态5.区分和equals方法6.toString的使用7.Object的概念8.static,final,代码块static代码块final 9.动态代理10.类的动态加载1)类加载器含义&#…

卷积篇 | YOLOv8改进之C2f模块融合SCConv | 即插即用的空间和通道维度重构卷积

前言:Hello大家好,我是小哥谈。SCConv是一种用于减少特征冗余的卷积神经网络模块。相对于其他流行的SOTA方法,SCConv可以以更低的计算成本获得更高的准确率。它通过在空间和通道维度上进行重构,从而减少了特征图中的冗余信息。这种模块的设计可以提高卷积神经网络的性能。本…

常用的vim和linux命令

常用的vim命令和linux命令 vim编辑器有三种模式 命令模式、编辑模式、末行模式 模式间切换方法&#xff1a; 1.命令模式下&#xff0c;输入&#xff1a;后&#xff0c;进入末行模式 2.末行模式下&#xff0c;按esc慢退、按两次esc快退、或者删除所有命令&#xff0c;可以回…

如何正确从github上下载数据集等内容

文章目录 一、现象&#xff1a;二、解决方案 一、现象&#xff1a; 数据集点击下载没有反应&#xff0c;那需要怎么下载数据集呢&#xff1f; 二、解决方案 输入以下命名行&#xff0c;亲测有效 git clone https://github.com/mymusise/ChatGLM-Tuning.git

LeetCode每日一题[C++]-1793.好子数组的最大分数

题目描述 给你一个整数数组 nums &#xff08;下标从 0 开始&#xff09;和一个整数 k 。 一个子数组 (i, j) 的 分数 定义为 min(nums[i], nums[i1], ..., nums[j]) * (j - i 1) 。一个 好 子数组的两个端点下标需要满足 i < k < j 。 请你返回 好 子数组的最大可能…

【ADF4351】使用FPGA进行SPI寄存器配置、使用FPGA计算各个频率的频点,ADF4351配置程序

简介 特性 输出频率范围&#xff1a;35 MHz至4,400 MHz 小数N分频频率合成器和整数N分频频率合成器 具有低相位噪声的VCO 可编程的1/2/4/8/16/32/64分频输出 典型抖动&#xff1a;0.3 ps rms EVM(典型值&#xff0c;2.1 GHz)&#xff1a; 0.4% 电源&#xff1a;3.0 V至3.6 V …

Selenium 自动化 —— 使用WebDriverManager自动下载驱动

上一篇文章 入门和 Hello World 实例 中&#xff0c;我们提供了一个最简单的 Selenium 上手的例子。 但是某一天&#xff0c;突然发现相同的代码居然运行报错了。这是怎么回事呢&#xff1f; 日志排查 日志中其实提示的很明显了&#xff1a;Chrome浏览器和Chrome WebDriver的…

adobe animate 时间轴找不到编辑多个帧按钮

如题&#xff0c;找了半天&#xff0c;在时间轴上找不到编辑多个帧按钮,导致无法批量处理帧 然后搜索发现原来是有些版本被隐藏了&#xff0c;需要再设置一下 勾选上就好了

day0 3r文档docker部署

3R编码 | 3R教室 - 最好的数字游民学习与交流俱乐部! (3rcd.com) window安装wsl下载不下来&#xff0c;正好有个服务器&#xff0c;就用linux吧密钥长度不匹配&#xff0c;设置一下长度即可 文档启动不成功&#xff0c;单独下载了下nginx&#xff0c;docker pull nginx:latest …

笔记本固态硬盘损坏数据恢复两种方法 笔记本固态硬盘损坏如何恢复

大家好&#xff01;今天要跟大家分享的是笔记本固态硬盘损坏数据恢复的两种方法。相信很多小伙伴都遇到过这种情况&#xff0c;电脑突然蓝屏或者死机&#xff0c;再开机后发现自己的数据不见了&#xff0c;这时候该怎么办呢&#xff1f;这可真是让人头疼。毕竟&#xff0c;我们…

LeetCode-回文数

LeetCode-回文数 解体思路&#xff1a; ①第一种&#xff1a;转换成字符串&#xff0c;使用字符串的现有api方法进行反转 ②第二种&#xff1a;直接使用循环除余乘10方法&#xff0c;进行反转 涉及知识点&#xff1a; 循环判断&#xff0c;StringBuffer&#xff0c;int类型…

Unity中实现游戏对象逐渐放大的脚本教程

这个脚本是用于Unity游戏开发的&#xff0c;其主要功能是使一个游戏对象&#xff08;在这个例子中是一个球体&#xff09;在一段时间内逐渐放大到一个目标大小。脚本使用了Unity的协程&#xff08;Coroutine&#xff09;来实现这一过程&#xff0c;下面是脚本的详细介绍&#x…

C语言实现三叉树

#include <stdio.h> #include <stdlib.h> // 定义三叉树节点结构体 typedef struct TripletNode { int data; struct TripletNode *left; struct TripletNode *middle; struct TripletNode *right; } TripletNode; // 创建新的三叉树节点 Trip…

PSCA复位控制集成之复位信号

组件可能支持两种基本的复位类型。 • 冷复位&#xff1a;重置组件中的所有逻辑。用作上电复位。 • 热复位&#xff1a;重置组件中的大部分逻辑。通常&#xff0c;复位的范围是所有功能逻辑。不包括在热复位中的逻辑会随组件类型而变化&#xff0c;但通常会排除诸如调试和 R…

富格林:正确辨析虚假黑幕平台

富格林悉知&#xff0c;现货黄金自面世以来一直都是投资者关注的焦点。黄金市场的波动性较大&#xff0c;因此在进行交易前&#xff0c;选择一款正规的平台是保障交易的关键。事实上&#xff0c;目前市面上混杂着不少虚假黑幕平台&#xff0c;对于新手投资者来说如何正确辨析虚…

SAP前台处理:物料主数据创建<MM01>之基础视图

一、背景&#xff1a; 终于来到了物料主数据&#xff0c;我觉得物料账是SAP最重要的一项发明&#xff0c;也一直是SAP的一项重要优势&#xff0c;物料账记录了一个个物料的生生不息&#xff1b; 本章主要讲解物料主数据和财务相关的主要内容&#xff1a;这里特别提示由于作者…

MySql安装与卸载—我耀学IT

1.MySql安装 打开下载的mysql安装文件mysql-5.5.27-win32.zip&#xff0c;双击解压缩&#xff0c;运行“setup.exe”。 选择安装类型&#xff0c;有“Typical&#xff08;默认&#xff09;”、“Complete&#xff08;完全&#xff09;”、“Custom&#xff08;用户自定义&…