How does JVM deal with dynamic classes - java

Class definitions are stored in the Method Area, as the Java Virtual Machine Specification says (The Java® Virtual Machine Specification Java SE 7 Edition):
The method area is created on virtual machine start-up. Although the
method area is logically part of the heap, simple implementations may
choose not to either garbage collect or compact it.
As we know, some bytecode tools like ASM, cglib, javassist, Hibernate and Spring frameworks are using them. For a common class file, JVM loads and parses and initializes and finally uses it, I am confused about how does JVM deal with the classes generated by bytecode tools dynamically. My questions are:
If JVM loads, parses and initializes the dynamic classes as the common class file?
Are they stored in the Method Area as well?
How does JVM unload and clean the dynamic class definitions to prevent itself from occurring an OutOfMemoryError?

All class are loaded at runtime, possibly compiled to native code. As such there is nothing special about class generated after the program has started.
If JVM loads, parses and initializes the dynamic classes as the common class file?
It loads the same way as class which existed when the program started.
Are they stored in the Method Area as well?
They are stored the same way in fact it is hard to tell if a class is dynamic or not.
How does JVM unload and clean the dynamic class definitions to prevent itself from occurring an OutOfMemoryError?
The JVM can unload classes when the ClassLoader they are in is unloaded. This is true whether the classes are dynamic or not.
how could the JVM know to treat dynamic classes any differently than 'normal' classes?
There is one example of dynamic classes which are special. These are the lambda classes which are generated at runtime. What makes them different is they are not bound to a class loader, they don't even have a normal class name. They get unloaded when all the instances of that class are unused.
From InnerClassLambdaMetafactory
UNSAFE.defineAnonymousClass(targetClass, classBytes, null);
The class has no class name attached to it (nor a ClassLoader)

There is no difference between .class data on the file system, inside a jar file or dynamically created by tools like ASM.
In fact when the class loader loads the class, it's just a byte[] how that byte array is populated with .class data is up to the class loader to get it from the filesystem, inside a jar or zip file, from a URL, dynamically generated etc.
If JVM loads, parses and initializes the dynamic classes as the common class file?
As I said it is exactly the same. The JVM doesn't know the difference.
Are they stored in the Method Area as well?
Again, JVM doesn't know the difference so I guess.
How does JVM unload and clean the dynamic class definitions to prevent itself from occurring an OutOfMemoryError
The same way as non-dynamic classes. by unloading although I don't know how often this happens

Related

How can my code accommodate modding/plugins?

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.

Class Loading: Compile time or Runtime

Is java class loaded at compile time or Runtime? I know you can dynamically load a java class using your own Class Loaders or calling Class.forName("fully qualified name of java file").
But if I am not using any of the above techniques then does it means that Java classes are loaded at compile time?
No. The JLS explains how loading and linking is runtime. Any binary-compatible revision of a class can be thrown in place of an existing class.
A class is compiled with a symbolic reference to other classes, not the code of those classes.
However with certain non-JVM compilers like GCJ classes can be compiled ahead of time into one executable.
Classes are loaded at runtime to execute their code.
Classes are loaded at compile time to check code using the class for type safety.
Whenever you write code that uses a class (eg, calling a method on it), the compiler needs to load that class to make sense of your code (eg, to check methods or base type)
At compile time nothing is loaded. At compile time classes are just generated from sources.
The difference could be if a class is loaded by the ClassLoader when the JVM powers up or if you do it dynamically during the execution, but they are two sides of the same medal.
In both cases they are loaded dynamically, but in the former this is done as soon as the JVM starts.
As many others have stated, classes are loaded at runtime unless you are using an AOT compiler to allow them to run in non-JVM environments. If you want to read up all the details on how the Java Virtual Machine starts up, initializes and loads the first then subsequent classes you can take a look at the Java SE 7 specifications.

Tomcat class-reloading for JSPs

How does class-reloading works in Tomcat when it comes to reloading JSPs (I am talking about the internal architecture)?
I know that each JSP is compiled to a Java class. But how does the classloader (which is unique per web application) reload these generated classes given that a classloader does not allow class unloading and without collecting too much garbage?
A JasperLoader instance is the classloader loads jsp generated servlets.
The jsp compiler "throw away" (set to null) the old JasperLoader instance when it generates a newer servlet class file.
Quote from the comments in JspServletWrapper.setServletLastModifiedTime:
Really need to unload the old class but can't do that. Do
the next best thing which is throw away the JspLoader so
a new loader will be created which will load the new
class.
See also where this method is called after compiling.
The standard Java class loader never unloads a class. Tomcat has its own class loaders, which can replace an old instance of a class with a new instance, and then orphans the old instance, making it available to the garbage collector in the usual manner.
Somewhere along the line I read that if a class is not used for some specified period of time, Tomcat will unload it. But I can't find any reference for that at the moment.
Read the code if you want an education.
Start here: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/jasper/servlet/JspServlet.java?view=markup

Finding classes at JVM Runtime

Is there anyway to find all the class names which are extending a particular class by using classloader information?
More Detailed Explanation
I have a jar file which has 3 classes X (extends A), Y (extends A) and Z (extends B). I have put this jar file into the classpath and start the JVM (calling main method of some class). Now from this main method is there any way to find the classes which are sub classes of A? i.e. classes X and Y as they are extending the class A.
Unfortunately there's no easy way to do it. The JVM has no information about a particular class until it gets loaded by a classloader. But to have the classloader actually load the class, you must know the name of the class. Chicken and egg problem.
However, there is some other, but a bit more complicated way.
To determine which .jar files are on the classpath when running your application, you can call the System.getProperty("java.class.path") then split the classpath entries along the File.separatorChar characters. Classpath entries may be numerous, consider filtering them somehow (limiting only to a specific directory, leaving out standard entries like rt.jar, etc.)
If you know which .jar file contains your classes of interest, you can open it with an instance of the class JarFile. Then you can iterate over all entries (eg. .class files) and from their internal path in the JAR file you are able to construct their fully qualified class name.
With the classname in your hand, you can call Class.forName() to load the class, and the you can use reflection to get the superclasses of each class to find out whether it extends your particular class or not.
Note that this method is quite resource consuming, you make the JVM to actually load all the classes from a .jar file (or multiple .jar files), even if you won't use them later. This wastes a fair amount af memory (PermGen space).
There are some low-level libraries that manipulate Java bytecode and class files (see BCEL or ASM). Using them you will be able to determine the superclass for a class without actually (class)loading it, thus this way is more faster and uses less memory.
Your question resembles the way JavaEE application servers work when deploying a web application. To find out which classes to load and initialize as for example HTTP servlets they must examine all classes in the web archive looking for a specific Java annotation or superclass. However they are at least know which .war file to scan. Apache Tomcat for example uses BCEL instead of Java classloading mechanism.
If you're designing some sort of dynamic classloading mechanism for your application, then consider other design options to narrow down the numbers of classes your loader must scan to find the proper class to load: Telling the exact name of the .jar file instead of putting it on the classpath, using some meta information in the JAR (you can use the aforementioned JarFile to read entries from the META-INF/manifest.mf file) to specify which classes to look for, etc.
just fore the sake of completeness
http://code.google.com/p/reflections/
others where mentioned in the linked post

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.

Categories