Byte Buddy LocationStrategy types - byte-buddy

I saw that the default LocationStrategy is STRONG, which keeps a strong reference to the class loader when creating a ClassFileLocator. Does this mean Byte Buddy can prevent a class loader from being garbage collected (eg when undeploying a webapp from a servlet container) or is there another mechanism to evacuate those?
Also in this regard- the documentation about the WEAK strategy says a ClassFileLocator will "stop working" after the corresponding class loader is garbage collected. What are the implications? How would a locator for a garbage-collected class loader be used?

You are right about your assertion. With a strong type locator, all TypeDescriptions will reference the class loader as dependent types are resolved lazily. This means for example that if you look up a type's field type, that type will only be loaded if you are using it for the first time what might never happen.
Typically, those type descriptions are not stored over the life time of a class being loaded. Since the class loader will never be garbage collected during a loading of one of its classes, referencing the class loader strongly does not render any issue. However, once you want to cache type descriptions in between multiple class loadings (what can make a lot of sence since some applications load thousands of classes using the same class loader), this might become a problem if a class loader would be garbage collected while the cache is still referencing the type description with the underlying class loader.
In this case, reusing the type descriptions will be problematic since no lazily referenced classes can be resolved after the class loader was garbage collected. Note that a type description might be resolved using a specific class loader while the class is defined by a parent of that class loader which is why this might be a problem.
Typically, if you maintain a cache of type descriptions per class loader, this should however not be a problem.

Related

Byte Buddy: Convert an object of a class from one class loader to same class loaded in another class loader

I'm exploring if Byte Buddy is the right tool for me to use. I was looking at this answer which talks about how with Byte Buddy, one can take a class Foo loaded with class loader A, rename it to Bar and redefine it on another class loader B. That's incredible.
My question is:
Is it possible to have an object which was created from Foo on class loader A and convert to Bar's object which is coming from class loader B? The solution which I have in mind right now is to basically serialize the object from Foo and then edit the serialized bytes to rename the name of the class. It would be nice if I can do it safely with Byte Buddy. Another solution would be to use Transloader.
Is java-agent or any special instrumentation required for doing all the things that was described in the above SO answer
Thank you so much.
You can always load a class in another class loader without using a Java agent. As for translating the class, replacing the symbol of one class name to anther should not be a problem but you need to watch out for serial version UIDs where there name of the class might be a part of. Byte Buddy is a code generation library and does not add any extra help for such operations.

Redis Serialization and Deserialization

I have noticed that some of my serialized objects stored in Redis have problems deserializing.
This typically occurs when I make changes to the object class being stored in Redis.
I want to understand the problem so that I can have a clear design for a solution.
My question is, what causes deserialization problems?
Would a removal of a public/private property cause a problem?
Adding new properties, perhaps?
Would a adding a new function to the class create problems? How about more constructors?
In my serialized object, I have a property Map, what if I change (updated some properties, added functions, etc) myObject, would it cause a deserialization problem?
what causes deserialization problems?
I would like to give you bit of background before answering your question,
The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException.
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, It uses the following information of the class to compute SerialVersionUID,
The class name.
The class modifiers written as a 32-bit integer.
The name of each interface sorted by name.
For each field of the class sorted by field name (except private static and private transient fields:
The name of the field.
The modifiers of the field written as a 32-bit integer.
The descriptor of the field.
if a class initializer exists, write out the following:
The name of the method, .
The modifier of the method, java.lang.reflect.Modifier.STATIC, written as a 32-bit integer.
The descriptor of the method, ()V.
For each non-private constructor sorted by method name and signature:
The name of the method, .
The modifiers of the method written as a 32-bit integer.
The descriptor of the method.
For each non-private method sorted by method name and signature:
The name of the method.
The modifiers of the method written as a 32-bit integer.
The descriptor of the method.
So, to answer your question,
Would a removal of a public/private property cause a problem? Adding new properties, perhaps? Would a adding a new function to the class create problems? How about more constructors?
Yes, all these additions/removal by default will cause the problem.
But one way to overcome this is to explicitly define the SerialVersionUID, this will tell the serialization system that i know the class will evolve (or evolved) over the time and don't throw an error. So the de-serialization system reads only those fields that are present in both the side and assigns the value. Newly added fields on the de-serialization side will get the default values. If some fields are deleted on the de-serialization side, the algorithm just reads and skips.
Following is the way one can declare the SerialVersionUID,
private static final long serialVersionUID = 3487495895819393L;

How jvm classloader loads class that is defined inside another class?

How does JVM loads class that are defined inside another class?
Example: Lets say, there is a class B that is defined inside class A
package test.sample;
Class A {
// some instructions
Class B {
// few more instructions
}
}
In this case,
How does classloader load the class B? (i.e., How does it identify class B?)
What will be the fully qualified name of class B?
Inner classes are a Java language feature, not a JVM feature. That is, Java compilers "flatten" the class structure, so the JVM just sees regular classes, usually with $ in their names. In this case, there would be classes test.sample.A and test.sample.A$B (the latter being the fully qualified name of B). Anonymous inner classes get compiler-defined names, typically starting at 1 and counting up: test.sample.A$6, for example. The compiler may add methods with names like access$200 to allow the enclosing class and inner class to access each others' private members. (Note that $ is legal, though discouraged, in user-defined class and method names, so the presence of a $ in a name does not mean it is compiler-generated; for that, there's the Synthetic attribute and ACC_SYNTHETIC modifier bit, exposed reflectively via methods like Class.isSynthetic().)
The JVM loads these classes just like any other class, typically looking for a file test/sample/A$B.class in some JAR file, but also possibly loading them across a network, generating them on-the-fly with a bytecode manipulation library, etc.
When generating class files that reference an inner class (defining, containing, or simply using), Java compilers emit InnerClasses attributes specifying the containment relationships, for the aid of separate compilation and reflection (Class.getDeclaringClass() and Class.getEnclosingClass()). Class files for classes defined inside a method also contain an EnclosingMethod attribute referring to the enclosing method, for reflection (Class.getEnclosingMethod() and Class.getEnclosingConstructor()). However, these attributes are only checked for syntactic well-formedness by the JVM during loading and linking; inconsistencies are not reported until the reflective methods are actually called.

Java : when a class need to be loaded in a JVM twice and more?

When I read something about JVM, it tells me that the namespace of JVM can identify a class loaded in the JVM, only the full name of the class is not useful! When or on which circumstance a class will be loaded in the jvm(I mean the same jvm) twice and more? Is this way a useful way?
If you simply try to load the same class multiple times with reflection, then subsequent times will just return the already loaded class. This is a common situation, and there is nothing special about it.
It is possible to load the same class with different class loaders. In general, this is not necessary, and it can be very confusing. Because two instances of the same class loaded by different class loaders are not equal,

What's the purpose of noncreatable coclasses in IDL?

What is the reason for declaring noncreatable coclasses like the following in IDL?
[
uuid(uuidhere),
noncreatable
]
coclass CoClass {
[default] interface ICoClass;
};
I mean such class will not be registered to COM anyway. What's the reason to mention it in the IDL file and in the type library produced by compiling that IDL file?
noncreatable is good when you want to stop clients from instantiating the object with the default class factory yet still have a proper CLSID for logging, debugging &c; see an example at http://www.eggheadcafe.com/software/aspnet/29555436/noncreatable-atl-object.aspx of an issue which is properly resolved that way.
The noncreatable attribute is just a hint to the consumer of the object -- .Net and VB6, for example, when seeing this attribute, will not allow the client to create the object "the normal way", e.g. by calling New CoClass() [VB6].
However, the COM server's class factory is the definite authority for deciding whether it allows objects of given class to be created or not -- so in fact, it is possible that a class is marked noncreatable and yet, the class factory allows objects to be created. To avoid such situations, make sure that you update your class factory accordingly.
Mentioning noncreatable classes in the IDL is in fact optional. Note, however, that you get at least one benefit from including them anyway: midl will create CLSID_CoClass constants etc.