JNDI使用
应用场景
通过javaagent方式引入增强包,对JVM中的用户自定义类的方法(写在应用中的某个配置文件)进行增强,在Tomcat容器中启动时报无法找到配置文件的异常,通过对比Worker类型的应用,发现ClassLoader类型及加载机制不同造成。
- Tomcat 类型使用WebAppClassLoader加载应用,配置文件可以通过WebAppClassLoader可以获取;
- Worker类型使用AppClassLoader加载应用,配置文件可以通过AppClassLoader获取。
上述两种类型中,javaagent方式引入的增强包都在AppClassLoader中,从而导致Tomcat类型应用在启动时无法找到WebAppClassLoader中的配置文件,导致报异常。
解决方案
方案 一
- 同用户约定待增强方法的配置文件目录路径,然后在增强包中写死,程序运行时按约定路径去取配置文件;
- 开发时发现,J-one/jdos 对Tomcat类型提供的配置文件路径为相对路径,及后半部分路径,只提供给用户WEB-INF/后面的路径供用户选填写。由于每个应用的前半部分路径每个都不一样,所以导致无法同用户约定目录路径。
方案二
采用JNDI 方式,打破双亲委派的ClassLoader的加载机制,在Tomcat启动后,在增强包中获取WebAppClassLoader类加载器,从而获取到用户的配置文件。
classLoader原理
jvm有三种加载器,每种加载器负责特定目录的类。
- 根类加载器(BootStrap)和扩展加载器(Extension)不必说,它们负责加载的都是特定目录的类,而且这些类是固定的,我们不能说我们把自己编写的类加到java.lang目录下就能使这个类被根类加载器加载,那样就太不安全了。因为加载的类是固定的就很好理解,
- 但是系统类加载器(System)就比较不好理解了,它是加载classpath定义的目录下的类