When a client says "Code should not have custom classloaders" in Java, what does that exactly mean? What can't I do?
A class loader is an object in Java responsible for finding binary representations of Java classes and loading them into the JVM. All JVMs begin with a boot class loader responsible for loading the user's initial class, along with some of the built-in types like Class and SecurityManager, but users can provide their own class loaders to find classes from other sources. For example, a custom class loader could generate its own classes by composing its own bytecode, or it could find classes from a networked source.
To comply with what your client is asking, you should not define your own class loader and should rely on the boot class loader to find all your classes. This is almost universally what's done in simple Java programs because the use cases for custom boot loaders are usually fairly complex and nuanced. You shouldn't need to worry about this restriction unless you specifically want to change the way that that JVM finds and loads classes.
Custom class loaders are usually used to dynamically generate code or to enhance existing classes.
For example some ORM implementations (JDO) use this to create code that handles translating Java objects to database tables. Other use is in transparent-clustering solutions (like Terracota) where objects are enhanced so that they automatically replicate themselves across the cluster.
This basically prevents you to dynamically generate and inject code into an existing application.
A class loader is an object that is responsible for loading classes. Whenever you instantiate a class using new the runtime system attempts load the class using one or more instances of the ClassLoader abstract class. You can define custom class loaders to load classes from the network, databases, other processes, or any conceivable data source.
So, if your client does not want you to use custom class loaders then be sure to never write a class that extends ClassLoader or any of it's derivatives. Please see the ClassLoader java API docs for more details.
A custom classloader would let you load classes from unconventional sources (from anywhere you can imagine, including out of nowhere, i.e. created on-the-fly). Since your client is saying giving that message, then classes can be loaded only from standard sources (e.g. filesystem, jar files, etc).
Related
My question maybe trivial but after some research I am still not satisfied with the answers I got.
My question is if using a third party class would be more efficient than using java core classes or java libraries.
as far as I know the order of class loaders in java to be invoked
System class loader
Extension class loader
Bootstrap class loader
wouldn't it be more efficient to use a third party jar ( which will be loaded by System class loader) instead of using built in class files, for example suppose I have a huge system which requires sorting many times, and lets suppose the algorithm I am planning to use is merge sort , so typically I would go on with using
Collections.sort()
But wouldn't it be more efficient if I implement it myself and used it so I can get it from the first class loader?
The first class loader is the builtin class loader which is why it's not trivial to write your of Collections class.
Classes are only loaded once so where they came from after loading doesn't matter to performance. Even on the first time, it is unlikely to matter much.
BTW The System (your code) class loader comes last.
Even if this were not the case, the builtin classes are often optimised in ways which are not apparent in the Java code and you couldn't write yourself. i.e. the JVM just replaces some methods with hand crafted native code. (Called intrinsics)
Java has 3 class loaders:
BootStrap,
Extension and
System
and they have one role; loading classes from different packages.
But why does Java have 3 different class loaders instead of just one, since one class loader can load all the necessary classes?
The reason for having the three basic class loaders (Bootstrap, extension, system) is mostly security.
Prior to version 1.2 of the JVM, there was just one default class loader, which is what is currently called the "Bootstrap" class loader.
The way classes are loaded by class loaders is that each class loader first calls its parent, and if that parent doesn't find the requested class, the current one is looking for it itself.
A key concept is the fact that the JVM will not grant package access (the access that methods and fields have if you didn't specifically mention private, public or protected) unless the class that asks for this access comes from the same class loader that loaded the class it wishes to access.
So, suppose a user calls his class java.lang.MyClass. Theoretically, it could get package access to all the fields and methods in the java.lang package and change the way they work. The language itself doesn't prevent this. But the JVM will block this, because all the real java.lang classes were loaded by bootstrap class loader. Not the same loader = no access.
There are other security features built into the class loaders that make it hard to do certain types of hacking.
So why three class loaders? Because they represent three levels of trust. The classes that are most trusted are the core API classes. Next are installed extensions, and then classes that appear in the classpath, which means they are local to your machine.
For a more extended explanation, refer to Bill Venners's "Inside the Java Virtual Machine".
The main usage of class loaders is in application servers.
You want to be able to start Tomcat (for example). This already needs at least one classloader to run tomcat itself.
Then you want to be able to deploy an application into Tomcat. So Tomcat itself needs to load an analyze the classes of the application, which didn't even exist when Tomcat was started.
Then you want to be able todeploy another application in Tomcat. Maybe this second application uses a library that the first one also uses, but in a different version. So you want each app to have its own isolated class loader, otherwise the classes of app 2 might interfere badly with the classes from app 1.
Then you want to be able to undeploy one of the webapps. So its class loader must be destroyed and garbage-collected, to avoid a huge memory leak.
There are of course many other usages, but that's the one that is the most commonly used (in my experience).
Multiple class loaders are present to load multiple applications
simultaneously(One to load Server & Other to deploy in the server).
Each loader has a hierarchy to load only certain
classes to ensure security among them.
In general, how can I write programs to accommodate modding or plugins? Is every method wrapped with other behaviors? All my searching has led to are resources for writing plugins and mods themselves; I can't find anything on writing the systems. With regards to java, how do I expose internal portions of the logic to other systems without using reflection?
One way to do this is by creating your own ClassLoader that can load classes from a specified location that is not on the system classpath. (If it is on the system classpath, the system ClassLoader will find the classes first and you won't be able to unload them.) Creating instances requires a bit of reflection, but once they're created you can treat them just like any other instances.
This works because although only the custom ClassLoader knows about the actual class of those instances, it gets its definition of their superclass (your plugin class or interface) from the system ClassLoader. Therefore, other classes loaded by the system ClassLoader (i.e., the rest of your program) can reference those dynamically created instances by their superclass.
I've used Brian's Clapper's utility library to find classes that extend my plugin class.
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.
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.