Java Class Loaders [closed] - java

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
Can anyone point me a good resource or explain me about the concept behind Class Loaders? I found the following resource on class loaders http://www.onjava.com/lpt/a/5586 but still no help. The following questions may look silly but trying to answer them always confuses me.
Why do developers write Custom class loaders, why not invoke a Bootstrap class loader to invoke your custom classes? What is the need to define custom class loaders?
Why there are so many varieties of class loaders? eg: Bootsrap, Comman, Catalina class loader etc.,
Thanks in advance.

I found the following, valid reasons to create custom classloaders:
You want to load a class from an unconventional source (For example, the bytecode for one class is stored in a database, across the network or carried as 0 and 1s by pidgeons - MessengerPidgeonClassLoader). There is some ClassLoader implementations already in the API for such cases, such as URLClassLoader.
You need to define a different hierarchy to load classes. Default implementations of the ClassLoader delegate the search first to the parent, then they try to load the class themselves. Maybe you want a different hierarchy. This is the reason why OSGI and Eclipse have its own ClassLoaders as the Manifest .MF files define all types of weird hierarchy paths (buddy-classloading, for example). All Eclipse classloaders implement the BundleClassLoader interface and have some extra code to find resources within Eclipse Plugins.
You need to do some modification to the bytecode. Maybe the bytecode is encrypted, and you will unencrypt it on the fly (Not that it helps, really, but has been tried). Maybe you want to "patch" the classes loaded on the fly (A la JDO bytecode enhancement).
Using a different classloader than the System Classloader is required if you need to unload classes from memory, or to load classes than could change their definition at runtime. A typical case is an application that generates a class on the fly from an XML file, for example, and then tries to reload this class. Once a class is in the System Classloader, there is no way to unload it and have a new definition.

A common use of classloaders is to isolate a JAR. If you have an application which uses plugins (Eclipse, Maven 2), then you can have this situation: Plugin X needs jar A with version 1.0 while plugin Y need the same jar but version 2.0. X does not run with version 2.0, though.
If you have classloaders, you can create partitions of classes (think of isolated islands connected by thin bridges; the bridges are the classloaders). This way, the classloaders can control what each plugin can see.
When plugin X instantiates a class Foo, which has static fields, this is no problem and there won't be a mixup with the "same" class in plugin Y because each classloader will in fact create its own instance of the class Foo. You then have two classes in memory, where cl1.getName().equals(cl2.getName()) is true but cl1.equals(cl2) is not. This means that instances of cl1 are not assignment compatible to instances of cl2. This can lead to strange ClassCastExceptions which say that org.project.Foo can't be assigned to org.project.Foo.
Just like with remote islands, the two classes are not aware that the other one exists. Think of human clones which are born and then raised on different islands. From the point of view of the VM, there is no problem because instances of the type Class are handled like any other object: There can be several of them. That you think that some of them are "the same" doesn't matter to the VM.
Another use for this pattern is that you can get rid of classes loaded this way: Just make sure that no one has a pointer to any object created from classes loaded from a classloader and then forget about the classloader, too. On the next run of the GC, all classes loaded by this classloader are removed from memory. This allows you to "reload" your application without having to restart the whole VM.

Another good link for java class loaders - Java classloaders

A couple blogs I've written in the deep past about using post-delegation classloaders:
Writing a post-delegation classloader
A Tale of Two Classloaders

You can't go past the raw source, in cases like this. If you really want the inside dope, the hard core, read the relevant bits of the Java Virtual Machine Specification.

It's extremely rare that you need to create your own ClassLoader. And genereally if you need to, you should already have a really good understanding of what the ClassLoader does.
In other words, if you're asking why you would need to create your own ClassLoader, then you don't need to create one ;)
That being said, I've also seen a ClassLoader being created for an application that dealt with cryptography. This way every time you create a java.netSocket or some kind of file/stream object, instead of using the JVM versions it would use their own special custom built classes. This way they could guarantee the that all information was encrypted and that there were no developer errors.
But it's not very common. You can go a whole Java career without ever needing to create your own custom ClassLoader. Actually if you need to create one, you should really ask if it's necessary.

An example:
Tomcat use customized WebAppClassloader to load and isolate classes/jars from different web applications.

Why do developers write Custom class loaders, why not invoke a Bootstrap class loader to invoke your custom classes? What is the need to define custom class loaders?
Depending on the application, the developers might override or completely replace the class loading mechanism to suit their needs.
For instance, I have used one application whose classes are loaded from a LDAP :S
Other apps need independent class managing ( like most of the application servers that support hot-deploy )
About resources, there are TONS, in the web, that simply cannot be listed.

Related

use of fragments over plugin

In my project, I could see all the JUnit Test cases are written
in eclipse fragments not in eclipse plugin. And we do run each test classes
as JUnit plugin. I am not very much
clear about the concepts. I am relatively new to this concept.
I just googled to get better knowledge about using fragments over Plugins for Tests.
What I have understood is, fragments and host plugins share the
same class loader.Please correct me if my understanding is wrong.
However I did not understand the meaning of the below line.
If we create the tests in eclipse plugin, test classes will be loaded by a separate Classloader and will therefore not have access to the non-public methods of the classes under test.
Why it does not have access to the non-public methods? can any one help me in understanding the meaning of the above with simple example?
To understand this you need to understand how classes and classloading actually works in Java. Often we think of loading in terms of 'the classpath', but this is a massive simplification of how things work. In many Java SE envrionments this just works, but in multi-tenanted environments like OSGi it gets more complicated.
Essentially in Java classes are scoped by three things:
Name
Package
ClassLoader
It is perfectly possible to have two instances of myPackage.MyClass loaded in the JVM at more than once, you just need multiple classloaders. Even though these classes could be loaded from identical .class files they will be different at runtime. This can cause much confusion when you write code like this:
MyClass c = (MyClass)obj;
and get a ClassNotFoundException: MyClass.
Classes exist in packages and there are special visibility rules associated with this. Types, methods and fields with no stated visibility are visible to all types in the same package. When a class is loaded it gets associated with a java.lang.reflect.Package and the visibility rules are resolved by essentially checking that the classes are associated with the same java.lang.reflect.Package instance. So in the case of mypackage.MyClass if you load it twice using two different classloaders you will get two Package instances for mypackage.
OSGi is designed to support multi-tenanted class loading, this is what allows you to have two different versions of a class or package in the same JVM at once. This solve many problems caused if you have different version dependencies. It implements this by using a different Classloader for each bundle. Fragments work differently that bundles in that they are associated with a bundle and classes in them are loaded by the bundle's Classloader rather than having their own one.
To relate this back to your original question if you put your junit tests in a bundle (rather than a fragment) your class will be loaded by a different classloader, so it'll be associated with a different instance of java.lang.reflect.Package so when the JVM tests for member accessability it will fail.

What is an isolated classloader in Java?

When trying to solve this problem, I encountered some articles, etc. referring to "isolated" ClassLoaders. I was unable to find a definition for isolated classloader via Google search, so maybe the term is not widely-known jargon, and perhaps has a different meaning in different contexts.
Anyway, Maven's surefire plugin can use an isolated ClassLoader: http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html
Also one of the answers below references an article explaining how to create an "isolated" ClassLoader.
Neither reference above gives a definition for an isolated ClassLoader; they seem to assume the reader knows what that means or can look it up. However, the second link does include a hint as to what it means by "isolated":
Bootstrapping lets you run your container without polluting the system classpath. This allows you to run your deployed applications with the unpolluted system classpath as its parent. You’ve achieved classloader isolation.
But I'm not quite clear on what is isolated from what and how from this paragraph or the rest of the article. I see that he's loading one version of a class w/o overriding / overwriting another version--maybe one classloader is isolated from another by being different instances w/o one being the parent of the other? I'm not sure.
I especially covet a Google or SO search link that contains a link clearly holding the answer. A direct link to an answer works too. :)
The author is using the term "isolation" basically to mean that the bootstrap classloader for the JVM (the "main" classloader) doesn't have any extra jars/classes in it (just one simple class which in turn sets up the child classloader(s)). The article isn't real obvious as to why this is "isolated" because it only sets up one child classloader. The "isolation" term becomes more obvious when you setup more than one child classloader. These children will be isolated from each other in that they won't share any classes (other than the core JRE classes). Thus, you can do things like have each child use a different version of the same jar.
Here's how to create an isolated classloader, you'd create one any time you want an unpolluted system classpath, useful for bootstrapping Java programs.
From my understanding from the article that you linked to that an isolated class loader is a class loader that is separate to the main system class loader. That is, classes loaded by the isolated class loader won't be available to every class in JRE (only the ones that the isolated class loader loaded itself [and any classes loaded by any child class loaders]).
This could be useful because two of your dependencies might require different versions of the same library to run. That is, your dependencies might expect to see different instantiations of the same class in the library. Thus giving them two separate isolated class loaders will allow them to load the classes they require and not interfere with each other.
By default classloaders form a tree with the system classloader at the root. New child classloaders will by default ask their parent first if it can load the class, and if not, load from their own sources.
The goal of an isolated classloader is to isolate yourself from the parent classloaders by checking your own sources FIRST, then your parent SECOND, so reversing the order. This allows you to create a new classloading context where you control the first place to look. You still want to fallback to the parent chain so you can load things like the jdk etc.
You also need to take care that the isolated classloader return instances of interfaces defined in the parent classloader, or else you will run into LinkageErrors or other issues.
Here's an article I wrote in 2006, but it's still fairly relevant (it's incomplete with respect to resource loading and the apis have changed a bit over the years):
http://tech.puredanger.com/2006/11/09/classloader/

How to use two incompartible classes with same full name?

A problem: My application uses two libraries which use incompatible versions of a third library. Does someone know any method for classes isolation?
I have heard about class loaders, but I do not understand, how they could help - if we will load one version of class, we cannot load another - class is already loaded?
I also thinking about Spring, but do not know if it provides such isolation.
ClassLoaders are basically the elements that gives meaning to classes in the JVM. They form a hierarchy for wich the root lies in the JVM and loads java classes. The ApplicationClassLoader is the first ClassLoader you have to consider, as it loads all the classes of your application.
When a class is loaded, all its references to other classes are resolved and theses classes are loaded. The JVM by default provides a system where classloaders ask their parent first to see if they have already loaded a class. If not, they search in their classpath
Two classes can be isolated if they live in 2 different classloader, and not in the app classloader. It's not difficult to do. You only have to create a classloader (like URLClassLoader) while specifying its parent and its classpath(the place where the bytecode is)
then, you tell him to load a class. It will ask its parent, and if the class is not loaded yet, it will search its classpath and load it. If you create another classloader attached to the same parent, the classes loaded by the first will never be seen by the seconds as they are siblings. And the second can loads a class with the same name without any problem
That's quite a good isolation
App Servers use another form of delegation to have a frank isolation between applications. they redefine a classloader extending, for example, URLClassLoader and reverse the delegation process by starting to search for classes in their classpath first, then ask to the parent
if we will load one version of class, we cannot load another - class
is already loaded?
Not true. The class loader is considered part of the class's identity. If it's loaded by a different classloader, it's considered a different class.
If at least one of the libraries is open source, and the library they depend on is open source, no need for messing about with classloaders. Just bulk rename all the packages in one of the versions of the library being depended on, making sure to also change all code which refers to those packages. Hey presto - no name clashes. This is what Sun actually did for the JDK, when they included Xerces and Xalan behind the scenes.

Java, runtime class reloading

I am looking for a way to reload a class into Java at runtime. The motivation is to make debugging more efficient. The application is a typical client/server design that synchronously processes requests. A "handler" object is instantiated for each request. This is the only class I intend to dynamically replace. Since each request deals with a fresh instance, reloading this class won't have any side-effects. In short, I do not want to restart the entire application every time there is a change to this module.
In my design, the Java process becomes aware that a .class file has been updated in the classpath in between requests. When this happens, the "handler" class is unloaded and a new one is loaded.
I know I can use the classLoader interface to load in a new class. I seem to be having trouble finding the proper way of "unloading".
Classes will be unloaded and garbage collected like any other object, if there is no remaining reference to them. That means there must be no reachable instance of the class (as loaded by that particular classloader instance) and the classloader instance itself must be eligible for garbage collection as well.
So basically, all you have to do is to create a new classloader instance to load the new version of the class, and make sure that no references to instances of the old version remain.
I believe that you actually need to have a hierarchy of classloaders, and in order to reload you actually get rid of the low level classloader (by normall GC means), and hence all the classes it loaded. So far as I know this technique is used by Java EE app servers for reloading applications, and there's all manner of fun results when framework code loaded in one classloader wants to use classes loaded somewhere else.
As of 2015 also java's class reloading is a missing feature.
Use OSGi to create a class reloading application.
Use jrebel for testing. There are a few others which does the same thing.
Use application server and externalize the parts which you want to reload into a separate web application. Then keep deploying/undeploying. You will eventually get some perm gen space overflow kind of errors due to dangling old ClassLoader instances.
Use a script runner to execute parts of changeable code. JSR-223 Java Scripting API support for the scripting language "Java".
I had written a series about class reloading. But all of those methods are not good for production.
The blog and source codes in google sources
IMHO this class reloading is messy in java and its not worth trying it. But I would very much like this to be a specification in java.

Class Loading to an interface

I'm quite restricted in the platform I'm currently working on (JDK 1.3, BD-J). One JAR file I would like to use attempts to perform a self-integrity check on load and if it fails it goes into an inoperable state. It's quite difficult to find out why this is happening but most sources point to that it cannot find/access it self through the BD-J structure, so it dies.
This rules out using it at load time and instead to load it in the application itself. This is quite a large library so I have to create quite an amount of interfaces so I can cast a loaded object to it and potentially use it. This is where my problem lies.
The interfaces are loaded on normal load time and the library is then loaded during run time and casted to the previously loaded interfaces, is this a problem? I'm receiving ClassCastException
I've based the interfaces off the libraries public methods as best I can, but when I attempt to cast to an interface I receive the ClassCastException. Note: It all loads fine, I can access constructors and read the method names. Just when casting it for it to be useable it fails.
The interface packages are different in my project to that of the toolkit, does this matter?
I'm running out of ideas, is there something I have overlooked?
Thanks.
I'm not sure I fully grok what your problem is - maybe some more details about what the class hierarchy looks like would help in figuring out the situation. From what you wrote I can guess two possible scenarios:
.1. The classes you want to use do not implement any interface.
In this case no matter what you name your interfaces, it will not work, since the classes you're loading do not implement them. You're stuck with using reflection if you can't load that jar as part of the boot classpath.
.2. The classes you want implement some interface that you're trying to replicate.
In this case you interface implementation must match the exact qualified name of the interface the classes are implementing. Normally, when loading the classes from the jar, the class loader will pick up the interfaces from the system class loader first, thus loading your interfaces, and everything should work.
If they use some crazy internal class loader, though, they might still try to load their own interfaces. You could try to figure out if that's the case by using "-XX:+TraceClassLoading", although I don't know if the 1.3 jre will understand that option.
Now if you're willing to experiment more, you could also try another approach. Write your own class loader that loads both the classes from that jar and the code you want to run. That way, your code would be able to directly refer to the classes in that jar, but to start your application the "main" method will have to be one that initializes this classloader, loads the "real" main class using reflection, and executes its main() method also via reflection.
Most probably the classes are loaded by different class loaders. http://mindprod.com/jgloss/classloader.html may give some idea.

Categories