• 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下分隔符用;Linuxmac下分隔符为:):

    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::
    

     

  • 相关阅读:
    【论文阅读-Embedding】《GloVe: Global Vectors for Word Representation》
    机器学习的问题总结
    预算平滑
    ML基础番外篇-距离度量
    vim配置使用
    强化学习 Note
    强化学习(David Silver)9:探索与利用
    强化学习(David Silver)8:集成学习和计划
    强化学习(David Silver)7:策略梯度算法
    数学基础01-最优化(梯度下降法、牛顿法、拟牛顿法等)
  • 原文地址:https://www.cnblogs.com/mmaa/p/5789933.html
Copyright © 2020-2023  润新知