概述
catalina.sh部分shell代码剪切
shift
touch "$CATALINA_OUT"
if [ "$1" = "-security" ] ; then
if [ $have_tty -eq 1 ]; then
echo "Using Security Manager"
fi
shift
eval $_NOHUP ""$_RUNJAVA"" ""$LOGGING_CONFIG"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS
-Djava.endorsed.dirs=""$JAVA_ENDORSED_DIRS"" -classpath ""$CLASSPATH""
-Djava.security.manager
-Djava.security.policy==""$CATALINA_BASE/conf/catalina.policy""
-Dcatalina.base=""$CATALINA_BASE""
-Dcatalina.home=""$CATALINA_HOME""
-Djava.io.tmpdir=""$CATALINA_TMPDIR""
org.apache.catalina.startup.Bootstrap "$@" start
>> "$CATALINA_OUT" 2>&1 "&"
else
echo "======================================================================================================"
echo "打印启动详细的参数及路径 $_NOHUP $_RUNJAVA $LOGGING_CONFIG $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS
-Djava.endorsed.dirs=$JAVA_ENDORSED_DIRS -classpath $CLASSPATH
-Dcatalina.base=$CATALINA_BASE
-Dcatalina.home=$CATALINA_HOME
-Djava.io.tmpdir=$CATALINA_TMPDIR
org.apache.catalina.startup.Bootstrap $@ start"
echo "======================================================================================================"
echo "=============================================执行启动如下======================================="
eval $_NOHUP ""$_RUNJAVA"" ""$LOGGING_CONFIG"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS
-Djava.endorsed.dirs=""$JAVA_ENDORSED_DIRS"" -classpath ""$CLASSPATH""
-Dcatalina.base=""$CATALINA_BASE""
-Dcatalina.home=""$CATALINA_HOME""
-Djava.io.tmpdir=""$CATALINA_TMPDIR""
org.apache.catalina.startup.Bootstrap "$@" start
>> "$CATALINA_OUT" 2>&1 "&"
fi
if [ ! -z "$CATALINA_PID" ]; then
echo $! > "$CATALINA_PID"
fi
echo "Tomcat started."
elif [ "$1" = "stop" ] ; then
shift
执行./startup.sh后控制台打印如下
======================================================================================================
打印启动详细的参数及路径 /usr/local/jdk1.7.0_79/bin/java -Djava.util.logging.config.file=/usr/local/apache-tomcat-7.0.70/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048
-Djava.endorsed.dirs=/usr/local/apache-tomcat-7.0.70/endorsed -classpath /usr/local/apache-tomcat-7.0.70/bin/bootstrap.jar:/usr/local/apache-tomcat-7.0.70/bin/tomcat-juli.jar
-Dcatalina.base=/usr/local/apache-tomcat-7.0.70
-Dcatalina.home=/usr/local/apache-tomcat-7.0.70
-Djava.io.tmpdir=/usr/local/apache-tomcat-7.0.70/temp
org.apache.catalina.startup.Bootstrap start
======================================================================================================
=============================================执行启动如下=======================================
Tomcat started.
从这里看出-classpath /usr/local/apache-tomcat-7.0.70/bin/bootstrap.jar:/usr/local/apache-tomcat-7.0.70/bin/tomcat-juli.jar是保证tomcat能被启动的基础,将一个含有主类的jar包加入类路径,同时在运行过程中依赖的类的jar包也添加进类路径
问题: JDK里面的那些Tomcat用到的jar包由谁加载呢?不需要指定其具体位置吗?
测试不同lib目录下jar包里面的类加载器及其父亲加载器
System.out.println(System.getProperty("user.dir"));
ClassLoader t1 = Bootstrap.class.getClassLoader();
System.out.println("Bootstrap classloader: " + t1);
ClassLoader t2 = ZipFileAttributeView.class.getClassLoader();
System.out.println("ZipFileAttributeView classloader: " + t2);
ClassLoader t3 = String.class.getClassLoader();
System.out.println("String classloader: " + t3);
ClassLoader t4 = HashMap.class.getClassLoader();
System.out.println("HashMap classloader: " + t4);
ClassLoader t1Loader = t1.getClass().getClassLoader();
System.out.println(t1 + "的classLoader: " + t1Loader);
ClassLoader t2Loader = t2.getClass().getClassLoader();
System.out.println(t2 + "的classLoader: " + t2Loader);
运行结果如下
Bootstrap classloader : sun.misc.Launcher$AppClassLoader@18b4aac2
ZipFileAttributeView classloader: sun.misc.Launcher$ExtClassLoader@50675690
String classloader : null
HashMap classloader : null
sun.misc.Launcher$AppClassLoader@18b4aac2的classLoader: null
sun.misc.Launcher$ExtClassLoader@50675690的classLoader: null
值得一体的是他们分属的lib目录如下
类名 | lib目录 | 类加载器 | 类加载器的父亲 |
---|---|---|---|
Bootstrap | apache-tomcat-*binbootstrap.jar | sun.misc.Launcher$AppClassLoader | sun.misc.Launcher$ExtClassLoader |
ZipFileAttributeView | jdkjrelibextzipfs.jar | sun.misc.Launcher$ExtClassLoader | null |
String | jdkjrelibrt.jar | null | null |
HashMap | jdkjrelibrt.jar | null | null |
这里类加载为null的表示,该类的类加载器我们无法获取,它不是由Java实现的。jdkjrelib和 jdkjrelib|ext里面的jar包中的类分别由BootStrapClassLoader(非Java实现)和ExtClassLoader,而tomcat中bootstrap.jar包下的类是由AppClassLoader实现的
jdk jre中自带rt.jar包和jrelibext中的类,加载时,jvm会自动寻找,并且有不同的类加载去加载?验证代码如下
路径D:test 下面的, HelloWorld.java,只引用jdk自带的jdkjrelib和jdkjrelibext下面jar包中的类
import sun.net.spi.nameservice.dns.DNSNameService;
import java.util.HashMap;
import java.util.Map;
public class HelloWorld {
/**
* 引用String, jdkjrelibrt.jar中
*/
public static void main(String[] args) throws Exception {
System.out.println("hello world");
Map<String, String> map = new HashMap<String, String>();
System.out.println(map.size());
// DNSNameService,jdkjrelibextdnsns.jar
DNSNameService t2 = new DNSNameService();
// 引用自定义的类
// Xiaomiing xiaomiing = new Xiaomiing("1205130232", "Jack");
// System.out.println(xiaomiing);
}
}
剔除本机环境下设置的CLASSPATH变量
检测是否剔除成功,如下图所示,是成功的
编译HelloWorld.java
有中文报错(对记住,命令行模式下,这里不能有中文),改成英文后,代码如下
import sun.net.spi.nameservice.dns.DNSNameService;
import java.util.HashMap;
import java.util.Map;
public class HelloWorld {
/**
* get reference form java.lang.String in jdkjrelibrt.jar
*/
public static void main(String[] args) throws Exception {
System.out.println("hello world");
Map<String, String> map = new HashMap<String, String>();
System.out.println(map.size());
// DNSNameService,jdkjrelibextdnsns.jar
DNSNameService t2 = new DNSNameService();
// customized class
// Xiaomiing xiaomiing = new Xiaomiing("1205130232", "Jack");
// System.out.println(xiaomiing);
}
}
再次编译,如下图,成功,但是我此时并没有指定要引用的这些jar包路径在哪,由此可见是jdk自己寻找的
运行代码,这个地方要注明自己编译的类所在的地方
将自定义的代码注释放开,源码如下
import partner.pals.Xiaomiing;
import sun.net.spi.nameservice.dns.DNSNameService;
import java.util.HashMap;
import java.util.Map;
public class HelloWorld {
/**
* get reference form java.lang.String in jdkjrelibrt.jar
*/
public static void main(String[] args) throws Exception {
System.out.println("hello world");
Map<String, String> map = new HashMap<String, String>();
System.out.println(map.size());
// DNSNameService,jdkjrelibextdnsns.jar
DNSNameService t2 = new DNSNameService();
// customized class
Xiaomiing xiaomiing = new Xiaomiing("1205130232", "Jack");
System.out.println(xiaomiing);
}
}
再次编译,如下图
这里可见自己定义的类似需要指明路径的,将编译后的自定义类拿到目录文件夹
再次编译,运行成功,如下图
如果换一种方式来编译,如下图,报错了,为什么
请注意:这里-classpath并不会为javac编译器提供任何引导作用,所以需要直接指明要编译的源文件的具体位置
编译成功后,运行,如下
这里我们可以看到-classpath可以为java解释器提供类位置的引导作用
总结
综上可知,得出如下结论:
1.java jdk里面自带的jar包是由java运行时环境自动加载的,并且不同的lib目录下jar包里面的类由不同的类加载器加载,这里要提醒一下jrelib下 的jar包并不是所有的都会被bootStrapClassLoader加载,但是jrelibext下的jar包确都会被Launcher$ExtClassLoader加载,比较幸运的是tomcat运行用到的jdk的jar包中的类都被bootStrapClassLoader和Launcher$ExtClassLoader加载了
2.当编译一个java源文件时,引用到jdk里面自带的、 ‘被bootStrapClassLoader和Launcher$ExtClassLoader加载’的jar包的类时,无需将这些jar包添加到类路径中区,java虚拟机会自动去指定的地方寻找
3.但是如果是用户自定义的类被该源文件引用,则需要将该自定义的类的根路径添加到类路径下面以辅助javac编译器来编译该源文件
4.-classpath不会为javac编译器指明源文件的位置,因此我们需要将源文件的具体路径一并写上
5.-classpath 会为java解释器提供引导作用,告诉java解释器,类的具体位置
6.Tomcat相当于是一个指定的软件包,启动tomcat时,需要将其要使用的jar包添加到类路径
最后
以上就是冷艳银耳汤为你收集整理的Linux上关于Tomcat启动时与jdk环境变量设置的关系catalina.sh部分shell代码剪切问题: JDK里面的那些Tomcat用到的jar包由谁加载呢?不需要指定其具体位置吗?总结的全部内容,希望文章能够帮你解决Linux上关于Tomcat启动时与jdk环境变量设置的关系catalina.sh部分shell代码剪切问题: JDK里面的那些Tomcat用到的jar包由谁加载呢?不需要指定其具体位置吗?总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复