Class Loading: Compile time or Runtime - java

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.

Related

How does JVM deal with dynamic classes

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

Java Path Finder for Bytecode Verification in an existing project, Bytecode Verification

I'm trying to use JPF to verify my bytecode generated while runtime with javassist.
The code I'm trying to verify is supplied by the user while my program is running. As I can't check all OOP models and stuff like that I need a verification process before running his code.
At the moment I simply generate bytecode with javassist from his classes.
My problem now is that I get exceptions sometimes because the user did some inheritance mistakes and stuff and my application shuts down with an exception cause I tried to load and execute his classes.
Therefore I would like to verify that generated bytecode in runtime to avoid such exceptions and to know earlier if the classes supplied from the user are faulty (or contain any problem).
Is this possible with JPF while in runtime?
Any other solutions on this?
Thanks!
As JPF uses BCEL Stand-alone Bytecode Verifier might be helpful. Just programmatically invoke the Verifier class - or even dive into the details of this class.
hth
There are many points to check:
the bytecode itself according to the class file format
the runtime phases: loading, linking and initializing
From my point of view, a ClassLoader does all that steps but it generally loads one Class at a time, and only on demand.
In your context, I propose you write a ClassLoader that loads in sequence all classes from generated bytecodes and reports each failing class name with caught exceptions. The ClassLoader is instantiated with the reference to the relevant parent ClassLoader and is discarded after the test passed, the generated bytecode is then loaded by the original ClassLoader of your runtime context.
Probably this class loading check may be implemented thanks to OSGi but it will require more efforts than a standalone ClassLoader.
If you don't have an absolute requirement to use JPF, the ASM library includes CheckClassAdapter which can verify byte code. It is only a sanity check however - I don't believe it will catch problems with inheritance etc.

Does (sun-jvm) hotspot optimization take place multiple times, if a class is loaded by different classloaders?

imagine a (container-) application is creating multiple classloaders to host a couple of other/sub- applications.
There is a -say- root classloader for the container app. Each time a sub-application is loaded, the container creates a new classloader for this application.
Some sub-applications use the same classes, but they were not loaded by the container's classloader, so each sub-application (better: its classloader) loads the code for e.g. class A. Therefore permspace will be filled twice: once for sub-application #1 and once for sub-app #2.
What does this mean for sun's hot-spot optimization?
Will the same optimizations occur twice on class A, once for each class-loader?
Or, is there some "magic" built-in which avoids this? (Optimizations done once)
Somebody knows a link, were this is explained?
I am referring to a sun (server) vm shipping with jdk 1.6
I don't have any literature that I can point you to in order to prove this, but I can tell you from experience that if your classes are being re-loaded, your methods will be re-compiled and re-optimized. You can observe this by adding:
-XX:+PrintCompilation
to the Java command line and execute your app. This will tell you exactly what methods are being compiled. If you see the same method output twice, you know it's being re-compiled. If you aren't sure that your classes are being re-loaded, add:
-verbose:class
as well. This will show you all class load events.
It must. There is no guarantee that the 2nd classloader loaded the same bytecode as the 1st classloader.

What's the difference of compile time libraries and run time libraries in java?

And what are the pro's con's of using either?
I actually saw it in Netbeans under Project Properties > Libraries for Java Applications. We have two tabs, one for compile time libraries and run time libraries, and it looks like we can add a library to either independent of each other
There is no such a thing as compile time libraries vs. runtime libraries
Perhaps you're mixing some concepts.
In Java the libraries to be used are statically validated at compile time and also validated at runtime.
For instance if you want to use IterableMap specified in the Apache Collections library. The compiler validates "at compile time" you are invoking a method that exist in that class.
But the compiler doesn't link or do much of anything with that library, you still need it at runtime. So, when your code executes, the Java runtime, searches for that class again, and invokes the method the compiler verified existed.
And that what there is.
The UI and terminology of the Libraries properties dialog is pretty confusing.
The Help button on that dialog will give you a fair bit of info.
The Compile-time library list may be a subset of the Run-time library list.
Consider this situation...
You have source code that imports classes from on a library 'widgets.jar'. The class files in widgets.jar reference symbols from the jar file 'xml.jar'. If your source code does not import classes from xml.jar, you could define the Compile-time libraries list to contain just widgets.jar.
When you try to run your project, you will probably need to include xml.jar in the Run-time libraries list to prevent ClassNotFoundException's.
Perhaps, this comes into play when you want to load a library dynamically, or check for an existence of the library and then execute the code.
During compilation, compiler needs to know what the signatures of the methods, classes etc to know if you code is correct. Hence you add the compile time library.
During runtime, JVM still needs the library to run that specific code. But you can put a logic to avoid that code by checking if the library exists, for example by doing Class.for() method. Some libraries might already exist in the system (qt.jar for example) or might not, and you can check and execute your code accordingly.
Please correct me if I am wrong.
As others have stated, you are confusing concepts. I think what you are really trying to understand is what Maven refers to as dependency scope. Sometimes you only need a dependency at compile time because you expect it to be provided at runtime, and sometimes you need it at runtime but not compile time.

-classpath option for javac and java

I'm confused with the role -classpath option plays in both compiling and running a java program. Please help me understand.
Because they are two separate operations and not necessarily the same paths.
The runtime dependencies are often more extensive than the compile time dependencies. For example, many programs will code to interfaces, which limits the compile time dependencies to those interfaces. At runtime, the VM must be able to resolve the implementations of those interfaces, which are not required until they are loaded at runtime.
it simply in both cases tells javac and java where to find dependencies required for your program to both compile and run
The reason it is done twice is that the environment you compile the code in may not be the same environment you run the code in.
Java loads classes at runtime. For example, you could write a method that forces loading of class X, compile it, write class X, compile it, and then run them together. In addition, you typically refer to classes by a fully specified name, but could run the same program with different versions of that class (e.g., a different version of the library). Thus, you need to tell Java where it could potentially find the classes that it needs to load.
As for compilation, to ensure type safety, you have to provide the Java compiler at least with the interfaces or base classes that you are referring to and making calls on, so that the compiler can at least ensure that the call would be legal. For that reason, you have to tell it where to find the jars containing them.
Here is an example. Let's say you want to use JMS (a messaging framework) in a core Java program. At compile time, you need to at least tell javac where to find the JMS interfaces. At runtime, you need to provide these interfaces, but you also need to provide the JAR with the actual implementation (e.g., ActiveMQ).
In C++ I believe it is the case that linking happens around compile-time, to create an executable (I am not a C++ programmer so I'm not sure about that).
In Java, the linker step happens at runtime (see the JVM spec, "Loading, Linking and Initalizing"). From your question it sounds like you understand why the classpath needs to be specified at compile time (because you might reference classes from third-party JARs in your code), so I will just explain that when your program is being run, those classes are not loaded into the JVM until they are referenced. At this point, the JVM needs to know where to find their representation.
The compiler has to know where to look to satisfy compile-time dependencies.
The VM has to know where to look to satisfy runtime dependencies.
At compile time, you need to tell javac where to find third-party and user-defined classes. At runtime, you also need to tell java where to find third-party and user-defined classes. In both cases, one way to change the class path is to use the JDK Tools' -classpath option. Checkout the Setting the Class Path technical note for more details.

Categories