Linux上关于Tomcat启动时与jdk环境变量设置的关系

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目录类加载器类加载器的父亲
Bootstrapapache-tomcat-*\bin\bootstrap.jarsun.misc.Launcher$AppClassLoadersun.misc.Launcher$ExtClassLoader
ZipFileAttributeView\jdk\jre\lib\ext\zipfs.jarsun.misc.Launcher$ExtClassLoadernull
Stringjdk\jre\lib\rt.jarnullnull
HashMapjdk\jre\lib\rt.jarnullnull
	这里类加载为null的表示,该类的类加载器我们无法获取,它不是由Java实现的。jdk\jre\lib和 jdk\jre\lib|ext\里面的jar包中的类分别由BootStrapClassLoader(非Java实现)和ExtClassLoader,而tomcat中bootstrap.jar包下的类是由AppClassLoader实现的

jdk jre中自带rt.jar包和jre\lib\ext中的类,加载时,jvm会自动寻找,并且有不同的类加载去加载?验证代码如下

在这里插入图片描述
路径D:\test 下面的, HelloWorld.java,只引用jdk自带的jdk\jre\lib和jdk\jre\lib\ext下面jar包中的类

	import sun.net.spi.nameservice.dns.DNSNameService;

	import java.util.HashMap;
	import java.util.Map;
	
	public class HelloWorld {
	
	    /**
	     * 引用String, jdk\jre\lib\rt.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,jdk\jre\lib\ext\dnsns.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 jdk\jre\lib\rt.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,jdk\jre\lib\ext\dnsns.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 jdk\jre\lib\rt.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,jdk\jre\lib\ext\dnsns.jar
        DNSNameService t2 = new DNSNameService();

        // customized class
        Xiaomiing xiaomiing = new Xiaomiing("1205130232", "Jack");
        System.out.println(xiaomiing);
    }
}

再次编译,如下图
在这里插入图片描述
这里可见自己定义的类似需要指明路径的,将编译后的自定义类拿到目录文件夹
在这里插入图片描述
在这里插入图片描述
再次编译,运行成功,如下图
在这里插入图片描述
如果换一种方式来编译,如下图,报错了,为什么
请注意:这里-classpath并不会为javac编译器提供任何引导作用,所以需要直接指明要编译的源文件的具体位置
请注意:这里-classpath并不会为javac编译器提供任何引导作用,所以需要直接指明要编译的源文件的具体位置

编译成功后,运行,如下
在这里插入图片描述
这里我们可以看到-classpath可以为java解释器提供类位置的引导作用

总结

	综上可知,得出如下结论:
	1.java jdk里面自带的jar包是由java运行时环境自动加载的,并且不同的lib目录下jar包里面的类由不同的类加载器加载,这里要提醒一下jre\lib下		      的jar包并不是所有的都会被bootStrapClassLoader加载,但是jre\lib\ext下的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包添加到类路径
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值