离开了IDEA,你还会运行JAVA项目吗?
来源:https://juejin.cn/post/6986960816264183822
引言
你可能认为我是标题党,但是这绝不是危言耸听。我相信有很多开发者,早已经迷失在IDEA等集成工具的方便之中。
我们正式部署的时候,如果是Web项目,可以将程序打成WAR包使用tomcat服务器运行我们的项目。不是Web项目可以借助Maven打成JAR包直接去运行。
但是在开发的时候,我们可能都是用集成工具去执行我们的项目,比如我们最熟悉的IDEA、Eclipse,但是脱离他们你还会执行吗?你们还记得入门时的JDK命令吗?
我们知道JAVA是需要编译的语言,一次编译处处运行的特点,是JAVA的特点之一。
我们知道javac是编译java文件的命令,编译完的java文件就变成了.class文件,我们可以使用java命令运行编译后的文件,但是实际开发中,我们的文件有很多,而且还需要引入很多别人写好的依赖,当不让你用IDEA去运行,而是直接用命令你还会吗?
HelloWorld
先从我们最熟悉的HelloWorld开始,代码如下:
/**
* @author WangScaler
* @date 2021/7/20 16:39
*/
public class HelloWorld {
public static void main(String[] args) {
System.out.println("hello world");
}
}
复制代码
在HelloWorld的当前目录下打开cmd,先编译javac HelloWorld.java
生成了HelloWorld.class的编译文件,执行java HelloWorld
成功执行并打印hello world
。
这个过程对你来说,熟悉不能再熟悉,每个JAVA程序员起初都会学习的JAVA编译执行的过程。然而给程序加上包名,还能这么轻巧的执行吗?
加包名
在程序上加上包名package com.wangscaler.main;
,我们同样在当前文件下执行上述的操作。发现程序报错了,找不到主类。
这时候我们得带着包去执行,所以这次我们不在文件所在目录执行文件,而是在包的上层目录编译,如上图,我的编译路径应该是D:/springboot/javademo/src/main/java
在这个路径下执行
java com.wangscaler.main.HelloWorld
是可以正确执行的。然而,当我们多个包进行了依赖的时候呢?
包之间进行依赖
创建包com.wangscaler.util,并在此包下创建文件StringUtil.java
package com.wangscaler.util;
/**
* @author WangScaler
* @date 2021/7/20 16:20
*/
public class StringUtil {
public static String change(String a, String b) {
a = b;
return a;
}
}
复制代码
更改HelloWorld.java
package com.wangscaler.main;
import com.wangscaler.util.StringUtil;
/**
* @author WangScaler
* @date 2021/7/20 16:39
*/
public class HelloWorld {
public static void main(String[] args) {
System.out.println("hello world");
String a = "a";
String b = "b";
String c = StringUtil.change(a, b);
System.out.println(c);
}
}
复制代码
这时候,我们再按照上面的方法,在HelloWorld.java所在路径下执行javac HelloWorld.java
,就不行了,提示如下错误:
HelloWorld.java:3: 错误: 程序包com.wangscaler.util不存在
import com.wangscaler.util.StringUtil;
^
HelloWorld.java:16: 错误: 找不到符号
String c = StringUtil.change(a, b);
^
符号: 变量 StringUtil
位置: 类 HelloWorld
2 个错误
复制代码
原因是他不知道其他包在哪。那么我们在src/main/java下,编译可以吗?在src/main/java下执行
javac com/wangscaler/main/HelloWorld.java
发现是可以,然后执行 java com.wangscaler.main.HelloWorld
也是可以正确执行的。
那么我们不仅依赖我们自己的包,还依赖了别人的包,该如何编译呢?
Maven引入依赖
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
复制代码
更改HelloWorld.java
package com.wangscaler.main;
import com.wangscaler.util.StringUtil;
import org.apache.commons.lang.StringUtils;
/**
* @author WangScaler
* @date 2021/7/20 16:39
*/
public class HelloWorld {
public static void main(String[] args) {
System.out.println("hello world");
String a = "a";
String b = "b";
String c = StringUtil.change(a, b);
System.out.println(c);
System.out.println(StringUtils.equals(c,b));
}
}
复制代码
在src/main/java下执行javac com/wangscaler/main/HelloWorld.java
发现出现了错误
com\wangscaler\main\HelloWorld.java:4: 错误: 程序包org.apache.commons.lang不存在
import org.apache.commons.lang.StringUtils;
^
com\wangscaler\main\HelloWorld.java:18: 错误: 找不到符号
System.out.println(StringUtils.equals(c,b));
^
符号: 变量 StringUtils
位置: 类 HelloWorld
2 个错误
复制代码
上部引入我们自己的包,我们编译的时候找不到,我们提到上层去编译可以成功编译。而这次我们maven引入的包在其他盘,我们总不能还是和上次一样往上提路径了,那么我们如何将引入的jar包告诉它呢?
使用javac -cp
命令cp是classpath的缩写,所以你也可以使用javac -classpath
。命令如下:
javac -cp "C:\Users\ZYPC.m2\repository\commons-lang\commons-lang\2.6\commons-lang-2.6.jar;" D:/springboot/javademo/src/main/java/com/wangscaler/main/HelloWorld.java
复制代码
需要注意的是:你必须指定你文件的绝对路径,而且你必须知道你引入的包的位置。向我们直接在项目引入jar包的话,就更容易找到jar包的位置。
执行
java -cp "C:\Users\ZYPC.m2\repository\commons-lang\commons-lang\2.6\commons-lang-2.6.jar;" com.wangscaler.main.HelloWorld
复制代码
运行编译文件,这时候也得带着依赖,否则还是报错,因为编译的时候,不会把依赖编译进你的项目中。
命令技巧
将编译文件放入指定的文件夹
像IDEA编译的文件夹叫/target,所以我们也指定编译的文件到/target。
在src下创建文件夹target,并执行。
javac -d D:/springboot/javademo/src/target -cp "C:\Users\ZYPC.m2\repository\commons-lang\commons-lang\2.6\commons-lang-2.6.jar;" D:/springboot/javademo/src/main/java/com/wangscaler/main/HelloWorld.java
复制代码
编译的文件将放在target的路径下。我们在target下执行
java -cp "C:\Users\ZYPC.m2\repository\commons-lang\commons-lang\2.6\commons-lang-2.6.jar;" com.wangscaler.main.HelloWorld
复制代码
成功运行。
在项目其他路径下编译
上述编译过程都是在包名的上层路径,即src/main/java下编译的,如果我们想在src编译怎么办呢?我们之前在src/main/java编译是因为,如果不这样的话,找不到其他的包,所以我们如果告诉它这些包的位置,那么就可以了。
dir *.java/s/b > srclist.txt
将我们.java文件路径写入到srclist.txt文件中,然后执行编译
javac -d D:/springboot/javademo/src/target -cp "C:\Users\ZYPC.m2\repository\commons-lang\commons-lang\2.6\commons-lang-2.6.jar;" @srclist.txt
复制代码
根据这个文件进行编译,成功编译。
在其他路径运行项目
我们上述的运行项目,都是在编译文件的根路径上进行运行的,那么我们在其他位置可不可以?也是可以的。
只需要把编译的路径放入到cp参数里即可,即
java -cp "C:\Users\ZYPC.m2\repository\commons-lang\commons-lang\2.6\commons-lang-2.6.jar;D:\springboot\javademo\src\target" com.wangscaler.main.HelloWorld
复制代码
其他命令
命令有很多,如果你不记得,快去翻翻文档吧。
参考文档:
Java命令详解 命令行中 javac、java、javap 的使用详解 官方文档
Maven打成JAR包
真香定律,哈哈
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.wangscaler.main.HelloWorld</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>assembly</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
复制代码
执行mvn package
打包。
「技术分享」某种程度上,是让作者和读者,不那么孤独的东西。欢迎关注我的微信公众号:「Kirito的技术分享」
- END -