java class loader

Problem

In a project, We use a stub jar file generated by Axis2. It always throw: java.lang.NoSuchFieldError: localClientNameTracker

 

While in another project, everything is ok using same jar file. No exception is thrown.

 

CLUE

  1. Guess it's because environment, but has no idea about the cause. 
  2. Clean the project and re-add all the lib in Eclipse, the issue disappear 
  3. If we put axis1 before axis2 on classpath, the issue disappear but the project broken
  4. If we put axis2 before axis1 on classpath, the project ok but the issue occur

 

Suspect

 

It seem because of Axis1 and axis2 jar file conflict,  we need dig into detail to find out which jar cause this conflict.

 

 

diagnosis 

  1. Search the internet, try to find the Axis1 and Axis2 jar conflict, do not any any hit
  2. Search the internet, try to understanding class loader
  •  
    • prints a trace of the class loading process on the console in Eclipse . From an article on IBM java programming dynamics series, part1 Java classes and class loadin g.
    • In Eclipse, we append Eclipse console to the File , Run Configurations -> Common -> Standard Input and Output
    • Use Beyond compare to compare the two trace file, one is success trace, the other is fail trace

Cause

 

jar dependencies

  1. localClientNameTracker is a field in a parent class called ServerReuqest (x.jar)
  2. There is happened another jar file(y.jar) which has same class with exactly same class name and package name, while they are different version.
  3. When add y.jar file before x.jar into classpath, then JVM search y.jar first and load ServerRequest from y.jar file. Then NoSuchFieldError occur 
  4. When add x.jar file before y.jar into classpath, then JVM search x.jar first and load ServerRequest from x.jar file, everything is OK.

Solution1

According to problem solving policy : Try to find another ways which achieve same target but do not this problem. So our first solution is remove two version of same classes. Only keep a latest version of ServerRequest

jar_dependencies_2

 

 

Solution2

How about keep two version of same jar file.  According to Managing Component Dependencies Using ClassLoaders

We can let each jar file have one classloader, see the diagram 

 

class loader

The policy of our class loader

  1. Each Jar file has own class loader, JarClassLoader, which extended from URLClassLoader and load class from a single jar file. If can not load from jar, delegate to AppJarClassLoader.
  2. Add a Customer class loader (AppJarClassLoader ) to boot class path as System class loader, which iterate each JarClassLoader. If can not load from jars, delegate to the parent.    
  3.  If no parent delegation, NoClassDefError may be occur.

 

 

 

postmortem

ClassLoader

 

  • Startup (Main class is loaded by bootstrap class loader, In Sun JVM, Default loaded by AppClassLoader)

The Java virtual machine starts up by creating an initial class, which is specified in an implementation-dependent manner, using the bootstrap class loader (§5.3.1) . The Java virtual machine then links the initial class, initializes it, and invokes its public  class method void  main(String[]) . The invocation of this method drives all further execution. Execution of the Java virtual machine instructions constituting themain  method may cause linking (and consequently creation) of additional classes and interfaces, as well as invocation of additional methods.

At run time, a class or interface is determined not by its name alone, but by a pair: its fully qualified name and its defining class loader. Each such class or interface belongs to a single runtime package . The runtime package of a class or interface is determined by the package name and defining class loader of the class or interface.

 

  • Same Loader (L load c, if c reference d, then L will load d)

Creation of a class or interface C denoted by the name N consists of the construction in the method area of the Java virtual machine (§3.5.4)  of an 

implementation-specific internal representation of C. Class or interface creation is triggered by another class or interface D, which references C through its runtime constant pool. Class or interface creation may also be triggered by D invoking methods in certain Java class libraries (§3.12)  such as reflection.

 

The Java virtual machine uses one of three procedures to create class or interface C denoted by N:

If N denotes a nonarray class or an interface, one of the two following methods is used to load and thereby create C :

If D was defined by the bootstrap class loader, then the bootstrap class loader initiates loading of C (§5.3.1).

If D was defined by a user-defined class loader, then that same user-defined class loader initiates loading of C (§5.3.2).

Otherwise N denotes an array class. An array class is created directly by the Java virtual machine (§5.3.3), not by a class loader. However, the defining class loader of D is used in the process of creating array class C.

 

ClassNotFoundException NoClassDefFoundError

Basic Class Loading problems

 

ClassNotFoundException  but no definition for the class with the specified name could be found.

NoClassDefFoundError  is another common exception thrown by the class loader during the loading phase. The JVM specification defines NoClassDefFoundError  as follows

Essentially, this means that a NoClassDefFoundError  is thrown as a result of a unsuccessful implicit class load.

Java

-verbose:class
Display information about each class loaded.
-verbose:gc
Report on each garbage collection event.
-verbose:jni
Report information about use of native methods and other Java Native Interface activity.
-Xprof
Profiles the running program, and sends profiling data to standard output. This option is provided as a utility that is useful in program development and is not intended to be used in production systems.

-Xbootclasspath: bootclasspath
Specify a semicolon-separated list of directories, JAR archives, and ZIP archives to search for boot class files. These are used in place of the boot class files included in the Java 2 SDK.  Note: Applications that use this option for the purpose of overriding a class in rt.jar should not be deployed as doing so would contravene the Java 2 Runtime Environment binary code license.
-Xbootclasspath/a: path
Specify a semicolon-separated path of directires, JAR archives, and ZIP archives to append to the default bootstrap class path.
-Xbootclasspath/p: path
Specify a semicolon-separated path of directires, JAR archives, and ZIP archives to prepend in front of the default bootstrap class path.  Note: Applications that use this option for the purpose of overriding a class in rt.jar should not be deployed as doing so would contravene the Java 2 Runtime Environment binary code license.



 

Tomcat Classloader

 

Finding a way out of ClassLoader , the author said we have at least 3 choices:

the  system   (also referred to as the  application ) classloader, the  current   classloader, and the current thread  context   classloader. The question above refers to the latter. Which classloader is the right one?

If you choose the system classloader

  As soon as you move your code into an Enterprise JavaBean, a Web application, or a Java Web Start application, things are guaranteed to break.

So let's digg into Tomcat to see how a web concainter using customized class loader.

    

 
So each webapp has own class loader. Tomcat implements it by controlling the App entries: Filter, Listener, Servlet Listener Each StandardContext represent an App
  Filter

Each StandardWrapper is an individual servlet definition. StandardWrapperValue is a pipeline implements the default basic behavior for the StandardWrapper

 

Servlet

 

WebAppClassLoader

It's very important in web class loader, it verfiy the jar file, if it's servlet jar, discard this jar file. So all the interface javax.servlet is loaded from parent class loader while all the implementation is loaded from App class loader

 

OSGI

We do not need define own class loader, Other choice is OSGI

http://www.slideshare.net/stephanj/intro-to-osgi

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

FireCoder

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

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

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

打赏作者

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

抵扣说明:

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

余额充值