手动编译并运行Java项目实现过程解析
现在java开发基本上就是ide调试,如果跨平台打个jar包过去运行一般就可以了,但是有些情况比如需要引入外部依赖的时候,这个时候是不能直接运行的,还需要引入一些外部的参数,并不是简单的javac和java的关系了,下面来详细说一下
一般情况下,在本地都是使用eclipse开发工具进行开发,很多东西基本上就不用我们考虑了,如果我们要将项目放到linux下运行的话,那么就需要进行转移的操作,当然有maven、ant这样的自动化部署工具,简直是太方便了,为了做到更进一步认识的话,我们纯手动的去打包一个java的项目
首先,项目名称为jartest,在eclipse结构如下图所示:
包名和类名都看的非常清楚了,app是主类,包含有main方法;testbean是一个javabean实体;testservice是一个利用testbean进行简单计算的类,那么各个类的代码如下:
app.java
package net.javatest.package1; import java.util.arraylist; import java.util.list; import net.javatest.package2.testbean; import net.javatest.package3.testservice; public class app { public static void main(string[] args) { list<testbean> tb = new arraylist<testbean>(); string[] names = {"hacker","nginx","github","hadoop","storm","solr","kafka","spark"}; for(int i = 0;i < names.length;i++) { tb.add(new testbean(string.valueof(i),names[i])); } list<string> namelist = testservice.namelist(tb); for(int i = 0;i < namelist.size();i++) { system.out.println(namelist.get(i)); } } }
testbean.java
package net.javatest.package2; public class testbean { private string id; private string name; public testbean() { } public testbean(string id, string name) { this.id = id; this.name = name; } public string getid() { return id; } public void setid(string id) { this.id = id; } public string getname() { return name; } public void setname(string name) { this.name = name; } }
testservice.java
package net.javatest.package3; import java.util.arraylist; import java.util.list; import net.javatest.package2.testbean; public class testservice { public static list<string> namelist(list<testbean> tbs) { list<string> names = new arraylist<string>(); for(testbean tb : tbs) { names.add(tb.getname()); } return names; } }
文件就是这样,源程序都不依赖于外部包,其实在eclipse中自动已经进行编译成class了,我们可以直接使用class文件,在这里我们直接使用源文件进行编译,首先打包上传项目,压缩成jartest.zip上传到服务器,
接下来解压释放目录:
unzip jartest.zipcd jartest/src
因为我们打包项目的时候打包的项目外层目录,所以解压出来需要进入jartest这个目录,我们的源代码文件在src中,现在开始编译:
javac net/javatest/package1/app.java net/javatest/package2/testbean.java net/javatest/package3/testservice.java
这样回车之后,没任何提示就编译好了,现在每个包下都有一个和源文件对应的class文件,如果感觉上面太长太麻烦,可以使用通配符全部搞定编译:
javac net/javatest/package*/*.java
这样就全部编译完了,现在我们可以执行一下看一下运行结果,
java net.javatest.package1.app
这样就可以直接app的main方法了,接下来可以进行打包,打成一个jar包,用起来更方便,我们可以用eclipse打成jar包看一下目录结构,我们会发现jar包如果解压出来之后,会看到meta-inf的一个目录,这个目录中有一个manifest.mf文件,这个文件就是定义如何导入外部jar包以及主类的存在位置,接下来我们自己编写manifest.mf这个文件,我们使用命令:vim manifest.mf创建一个文件,直接在当前也就是src目录下创建即可,然后我们编辑以下内容:
manifest-version: 1.0
main-class: net.javatest.package1.app
第一行是固定格式,定义版本号,第二行就是指明主类的位置可以用空格分开多个声明,注意冒号之后要有一个空格;然后注意的就是后面需要空出2行,输入两次换号即可,然后我们保存退出,执行下面命令打包:
jar -cvfm jartest.jar manifest.mf net/
其中jartest.jar就是要打的包,net就是我们的包目录,现在我们就可以看到一个jartest.jar这样一个文件,
然后我们执行下面命令就可以运行该jar文件了
java -jar jartest.jar
如果jar包中具有多个包含main方法的类时,需要指定main-class定义的其中之一,命令如下:
java -jar jartest.jar net.javatest.package1.app
以上是没有任何外部依赖的java项目的运行,如果有其他依赖的话,具体运行情况如下,我们将刚才打好的jar包下载,然后新建另外一个项目去调用jar包里面类中的方法,项目如下:
只有一个主类,代码很简单,就是调用了jartest.jar的方法,jartest2.java代码如下:
package net.javatest; import java.util.arraylist; import java.util.list; import net.javatest.package2.testbean; import net.javatest.package3.testservice; public class jartest2 { public static void main(string[] args) { list<testbean> tb = new arraylist<testbean>(); string[] names = {"test2","nginx","hbase","hadoop","storm","solr","kafka","spark"}; for(int i = 0;i < names.length;i++) { tb.add(new testbean(string.valueof(i),names[i])); } list<string> namelist = testservice.namelist(tb); for(int i = 0;i < namelist.size();i++) { system.out.println(namelist.get(i)); } } }
这时候将jartest.jar导入项目的path里面,编译的时候就不会出错了,我们继续上传该项目,进行编译,编译命令如下:
javac -classpath ../lib/jartest.jar: net/javatest/jartest2.java
导入多个外部jar包时需要用:分割,并且最后一个后面必须有冒号,-classpath参数用于指定外部jar包和类文件都可以,运行的时候也需要进行包含,运行命令如下:
java -classpath ../lib/jartest.jar: net.javatest.jartest2
接下来将项目打包,打包之前同样执行vim manifest.mf编辑文件如下:
manifest-version: 1.0
main-class: net.javatest.jartest2
class-path: lib/jartest.jar
这里第三行导入外部jar包文件,多个文件依赖用空格分隔,目录无所谓这里是相对于打包后jar文件的目录,就是说lib目录和打包后的jar文件在一个目录即可正常运行,接下来打包:
jar -cvfm jartest2.jar manifest.mf net/
打包后直接使用java -jar jattest.jar是不能执行的,需要将刚才的lib复制过来才可以,执行下面命令:
cd ..cp -r lib/ src/
复制刚才的lib目录过来即可,现在执行java -jar jartest2.jar即可正常运行了
综合来说,对于一个复杂的项目,编译以及运行时除了系统类库的支持,还需要引入外部jar包或者类文件才能保证整个项目的正常运行,具体的执行流程需要不断地去熟悉
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。