java基础-构建命令行运行的java程序简要注意
今天编写了一个运行在服务端的java工具类,才发现自己以前很少关注运营方面的内容,导致在服务端部署一个java的工具变得异常困难,其实这也是自己对java的了解不够造成的。
首先,当代码编写完成之后,在主类中必须要有main函数,其中的参数非常重要。根据一位同事的说法,除正常的执行程序之外,其中至少要包含两种参数:-v(软件版本,以及作者等介绍信息),-h(软件的帮助信息,良好的帮助文档能够帮助使用本软件的人能够很容易地学会其基本用法)。
main函数编写完成后,需要在build的时候,指定对应的jar包中的主类型,本部分是用maven构建的,因此需要在pom文件中加入定义:
<build>
<finalName>daily-report-transfer</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId> <configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>Main Class Name</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
此后,build完之后的MANIFEST.MF文件中就会包含描述main的一行数据:
Main-Class: Main Class Name
java命令运行时,可以在没有写入Main-Class的时候,使用加入ClassPath的方式运行(其中windows下分隔符用;Linux和mac下分隔符为:):
java –cp 类路径;要执行的主类 参数...
如果写入的Main-Class,就可以直接使用java –jar 命令运行jar包中的主类,后面接具体的参数。
但是如果使用java –jar的方式运行,也就意味着不能够加入额外的-cp,即加入不了其他的jar包,如果项目中使用了其他的jar包该怎么办?这就需要将所有的依赖项加入到打好的jar包中。
在maven中,同样可以添加plugin标签内容来生成包含依赖jar包中类型的方法,使用如下的手段:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>Main Class Name</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
此时就会根据标签descriptorRef中的内容生成含依赖项的jar包,可以使用java –jar的方式运行。
在运行时,我们通常需要指定的运行文件路径为相对路径而非绝对路径,这就需要使用File的相关相对路径的方法,其实File对象本身就支持相对运行路径,但最好使用ClassLoader能够识别的文件路径,通过Class.getResourceAsStream的形式访问。
关于程序的输出,有三种形式,即system out, system err以及exit代码。在Linux系统中,程序的输出流有两种:正常输出以及异常输出,分别用1和2表示。即我们在执行一个linux命令时,如果没有指定对应的输出文件,就会将正常输出以及异常输出都输出至控制台Console中,可以使用>或>>的方式,将其输出至指定的文件,在输出时1>(或>>)会将java中system out的内容输出指定文件,2>(或>>)会将sytem err的内容输出至指定文件。
我们在java程序中当然可以System.setOut(...),System.setErr(...)的方式在程序中将输出流重置,这就相当于重置一个静态变量,这样所有的输出都会重置到这个流中。值得注意的是,一定要保留程序的异常堆栈,将其正常地输出至文件或者控制台中,以便查看问题。异常的输出方式不仅有e.printStackTrace()方法,这就相当于将错误堆栈输出到控制台中,可以通过e.printStackTrace(PrintStream)的方式定向到指定的输出流中。
我们都指定命令有返回值,通过$?的方式得到上个程序的返回值,在java中如何确定呢?这就要通过System.exit(返回值)的方式,注意这句话要在程序运行完成时才能调用,因为调用完成后,java虚拟机就会退出。
此外,尤其需要注意的是,我们的java程序可能会在多种平台下运行,了解一些关于系统的差异属性非常必要,这里System.getProperty就能够得到我们需要的一系列属性:
|
属性名称 |
含义 |
|
java.version |
运行时环境版本 |
|
java.vendor |
运行时环境供应商 |
|
java.vendor.url |
供应商url |
|
java.home |
java安装目录 |
|
java.vm.specification.version |
虚拟机规范版本 |
|
java.vm.specification.vendor |
虚拟机规范供应商 |
|
java.vm.specification.name |
虚拟机规范名称 |
|
java.vm.version |
虚拟机实现版本 |
|
java.vm.vendor |
虚拟机实现供应商 |
|
java.vm.name |
虚拟机实现名称 |
|
java.specification.version |
运行时环境版本 |
|
java.specification.vendor |
运行时环境规范供应商 |
|
java.specification.name |
运行时环境规范名称 |
|
java.class.version |
类格式版本号 |
|
java.class.path |
Java类路径 |
|
java.library.path |
加载库时搜索的路径列表 |
|
java.io.tmpdir |
默认的临时文件路径,在创建临时文件时会使用到 |
|
java.compiler |
使用的jit编译器名称 |
|
java.ext.dirs |
一个或多个扩展目录的路径 |
|
os.name |
操作系统名称 |
|
os.arch |
操作系统的架构 |
|
os.version |
操作系统版本 |
|
file.separator |
文件分隔符 |
|
path.separator |
路径分隔符(win是;linux是:) |
|
line.separator |
行分隔符 |
|
user.name |
用户的账户名称 |
|
user.home |
用户的主目录 |
|
user.dir |
用户当前的工作目录 |
这其中,又以最下面的几个属性最为有用,在编写跨平台的应用程序时,尤其注意控制文件分隔符,行分隔符等操作。下面是在本机(mac系统)中执行后的结果:
os_name:Mac OS X
os_arch:x86_64
os_version:10.9.3
user_dir:/Users/xxx/develop/workspace/github/dailyreport-analyse
java_vm_specification_version:1.0
java_vm_specification_vendor:Sun Microsystems Inc.
java_vm_specification_name:Java Virtual Machine Specification
java_vm_version:20.65-b04-462
java_vm_vendor:Apple Inc.
java_vm_name:Java HotSpot(TM) 64-Bit Server VM
java_ext_dirs:/Library/Java/Extensions:/System/Library/Java/Extensions:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/ext
file_separator:/
path_separator::
java基础-构建命令行运行的java程序简要注意的更多相关文章
- Java基础教程——命令行运行Java代码
视屏讲解:https://www.bilibili.com/video/av48196406/?p=4 命令行运行Java代码 (1)使用记事本新建文本文件[Test.java]. 注意,默认状态下W ...
- python如何通过windows命令行运行一个python程序文件?
python如何通过windows命令行运行一个python程序文件? cmd 进入到py文件对应目录下或者直接在上面的文件地址栏输入cmd,敲入回车 定位到对应的目录下 输入python xxx.p ...
- 含有package关键字的java文件在命令行运行报错
程序中含有package关键字,使用命令行运行程序时出现"找不到或无法加载主类",而使用Eclipse软件可以正常运行程序的可能解决办法. 在包下的类,在Java源文件的地方编译后 ...
- Java基础(命令行操作、注释及API、)
一.常用的dos命令. dir:列出当前目录下的文件及文件夹 md:创建目录 rd:删除目录 cd:进入到指定目录 cd..:退出到上一级目录 cd\:退出到根目录 del:删除文件 exit:退出d ...
- Java 命令行运行参数大全
Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOME"bin"java –option 来启动,-option为虚拟 ...
- Java命令行运行参数说明大全--转
来源:http://xinklabi.iteye.com/blog/837435 Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOME\ ...
- Java 命令行运行参数
Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOME"bin"java –option 来启动,-option为虚拟 ...
- Java 命令行运行java程序,出现“找不到或无法加载主类 ”的注意事项
引用:http://blog.chinaunix.net/uid-27106528-id-5209914.html 要在CMD命令行中使用java 运行java程序,关于出现 “找不到或无法加载主类 ...
- 命令行运行Java程序时出现错误
在命令行运行Java程序时出现下面错误 Error: Could not create the Java Virtual Machine. Error: A fatal exception has o ...
随机推荐
- 海康威视 嵌入到web页面相关问题
因项目上面需求,接触到了海康威视的设备,要把他嵌入到web页面中,所以就开始了爬坑之路 刚开始不知道如何把设备的页面嵌入到项目的web页面中,直到我遇见了他——“WEB3.0控件开发包V1.0.9_C ...
- MySQL学习(二): 数据类型记录
整形: 浮点型: 日期时间:(使用较少,可能存在跨区域问题) 字符型: CHAR(M):定长,会将位数补充到M位 VARCHAR(M):非定长,最多到达M位 ENUM('v1','v2',...):从 ...
- Freemaker的java.beans.IntrospectionException: type mismatch between read and write methods
引言:freemaker在特定的spring以及jdk下的问题解决路径. 环境描述 spring 3.1.1, jdk1.8u80, freemake 2.3.19 错误信息描述: 严重: Excep ...
- Sqlalchemy 设置表编码及引擎
1. 设置引擎编码方式为utf8. engine = create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/sqldb01?ch ...
- Jenkins构建持续集成
Jenkins 是一个开源软件项目,旨在提供一个开放易用的软件平台,使软件的持续集成变得可能.现在软件开发追求的是效率以及质量,Jenkins使得自动化成为可能! 亮点 采用shell自定义脚本,控制 ...
- ubuntu安装lua5.3.2
lua5.3要自主编译安装 1.获取源:weget http://www.lua.org/ftp/lua-5.3.2.tar.gz 2.解压:tar -zxf lua-5.3.2.tar.gz 3.编 ...
- 跳转后全屏,兼容大部分浏览器JavaScript
<!DOCTYPE html> <html> <head> <title>测试</title> </head> <body ...
- POJ2891 Strange Way to Express Integers【扩展中国剩余定理】
题目大意 就是模板...没啥好说的 思路 因为模数不互质,所以直接中国剩余定理肯定是不对的 然后就考虑怎么合并两个同余方程 \(ans = a_1 + x_1 * m_1 = a_2 + x_2 * ...
- .NET Core/Framework 创建委托以大幅度提高反射调用的性能
都知道反射伤性能,但不得不反射的时候又怎么办呢?当真的被问题逼迫的时候还是能找到解决办法的. 为反射得到的方法创建一个委托,此后调用此委托将能够提高近乎直接调用方法本身的性能.(当然 Emit 也能够 ...
- [LOJ6145][2017 山东三轮集训 Day7]Easy
loj description 一棵树,每次给出\(l,r,x\),求从点\(x\)出发到达\([l,r]\)中任意一点的最短距离. sol 动态点分治. 建出点分树后,在每个节点上用以点编号为下标的 ...