Looks like I am missing important concept on locking a class and it's related classloading event.As per my knowledge in java we can use any class only if classloader has already loaded the class ( byte code ) in memory. Based on this assumption I was thinking that "static block
of SharedQ class should execute when statement synchronized (SharedQ.class) { ... } executes in below code". But thats not the same.
Can anyone please explain what is happening here exactly.
public class VerifyClassLoadingOnClassLock {
public static void main(String[] args) {
show();
}
private static void show() {
synchronized (SharedQ.class) {
System.out.println(" Method Show() executing from Main() .... ");
}
}
}
public class SharedQ {
static {
System.out.println(" Classloader is loading SharedQ ");
}
public static void writeStream() {
// some multiThread code here
}
}
Output is : Method Show() executing from Main() ....
The class will have been loaded, but not necessarily initialized. Basically, there's a Class object available when you synchronize on it, but until something uses a member of the class, it doesn't have to be initialized.
From the JVM specification section 5.5:
Initialization of a class or interface consists of executing its class or interface initialization method (§2.9).
A class or interface may be initialized only as a result of:
The execution of any one of the Java Virtual Machine instructions new, getstatic, putstatic, or invokestatic that references the class or interface (§new, §getstatic, §putstatic, §invokestatic). All of these instructions reference a class directly or indirectly through either a field reference or a method reference.
Upon execution of a new instruction, the referenced class or interface is initialized if it has not been initialized already.
Upon execution of a getstatic, putstatic, or invokestatic instruction, the class or interface that declared the resolved field or method is initialized if it has not been initialized already.
The first invocation of a java.lang.invoke.MethodHandle instance which was the result of resolution of a method handle by the Java Virtual Machine (§5.4.3.5) and which has a kind of 2 (REF_getStatic), 4 (REF_putStatic), or 6 (REF_invokeStatic).
Invocation of certain reflective methods in the class library (§2.12), for example, in class Class or in package java.lang.reflect.
The initialization of one of its subclasses.
Its designation as the initial class at Java Virtual Machine start-up (§5.2).
Prior to initialization, a class or interface must be linked, that is, verified, prepared, and optionally resolved.
Section 5 of the specification talks a lot about all of this - in particular, it differentiates between loading, linking and verification.
Related
I saw answers like these, tried to clarify via comments, and was unsatisfied by examples here.
Maybe it's time for this specific question...
Why enum singleton implementation is called lazy?
public enum EnumLazySingleton {
INSTANCE;
EnumLazySingleton() {
System.out.println("constructing: " + this);
}
public static void touchClass() {}
}
How it is different from eager implementation?
public class BasicEagerSingleton {
private static final BasicEagerSingleton instance = new BasicEagerSingleton();
public static BasicEagerSingleton getInstance() {
return instance;
}
private BasicEagerSingleton() {
System.out.println("constructing: " + this);
}
public static void touchClass() {}
}
Both will init instance without accessing INSTANCE/getInstance() - e.g. call touchClass().
public class TestSingleton {
public static void main(String... args) {
System.out.println("sleeping for 5 sec...");
System.out.println("touching " + BasicEagerSingleton.class.getSimpleName());
BasicEagerSingleton.touchClass();
System.out.println("touching " + EnumLazySingleton.class.getSimpleName());
EnumLazySingleton.touchClass();
}
}
Output:
sleeping for 5 sec...
touching BasicEagerSingleton
constructing: BasicEagerSingleton#7bfcd12c
touching EnumLazySingleton
constructing: INSTANCE
Now, we can say both are lazy. What is eager then?
It is clear how (e.g) "double-checked locking" way is actually lazy (and messy, and slow). But if enum is lazy, then any singleton is lazy due to inevitable class loading - in fact, everything is lazy. At which point will this distinction stop making any sense?
The first two linked answers (by Peter Lawrey and Joachim Sauer) both agree that enums are not lazily initialized. Answers in the third link are simply wrong about what lazy initialization means.
The recommendation to use enums as singletons originates from Josh Bloch's Effective Java. Notably, the chapter on enum singletons makes no mention of laziness. There is a later chapter dedicated to lazy initialization, that likewise makes no mention of enums. The chapter contains two highlights.
If you need to use lazy initialization for performance on a static field, use the lazy initialization holder class idiom.
If you need to use lazy initialization for performance on an instance field, use the double-check idiom.
Undoubtedly, enums would be another idiom on this list if they were in any way lazily initialized. In fact they are not, although confusion about the meaning of lazy initialization results in some incorrect answers, as the OP shows.
May I wager the following:
You are trying to identify 2 "processes" or ... "things" (let's make this easy to understand - because if I start saying "Code Blocks", it sounds more difficult)...
At some point the class-loader will run, and you would like to know what "things" will be executed when the class-loader loads a class.
At another point invoking a method on the class will cause another "thing" to run / execute, and you would like to know which, exactly, (which "processes") would start..
The following facts are relevant:
Static initializers are run when the class-loader loads the class. The class-loader will not load the class until the code that is
running encounters the need to load it (because a method or field has
been invoked) such as: touchClass()
If a singleton instance of EITHER a class, OR an enumerated type has a field that is being initialized in the static
part of the class it will be loaded as soon as you 'touch' the
class - because the Class-Loader runs all static initializations for a class or enum on loading.
Lazy loading, likely, (And this is my "interpretation" about what you are asking) would happen when a method invokation asks the class
to create a singleton instance - which could happen quite a bit of
time after the "loading" of the class or enum.
A class like the following:
public class LazySingleton
{
// At time of class-loading, this singleton is set to 'null'
private static singleton = null;
// This is a method that will not be invoked until it is called by
// some other code-block (some other "thing")... When "touchClass()"
// is called, the singleton instance is not created.
public static LazySingleton retrieveSingleton()
{
if (singleton == null) singleton = new LazySingleton();
return singleton;
}
// DOES NOTHING... The Singleton is *not* loaded, even though the
// Class Loader has already loaded this Java ".class" file
// into memory.
public static void touchClass() { }
private LazySingleton()
{ System.out.println("constructing: LazySingleton"); }
}
Here on the other hand:
public enum EagerEnum
{
// The class loader will run this constructor as soon as this 'enum'
// is loaded from a '.class' file (in JAR or on disk) into memory
MyEnumConstant();
private EagerEnum()
{ System.out.println("Eager Enum Constructed"); }
// This will cause the Class Loader to Load this enum from the
// Java ".class" File immediately, and the "MyEnumConstant" will
// also have to be loaded - meaning the constructor will be called.
public static void touchEnum() { }
}
So the following code would produce the output
LazySingleton.touchClass(); // Prints nothing
EagerEnum.touchClass(); // Prints "Eager Enum Constructed"
LazySingleton.getSingletonInstance(); // Prints "constructing: LazySingleton
This is the code I have:
public class StupidClass {
static {
System.out.println("Stupid class loaded!");
}
}
And the tests I have, which I run separately.
import org.junit.Test;
public class StupidTest {
#Test
public void foo() throws ClassNotFoundException {
final Class<?> stupidClass = Class.forName("StupidClass");
System.out.println(stupidClass.getSimpleName());
}
#Test
public void bar() throws ClassNotFoundException {
final Class<StupidClass> stupidClassClass = StupidClass.class;
System.out.println(stupidClassClass.getSimpleName());
}
}
When I run test foo I will see:
Stupid class loaded!
StupidClass
But when I run the test bar all I see is:
StupidClass
Quoting from this page..
Class objects are constructed automatically by the Java Virtual
Machine as classes are loaded and by calls to the defineClass method
in the class loader.
So my understanding is, in test bar, Stupid class is loaded, otherwise I would have seen a null I guess? So Class object is created because class itself is loaded..
And now quoting from this page
Static initialization blocks are run when the JVM (class loader - to
be specific) loads StaticClass (which occurs the first time it is
referenced in code).
So I am expecting to see the "Stupid class loaded!" text in test bar as well, but I am not.
Also quoting from Thinking in Java
Each of the classes Candy, Gum, and Cookie has a static clause that is
executed as the class is loaded for the first time.
which is not very accurate it seems..
What am I missing?
Static initialization blocks are run when the JVM (class loader - to be specific) loads StaticClass (which occurs the first time it is referenced in code).
The above quote is plain wrong, but it is just one instance of a very widespread misconception.
Class is not initialized when it's being loaded, but when a static class member is first referenced. This is precisely governed by the specification.
Class loading does not occur when the class is first referenced, but at an implementation-dependent point.
The last moment when the class must be loaded is when the class is referenced, which is not the same as referencing a class member.
Class.forName initializes the class by default, but you have the choice of calling an overload that takes a boolean initialize and supplying false. You'll get the class loaded without initializing.
Class Loading and initialization are 2 different things. A class can be loaded but not initialized until it is really necessary. Static initializers are run only when a class is being initialized <> NOT loaded, "initialized"
In the first case you are loading and initializing a class when you use class.forName(), that's why the static initializers are run and hence you see "Stupid class loaded!" as output . In the second case, you are just assigning a reference of the class, the class is loaded (use java -verbose:class to see what classes are loaded) but you aren't really initializing it (or to be more precise, not doing anything that forces the initializers to run). Thus you don't see the output as Stupid class loaded!. Try doing something like calling newInstance() on the class, it should force the initialization of the class and you should see Stupid class loaded!
My code :
public class CheckPalindrome {
public static void main(String[] args) {
Class<Test> t = Test.class;
}
}
// class being loaded
class Test {
static {
System.out.println("aaa");
}
}
Classes that are loaded
...
[Loaded Test from file:/Workspaces/SampleTest/Java8/bin/]
...
^ - This shows that the class is loaded but not initialized.
class TestMemberOuter1{
private int data=30;
class Inner{
void msg(){System.out.println("data is "+data);}
}
void display(){
Inner in=new Inner();
in.msg();
}
public static void main(String args[]){
TestMemberOuter1 obj=new TestMemberOuter1();
obj.display();
}
}
Why innerclass is able to access private members of the outerclass ?
I want to know what implementation [ at the lower level (Maybe at memory level or java implementation specific or any other not sure)] enables to achieve this kind of behaviour in java .
I dont think neither you need any memory level modifictaion or logic implementation to achieve this nor I think java will have any huge code logic at memory level to implement the same.
Memory has got nothing to do with it. Private, public and protected are just a access filters, No matter whether it is a private, public or protected all these variables will reside in a same memory which is allocated for an object.
There is no differrent memory allocation for private, public or protected variables. They are all ultimately the properties of same object.
Then how come compiler handles this ???
Its bit simpler than that.
These access filters clearly informs in what context they should be allowed to access.
Private : Only whitin the class :) Whenever compiler sees the variable which is provate being accessed any where out side the class it will flag the error Thats all.
Protected : All class within the same package :) Whenever compiler sees the variable which is Protected being accessed any where out package it will flag the error Thats all.
Public : Access to all :) No flags.
Remember accessing variables outside context results in compiler error not runtime error ?? For the same reason.
You dont need a huge logic behind it, Just keep the list of private, protected and public variables and check their usage is appropriate or not thats all.
EDIT
As per your updated question "Why innerclass is able to access private members of the outerclass ?"
Drawing the conclusion from the same analogy I explained above, private variables are allowed to be accessed anywhere within the class.
Now where is your innerclass declared? As a part of your outer class itself isn't it. So when you access the private variable of outer class inside the inner class compiler has no issue with it, because your inner class itself resides inside the outer class.
I hope I made a little sense with my answer :) Happy coding.
Currently, inner classes are compiled into distinct class files, but the compiler will insert synthetic helper methods when there is an access to a private member across nested classes. The synthetic method itself will have package-private access and perform the access to the private member within its own class.
This can be demonstrated with private methods as their execution can be traced and will show the execution of these helper methods:
public class OuterClass {
static class InnerClass {
private static void test() {
OuterClass.privateMethod();
}
}
private static void privateMethod() {
Thread.dumpStack();
}
public static void main(String[] args) {
InnerClass.test();
}
}
Running this program will print:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1329)
at OuterClass.privateMethod(OuterClass.java:9)
at OuterClass.access$000(OuterClass.java:2)
at OuterClass$InnerClass.test(OuterClass.java:5)
at OuterClass$InnerClass.access$100(OuterClass.java:3)
at OuterClass.main(OuterClass.java:12)
These nested classes are compiled into two distinct class files OuterClass.class and OuterClass$InnerClass.class. You can see that the compiler has inserted the synthetic method access$100 into OuterClass$InnerClass which allows the main method of OuterClass to invoke the private method test of the inner class. This inner class method in turn invoked a synthetic method access$000 in the outer class which allows the invocation of privateMethod() in OuterClass.
Note that this kind of access is different to the access to private members performed with Java 8’s lambda expressions and method references. For the member access performed in that context, no helper methods are generated by the compiler and the way the JVM makes the access possible is intentionally unspecified, but we can say that for Oracle’s current JRE implementation, there will be a runtime-generated class which is indeed capable of bypassing the access restriction of private members, e.g.
import java.util.function.Consumer;
public class OuterClass {
static class InnerClass {
static final Consumer<Runnable> TEST_METHOD=InnerClass::test;
private static void test(Runnable outerMethod) {
outerMethod.run();
}
}
private static void privateMethod() {
Thread.dumpStack();
}
public static void main(String[] args) {
System.out.println(System.getProperty("java.version"));
InnerClass.TEST_METHOD.accept(OuterClass::privateMethod);
}
}
As of 1.8.0_65, it prints:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1329)
at OuterClass.privateMethod(OuterClass.java:12)
at OuterClass$InnerClass.test(OuterClass.java:8)
at OuterClass.main(OuterClass.java:16)
Not showing such helper methods, but also filtering out the runtime-generated classes. Changing privateMethod() to
private static void privateMethod() {
for(StackTraceElement e:Thread.getAllStackTraces().get(Thread.currentThread()))
System.out.println("\tat "+e);
}
reveals
at java.lang.Thread.dumpThreads(Native Method)
at java.lang.Thread.getAllStackTraces(Thread.java:1603)
at OuterClass.privateMethod(OuterClass.java:12)
at OuterClass$$Lambda$2/135721597.run(Unknown Source)
at OuterClass$InnerClass.test(OuterClass.java:8)
at OuterClass$InnerClass$$Lambda$1/471910020.accept(Unknown Source)
at OuterClass.main(OuterClass.java:16)
with the generated classes having fancy names like OuterClass$InnerClass$$Lambda$1/471910020 and OuterClass$$Lambda$2/135721597 which are accessing the private members. Note that the generation of these classes has been triggered by the classes which have the right to access these private members, which has been checked before allowing to create such function objects.
I have a Java based RMI Server in which one of the interface method is like this :
public Properties process(String operation, Properties params) {
Class nodecls = Class.forName("com.example.commands." + operation);
}
This method runs fine all the time but sometimes (say once in a million RMI calls) throws ClassNotFoundException. What could be the reason for this? I am sure that the name passed is correct.
From XYZWS - What does Class forname method do?:
A call to Class.forName("X") causes the class named X to be dynamically loaded (at runtime). A call to forName("X") causes the class named X to be initialized (i.e., JVM executes all its static block after class loading). Class.forName("X") returns the Class object associated with the "X" class. The returned Class object is not an instance of the "x" class itself.
Class.forName("X") loads the class if it not already loaded. The JVM keeps track of all the classes that have been previously loaded. This method uses the classloader of the class that invokes it. The "X" is the fully qualified name of the desired class.
The tag wiki for classnotfoundexception has a simpler description:
The Java exception thrown when an application tries to load a class by name. Usually raised by one of:
the forName method in class Class [...]
when no definition for the class with the specified name could be found in the classpath.
Therefore, there can only be two causes for this:
The class named "com.example.commands." + operation is not present on the Class Path.
The ClassLoader of the Class which your method is in cannot find the "com.example.commands." + operation class. Maybe some reflection trick broke it.
However, you should never have to bother with this, as your method wouldn't even compile - it's of a non-void return type, while you never included a proper return statement.
I am embedding a JVM in an existing C++ application and need to register implementation of native Java functions with a class.
Consider this simple class with native functions:
class Native {
static {
System.out.println("Class 'Native' static initializer called.");
}
public native int f(int i);
}
Inside the JVM I am running OSGi which is the reason I need to get the classes using Java code (using the correct class loader) instead of loading them from JNI. However, to keep this example simple, I have left out OSGi.
I have these four different Java methods for getting a jclass value in C++:
class Bridge {
public Class<?> getNativeClass1() throws ClassNotFoundException {
return getClass().getClassLoader().loadClass("org.example.Native");
}
public Class<?> getNativeClass2() throws ClassNotFoundException {
return Class.forName("org.example.Native", false, getClass().getClassLoader());
}
public Class<?> getNativeClass3() throws ClassNotFoundException {
final Class<?> clazz = getClass().getClassLoader()
.loadClass("org.example.Native");
clazz.getMethods();
return clazz;
}
public Class<?> getNativeClass4() throws ClassNotFoundException {
return Class.forName("org.example.Native", true, getClass().getClassLoader());
}
}
To register the native function implementation in C++ for Native.f() I call:
JNIEnv* env = ...
jclass clazz = ...; // Calling one of the four methods above.
JNINativeMethod nativeMethod = {
(char*) "f", // Method name 'f'.
(char*) "(I)I;", // Signature 'int --> int'.
(void*) f // Pointer to C++ implementation of function.
};
env->RegisterNatives(clazz, &nativeMethod, 1);
Depending on which method I use for getting the Class<?> instance, I get different results:
getNativeClass1(): The static initializer is not executed in class Native when loading the class (but of course when creating an instance of the class) and the native implementation is not bound correctly. (Calling the native function in Java gives incorrect results or crashes the JVM.)
getNativeClass2(): Same as above.
getNativeClass3(): The static initializer is still not called in class Native when the class is loaded but the native implementation is bound correctly and I can call f() successfully.
getNativeClass3(): The static initializer is called in class Native when the class is loaded and the native implementation is bound correctly.
So it seems that ClassLoader.loadClass() loads the class in a way so it is not properly initialized and JNIEnv::RegisterNatives() will not work properly. However, calling Class.getMethods() will somehow initalize the class (without invoking the static initializer) so that binding the native methods works.
On the other hand, Class.forName(clazz, false, classLoader) seems to work exactly like Class.loadClass() returning an uninitialized Class instance.
Can anybody explain the difference between
an uninitialized class like the one returned by getNativeClass1() and getNativeClass2()
a partially initialized class like the one returned by getNativeClass3()
a fully initialized class like the one returned by getNativeClass4()
and what is the most portable way to load a class before calling JNIEnv::RegisterNatives()?
So it seems that ClassLoader.loadClass() loads the class in a way so it is not properly initialized
According to the documentation:
loadClass(String): "Invoking this method is equivalent to invoking loadClass(name, false)."
loadClass(String,boolean) (emphasis added): "If the class was found using the above steps, and the resolve flag is true, this method will then invoke the resolveClass(Class) method on the resulting Class object"
Those two methods are intended for internal use by classloaders that need to do something between loading and linking. I'm not sure why loadClass(String) is marked public, but it arguably shouldn't be.
and what is the most portable way to load a class before calling
Class.forName(), which uses the context classloader and ensures that the class is ready for use.