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 ...
随机推荐
- 第1课:接口测试和jmeter总结
接口测试 1. 接口的分类:webService和http api接口 1) webService接口:是按照soap协议通过http传输,请求报文和返回报文都是xml格式,一般要借助工具来测试接口: ...
- 通过ssh证书远程登录
在渗透中,经常会发现某管理员主机上保存了大量机器的公私钥用于ssh证书登录.这个时候可以通过这个证书进行远程登录. 先回顾下证书登录通常的配置方法 一.生成不带passphrase的公私钥证书实现免密 ...
- JUnit出错,却没有显示任何报错信息【待解答】
JUnit测试代码如下: 原因分析: JUnit测试单元里,测试函数好像不能带参数? 解决办法: 发现测试函数testBookShopDaoUpdateBookStock(int isbn)里的参数i ...
- Confluence 安装
一.事前准备 1.jdk安装:5.8.10的jdk至少是7,其中7中还有很多官网是不建议的,这儿选中jdk-7u79 二.安装Confluence 双击atlassian-confluence-5.8 ...
- JFinal源码详解
JFinal的框架我24号的一篇博文写到过,它优秀的地方在精简代码上,那么有两处源码是我觉得是值得我们要好好解析一下,一处是初始化加载—servlet跳转,另一处是DB+ActiveRecord的映射 ...
- Python IDLE 的使用与调试
Python IDLE 是Python 安装包自带的集成开发环境.IDLE集成了Python 解释器.编辑器与调试器.适用于初学者了解Python 语法知识.1.使用 Python IDLE 编辑Py ...
- 【剑指offer】10矩阵覆盖
原创博文,转载请注明出处! 0.简介 # 本文是牛客网<剑指offer>刷题笔记,笔记索引链接 1.题目 # 用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地 ...
- 剑指offer第三章
剑指offer第三章 1.数值的整数次方 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. class Solution { public ...
- flask第十五篇——Response
从这一节开始,我就要开始讲关于模板的知识了.先来学习一下Response的相关知识. 所有返回前台的内容其实都应该是Response的对象或者其子类,我们看到如果返回的是字符串直接可以写成return ...
- 隐藏控件HiddenField使用
HiddenField控件顾名思义就是隐藏输入框的服务器控件,它能让你保存那些不需要显示在页面上的且对安全性要求不高的数据. 增加HiddenField,其实是为了让整个状态管理机制的应用程度更加全面 ...