17 Mart 2023 Cuma

Hidden Classes - Java 15 İle Geliyor

Giriş
Gizlice yüklenen sınıflar demek daha doğru olur. Çünkü byte code olunca artık saklamak mümkün değil.  Açıklaması şöyle
A hidden class is loaded into the JVM. When a class is in source code or byte code format, it cannot be "hidden." 
Bu sınıfları ismen bulmak mümkün olmadığı için ismi Hidden Class. Açıklaması şöyle
A class gets hidden when it is loaded in a particular way so that it remains secret in front of other code parts. Remaining hidden does not mean that other codes cannot use this class. They can so long as long they "know" about the secret. The big difference is that this class is not "advertised" because you cannot find it using the name.
Bazı özellikleri şöyle
  • Non-discoverable – a hidden class is not discoverable by the JVM during bytecode linkage, nor by programs making explicit use of class loaders. The reflective methods Class::forName, ClassLoader::findLoadedClass, and Lookup::findClass will not find them.
  • We can't use the hidden class as a superclass, field type, return type, or parameter type.
  • Code in the hidden class can use it directly, without relying on the class object.
  • final fields declared in hidden classes are not modifiable regardless of their accessible flags.
  • It extends the access control nest with non-discoverable classes.
  • It may be unloaded even though its notional defining class loader is still reachable.
  • Stack traces don't show the methods or names of hidden classes by default, however, tweaking JVM options can show them.
Yani
1. Hidden Class'ın canonical ismi yoktur. Açıklaması şöyle
When you call getName() or getSimpleName() on a variable referencing a hidden class, you will get some string. These are names for messages for humans and are irrelevant for the other classes. When a class refers to another class it needs the canonical name. getCanonicalName() returns null. The canonical name is the actual name of the class, which is non-existent in the case of hidden classes.
2. Cass Loader'dan bu sınıfa bir referans yoktur, çünkü sınıfın canonical ismi yok. Dolayısıyla hemen GC işlemine uğrayabilir. Açıklaması şöyle
Since the class cannot be found through the class loader without the canonical name, there is no reason for the loader to keep a reference to the class. Why would it keep a reference when it cannot give the class to anyone? Keeping a reference would have only one side effect: preventing the GC from unloading the class so long as the class loader is alive.

Since there is no reference from the class loader, the GC can unload the class object as soon as it is out of use.
2. JDK'nin bir parçasıdır. Açıklaması şöyle
It is not part of the language but part of the JDK. There is no language element to create hidden classes, but JDK methods and classes come to the rescue.
Örnek
Şöyle yaparız
// Create a Lookup object
// The Lookup::defineHiddenClass method creates the hidden class. 
// This method accepts an array of bytes.
MethodHandles.Lookup lookup = MethodHandles.lookup();

// Load class it into the input stream
Class<?> clazz = HiddenClass.class;
String className = clazz.getName();
String classAsPath = className.replace('.', '/') + ".class";
InputStream stream = clazz.getClassLoader()
    .getResourceAsStream(classAsPath);
byte[] bytes = IOUtils.toByteArray();

// Pass these constructed bytes into Lookup::defineHiddenClass:
Class<?> hiddenClass = lookup.defineHiddenClass(IOUtils.toByteArray(stream),
  true, ClassOption.NESTMATE).lookupClass();
Bu aslında iyi bir örnek değil. Burada Hidden.class isimli bir sınıf Lookup ile yükleniyor. Aslında bu sınıf normal ClassLoader ile de yüklenebilirdi. Açıklaması şöyle
Articles and tutorials showing how to load hidden classes use precompiled Java classes. These are usually part of the running application. The tutorial calculates the path to the .class file and reads the byte code.

Technically this is correct but does not demonstrate the basic need for hidden class loading: load dynamically created classes hidden. These classes are not dynamically created and could be loaded the usual way.




Hiç yorum yok:

Yorum Gönder