JNDI使用

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定义的目录下的类