一篇文章搞定 java 中的 path 和 classpath

1.path

1.1 path 作用

设置 path 是为了方便使用 java、javac等这些命令而不用写全路径。 如:

在这里插入图片描述

2. classpath

2.1 classpath 的作用

jar 包的搜索路径,告诉应用程序去哪里寻找 class。默认为当前目录。在实际的应用时,一般不需要设置 classpath。

2.2 classpath的使用方式

2.2.1 通配符
1. 匹配所有 .jar 或者 .JAR

如 -cp mydir/* 用来查找 mydir 下所有 .jar或者.JAR结尾的文件。仅仅是查找 mydir 下的,不会去查找 mydir 子目录

2.匹配所有 .jar或者.JAR以及 class files (如:cat.class)
-cp mydir:mydir/* or mydir/:mydir 注意它们是有顺序的,mydir:mydir/ 会先加载 classes files 再加载 jar files

2.2.2 直接通过 jar 包
-cp mydir/a.jar:mydir/b.jar:mydir/c.jar
2.2.3 加载 class files
( 可以忽略,在实际项目中根本不会用这种方式,因为有 idea 等工具的存在,所以重点来体会一下工具为我们做了什么 )

目录结构
在这里插入图片描述

//package test;

/**
 * @author shengjk1
 * @date 2020/4/8
 */
public class Test2 {
	public static void main(String[] args) {
		System.out.println("Hello Wrold");
	}
}

没有包名的时候
javac 执行成功,java 执行失败,并报  Could not find or load main class 。因为 classpath 默认为当前目录,当前是 iss 的 home 目录并未发现 Test2.class。故设置 classpath 重新执行

package test;

/**
 * @author shengjk1
 * @date 2020/4/8
 */
public class Test2 {
	public static void main(String[] args) {
		System.out.println("Hello Wrold");
	}
}

加上包名
在这里插入图片描述
在这里插入图片描述我们可以发现 java 以及 java -cp ./ 不管用了。发生了什么?
关键在于 package,package就表示在这个路径下去找这个类,当执行 java Test2 时,它会在 ./test 目录下查找,但根本就没有这个目录,故

Could not find or load main class

我们来指定 classpath
在这里插入图片描述
接下来呢,让 Test1去引用 Test2

package test;

import java.util.ArrayList;

/**
 * @author shengjk1
 * @date 2020/1/19
 */
public class Test1 {
	public static void main(String[] args) {
		Test2.main(args);
		
	}
}

在这里插入图片描述
在 Test1 中引入第三方的依赖 kudu

package test;

import org.apache.kudu.client.KuduTable;

import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @author shengjk1
 * @date 2020/1/19
 */
public class Test1 {
	public static void main(String[] args) {
		ArrayList<Integer> integers = new ArrayList<>();
		integers.add(192);
		integers.add(191);
		Map<String, SoftReference<KuduTable>> kuduTableMap = new HashMap<>();
		Test2.main(args);
		
	}
}

在这里插入图片描述

2.3 classpath的应用场景

  1. 打包是没有指定主类,可以用java -cp xxx.jar 主类名称(绝对路径)
  2. 要引用其他的jar包,可以用java -classpath $CLASSPATH:xxxx.jar 主类名称(绝对路径)

3. idea等工具究竟为我们做了什么

当我们使用idea的时候只需要
在这里插入图片描述
就可以运行一个包含 main 方法的 .java 文件,简单方便。可是为什么呢?

通过上面的例子我们可以知道,要想正常的编译执行 .java 文件,需要两个条件:
1.必须的 jar 包
2.class files 的正确路径
那么我们就来看一下 idea 是否满足这两个条件。

首先必须要有必须的 jar
在这里插入图片描述
我们所依赖的 jar 也都被放进了 classpath
在这里插入图片描述
所以基本 jar 依赖的问题就解决了,
其次,我们需要正确的 class files 路径。
在这里插入图片描述设置了 build 后的路径为 ${PROJECT_ROOT}/target。

在这里插入图片描述设置了 target 的文件路径。通过这两个设置,保证我们自己写的.java 文件的正确路径。至此我们执行
在这里插入图片描述
它就可以正确的跑起来了。

4. 参考

PATH and CLASSPATH
Setting the Class Path

5. 补充

就在刚刚我还好奇为什么一些程序,比如 Flink 。竟然可以不通过 java -jar 或者 java -cp 主方法 的方式来执行( 其实是通过 java -cp 主方法 的方式来执行的)。 我们修改一下 Flink 的启动脚本
# Add HADOOP_CLASSPATH to allow the usage of Hadoop file systems
echo '========================================='
echo $JAVA_RUN
echo $JAVA_ARGS
echo ${log_setting[@]}
classpath=`manglePathList "$CC_CLASSPATH:$INTERNAL_HADOOP_CLASSPATHS"`
echo $classpath
echo '======================================='
exec $JAVA_RUN $JVM_ARGS "${log_setting[@]}" -classpath "`manglePathList "$CC_CLASSPATH:$INTERNAL_HADOOP_CLASSPATHS"`" org.apache.flink.client.cli.CliFrontend "$@"

然后我们在执行一下,看看会发生什么?
这是 $JAVA_RUN
/mnt/jdk8/bin/java
这是 $JAVA_ARGS
空空如野
这是 ${log_setting[@]}
-Dlog.file=/mnt/software/flink-1.7.2/log/flink-wanghaoran-client-bigdata-dev-node-3.log -Dlog4j.configuration=file:/mnt/software/flink-1.7.2/conf/log4j-cli.properties -Dlogback.configurationFile=file:/mnt/software/flink-1.7.2/conf/logback.xml
这是 $classpath,加上了 hadoop conf
/mnt/software/flink-1.7.2/lib/flink-python_2.11-1.7.2.jar:/mnt/software/flink-1.7.2/lib/flink-shaded-hadoop2-uber-1.7.2.jar:/mnt/software/flink-1.7.2/lib/log4j-1.2.17.jar:/mnt/software/flink-1.7.2/lib/slf4j-log4j12-1.7.15.jar:/mnt/software/flink-1.7.2/lib/flink-dist_2.11-1.7.2.jar::/etc/hadoop/conf:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shengjk1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值