目录
Java SE 应用
Java FX应用
结束 jar 程序
解决 "没有主清单属性" 报错
Spring Boot Maven plugin 打包应用
Java SE 项目通常会用来封装工具类,此时如果要打包(Jar包),建议使用 Maven 更加简单,本文不做描述
Java SE 项目如果使用了awt、swing,Java FX,则可以用来做GUI程序;否则可以做普通的后台程序,即不需要用户界面的程序。无论哪种都应该导出为可执行Jar文件,即类似exe程序一样,双击即可运行。可执行Jar程序放到任何安装了Java JRE或者JDK电脑上双击都能运行
本文以一个Java SE 普通后台程序和一个Java FX GUI程序为例进行说明
新建应用
应用编码
程序很简单,以后双击jar文件时,就会写日志,支持用户输入命令行参数,用户输入什么,全部打印到日志文件中
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.ResourceBundle;
/**
* Created by Administrator on 2018/6/29 0029.
* 日志工具类
*/
public class LogWmxUtils {
private static final String LOG_DIR_PATH;
static {
ResourceBundle resourceBundle = ResourceBundle.getBundle("system");
LOG_DIR_PATH = resourceBundle.getString("logDirPath");
}
/**
* 写入日志
*
* @param message
*/
public static final void writeLine(String message) {
try {
if (StringUtils.isNotBlank(message)) {
File logDir = new File(LOG_DIR_PATH);
if (!logDir.exists()) {
logDir.mkdirs();
}
SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String logName = simpleDateFormat1.format(new Date());
String messageHead = simpleDateFormat2.format(new Date());
File logFile = new File(logDir, logName + ".log");
FileWriter fileWriter = new FileWriter(logFile, true);
fileWriter.write(messageHead + ":" + message + "\r\n");
fileWriter.flush();
fileWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
import com.lct.utils.LogWmxUtils;
import java.util.concurrent.TimeUnit;
/**
* Created by Administrator on 2018/6/29 0029.
* 应用程序入口
* 程序执行完成后,就会自动退出
*/
public class MainApp {
public static void main(String[] args) {
try {
/** 主要介绍方式,所以编码很简单*/
StringBuffer stringBuffer = new StringBuffer();
if (args != null && args.length > 0) {
stringBuffer.append("User input parameters:");
for (String arg : args) {
stringBuffer.append(arg + " ");
}
} else {
stringBuffer.append("User input parameters are empty");
}
LogWmxUtils.writeLine(stringBuffer.toString());
/** 延时10秒,模拟程序执行任务*/
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
生成jar可执行文件
运行测试
可以将此 可执行jar文件 拷贝到任意安装了Java 环境的电脑上运行,如下所示双击运行之后,可在任务管理器中看到一个"javaw.exe"的虚拟机进程
如果china.jar在已经运行的情况下,再次双击运行时,则会新开进程进行运行,这时任务管理器就会看到多个进程在运行
新建项目
IDEA 新建Java FX 应用可以参考《IDEA JavaFX 开发入门》,此处不再累赘
这里只讲 打包成 可执行 Jar文件,其实与上面的 Java SE应用打包完全一致
生成jar可执行文件
下面是它默认打包的形式,用它可以直接生产exe程序,但是这里暂时先不讲,选中之后点击红色的横杆删除掉,现在不讲这种方式
运行测试
同样直接双击运行即可,可以看到窗口,也可以看到任务管理器中的javaw.exe进程
同样应用中可以做任意操作,如通信,网络编程,文件上传下载,UDP监听等等,照样mian方法可以接收参数
1、如果 jar 是窗口程序,且除了主线程外,没有其它用户线程 时,关了窗口,理论上程序也就运行完了
2、如果 jar 是窗口程序,且除了主线程外,还有其它用户线程 时,则关了窗口,任务管理器照样还能看到 javaw.exe 进程,因为还有子线程没有执行完,则只能杀进程结束程序了。
3、如果 jar 本身也不是窗口程序,则也只能杀进程结束程序了,即可以在任务管理器中手动结束,也可以使用 DOS 命令来杀进程,如下所示:
taskkill /f /t /im javaw.exe
1、如果运行可执行 jar 程序出现如下报错,这通常是因为打包好的 jar 中的 xxxx.jar\META-INF\MANIFEST.MF 文件中没有自动生成程序入口类。
PS D:\wmx_projects\IDEA_workspaces\activitiFirst\out\artifacts\activitiFirst_jar> java -jar .\activitiFirst.jar
.\activitiFirst.jar中没有主清单属性
PS D:\wmx_projects\IDEA_workspaces\activitiFirst\out\artifacts\activitiFirst_jar>
2、打包后的 jar 文件中必须要有 MANIFEST.MF 主清单文件,否则是无法运行的,然后打包后没有,可以自己手动新建,然后加上 Main-Class: 入口类全路径
1、对于 Maven 管理的 Java SE 应用,使用上面 "Java SE 应用"的方式进行打包也是可以的,然后却还有更简单的方式。
2、Maven 项目推荐使用 spring-boot 的 spring-boot-maven-plugin 插件来进行打包,无论是 war 包还是 jar 包都可以一键打包。
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.5.RELEASE
wmx.com
maven-jar
1.0-SNAPSHOT
org.springframework.boot
spring-boot-maven-plugin
3、为了效果明显新建一个类,代码如下:
package com.wmx.main;
import java.util.Scanner;
import java.util.logging.Logger;
public class MainApp {
private static final Logger logger = Logger.getAnonymousLogger();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
logger.info("程序启动,请输入留言...");
String line = scanner.nextLine();
while (!"exit".equals(line)) {
logger.info("收到您的信息:[" + line + "]");
logger.info("您可以继续输入,也可以输入 exit 进行退出.");
line = scanner.nextLine();
}
logger.info("感谢您的来访,再见!");
scanner.close();
}
}
4、直接双击 package 或者 install 一键打包即可:
5、神奇的是它不仅可以自动将第三方的依赖全部一并打包,还会自动生成 META-INF/MANIFEST.MF 主清单文件,此例它的内容生成如下:
Manifest-Version: 1.0
Implementation-Title: maven-jar
Implementation-Version: 1.0-SNAPSHOT
Start-Class: com.wmx.main.MainApp
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.1.5.RELEASE
Created-By: Maven Archiver 3.4.0
Main-Class: org.springframework.boot.loader.JarLauncher
可以看出它的 Start-Class 就是程序的入口,没有这个入口类,或者没有此主清单文件,则应用无法双击或者命令行运行的。
注意:maven 项目在没有使用 spring boot maven 插件的情况,如果直接使用 package 打包或者 install 命令安装,它只会打包项目的自己的源码以及资源文件,对于第三方的内容并不会包含。