现在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.zip
cd 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包或者类文件才能保证整个项目的正常运行,具体的执行流程需要不断地去熟悉

手动编译并运行Java项目的过程的更多相关文章

  1. 使用CMD命令编译和运行Java程序

    对于初学者来说,使用CMD命令(Unix以及类Unix系统采用Termial)来编译和运行Java的好处是让初学者直观地体会到编译(Compile)这一步骤,加深记忆.所谓编译就是将文本文件xxx.j ...

  2. 【Java】【转】在命令行中编译和运行java

    原文:http://blog.csdn.net/u010900574/article/details/50792353 同时加载编译多个jar包和java文件 在个人平常使用或者当我们把代码部署到Li ...

  3. 在linux命令行中编译和运行java文件

    同时加载编译多个jar包和java文件 在个人平常使用或者当我们把代码部署到linux服务器上的时候,我们经常需要通过命令行编译和运行java文件,网上关于这个的方法大多是通过 javac -cp f ...

  4. 如何使用命令行编译以及运行java文件

    要想编译和运行java文件,很简单,只需要两个命令: (1) javac:作用:编译java文件:使用方法: javac Hello.java ,如果不出错的话,在与Hello.java 同一目录下会 ...

  5. [JAVA] 一个可以编辑、编译、运行Java简单文件的记事本java实现

    本来是Java课做一个仿windows记事本的实验,后来突然脑子一热,结果就给它加了一个编译运行Java文件的功能. 本工程总共大约3000行代码,基本上把所学的java界面.文件.控件的功能都包含在 ...

  6. 创建用于编译和运行Java程序的批处理文件

    创建用于编译和运行Java程序的批处理文件 每次编译或运行Java程序时,都要在DOS命令行中输入很长的javac或java命令,悟空觉得太麻烦,就编写了一个适用于Windows操作系统的批处理文件b ...

  7. 如何使用命令行编译和运行java文件

    相信大家现在一般都在使用IDE环境来开发运行java文件,但我觉得可以在命令行里面简单运行java文件,技多不压身. 接下来我来说一下编译和运行java文件: 第一步,首先下一个入门程序(注意:一定要 ...

  8. 在 Sublime Text 2 中编译和运行 Java 程序,以及输出中文出错问题解决办法

    Sublime Text 2 是我最喜欢用来编码的文本编辑器,如果你尝试使用后相信你也会喜欢上它的.在这篇文章中我们将讨论如何在 Sublime Text 2 中编译和运行 Java 程序. 第一步: ...

  9. Notepad++编译和运行Java

    首先要让Notepad++编译和运行Java,前提是电脑里已经配置好了Java的环境(这里可以参考我博客里关于Java环境配置的那篇随笔). 在Notepad++上面的选项栏中找到 插件---> ...

随机推荐

  1. jQuery EasyUI API 中文文档 - ComboGrid 组合表格

    jQuery EasyUI API 中文文档 - ComboGrid 组合表格,需要的朋友可以参考下. 扩展自 $.fn.combo.defaults 和 $.fn.datagrid.defaults ...

  2. [Angularjs]系列——学习与实践

    写在前面 这个系列是来这家公司到现在,边用边学,以及在工作中遇到的问题进行的总结.深入的东西不多,大多是实际开发中用到的东西. 这里做一个目录,方便查看. 系列文章 [Angularjs]ng-sel ...

  3. Linux下的特殊权限SetUID

    1.SetUID的功能 只有可以执行的二进制程序才能设置SUID权限 命令执行者要对改程序拥有x执行权限 命令执行者在执行改程序的时候获得该程序文件属主的身份(在执行程序的过程中灵魂附体为文件的属性) ...

  4. hdu4939 Stupid Tower Defense (DP)

    2014多校7 第二水的题 4939 Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131 ...

  5. 密码学初级教程(五)消息认证码MAC-Message Authentication Code

    密码学家工具箱中的6个重要的工具: 对称密码 公钥密码 单向散列函数 消息认证码 数字签名 伪随机数生成器 MAC能识别出篡改和伪装,也就是既可以确认消息的完整性,也可以进行认证. 消息认证码的输入包 ...

  6. 设置二级域名共享一级域名Cookie和删除共享Cookie

     设置共享Cookie: 二级域名要想共享一级域名的cookie,只需要设置cookie.Domain = ".一级域名.com";   删除共享Cookie:  HttpCook ...

  7. 2013成都Regional:一块木板,几个气球

    先来看木板: 再来看气球: 最后看木板+气球: google送的纪念品....  到现在还没敢打乱: 赛场外面.... 赛场里面: 和比赛时出了问题,并现场换了一台的电脑(对面长安大学1队)... 最 ...

  8. ThinkPHP报错处理

    1,当运行结果提示:找不到该页面(控制器),怎么办? 建造一个空页面:EmptyController <?php namespace Home\Controller; use Think\Con ...

  9. jquery选择器(一)-基础选择器

    1. ID元素选择器 $("#btn1") 2. class元素选择器 $(".btn") 3. 标签元素选择器 $("div") 4. 全 ...

  10. cocos布局分析

    HBox和VBox布局 HBox只是一个水平布局包装类. HBox里面所有的孩子节点都会水平排列成一行 VBox仅仅是对垂直布局的一个简便的类封装. VBox把它的子节点布局在一竖列中. Layout ...