Is it possible to define my own String class which has the exact same name as java.lang.String? My assumption is that after I have defined it, I can use it directly or load it with a class loader.
Sorry, the code I wrote has a mistake. The String class of the parameter String[] args of the method main() was incorrectly referenced to my own defined String. That is why it occured a compile error.
My working result is that we can define a class named String in my own namespace or java.lang. But since JVM has loaded the default java.lang.String, we can't load our own String and use it.
Yes, you can define that class, but you won't be able to use it. The class java.lang.String will be loaded out of the JRE at bootstrap, and you can't reload a class in the bootstrap classloader. If you try to use your own classloader, the JVM will notice that java.lang.String is already loaded and just use that one.
From the JLS section on class loading:
Given the same name, a good class loader should always return the same class object. (This means that the java.lang.String class that gets pulled in a bootstrap will be the authoritative class.)
If a class loader L1 (the bootstrap loader) delegates loading of a class C to another loader L2 (your own loader), then for any type T (java.lang.String) that occurs as the direct superclass or a direct superinterface of C, or as the type of a field in C, or as the type of a formal parameter of a method or constructor in C, or as a return type of a method in C, L1 and L2 should return the same Class object. (Your own java.lang.String would be conflicting with all of the parameters and fields in anything else loaded by the bootstrap loader and would cause virtually anything past the loading of your rogue class to come crashing down with link or cast errors.)
What exactly are you trying to do, anyhow? java.lang.String has very strictly defined semantics, and changing its behavior at all would break an enormous amount of code.
Related
According to the Java 8 Language Spec §15.8.2 (quote):
[...]
A class literal evaluates to the Class object for the named type (or for void) as defined by the defining class loader (§12.2) of the class of the current instance.
[...]
Mainly, 'the Class object' insinuates that this is or should be a singleton. Also §12.2 says:
[...]
Well-behaved class loaders maintain these properties:
Given the same name, a good class loader should always return the same class object.
[...]
In fact, using Java 8*, the following** prints true and true:
class Main {
public static void main(String[] args) {
Main main1 = new Main();
Main main2 = new Main();
System.out.println(main1.getClass().equals(main2.getClass()));
System.out.println(main1.getClass() == main2.getClass());
}
}
Is the class loader always 'well-behaved' and why (not)? In other words: are Class instances singleton? The other way around: can a Class of the same type be a different instance?
Notes: I do not refer to the singleton pattern here. However, if the Class implementation follows that pattern, that would be interesting. As a side-step, but by no means the main question: because the singleton pattern's legitimate uses are point of debate, would Java's Class be a good candidate to apply the singleton pattern to?
*:
$ java -version
openjdk version "1.8.0_262"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_262-b10)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.262-b10, mixed mode)
**: my IDE even warns me that the printed expressions are always true.
You are using the term singleton incorrectly.
A singleton implies the existence of only one object of its own class. A Class object is an instance of the class java.lang.Class and there is more than one instance of this class. It’s actually impossible to have only one Class object, as the existence of a Class object does already imply the existence of at least two classes, java.lang.Object and java.lang.Class, so there must be at least two Class objects in the runtime.
Your example is not capable of spotting whether the class loader is well behaved or not. You already mentioned JLS §12.2
Well-behaved class loaders maintain these properties:
Given the same name, a good class loader should always return the same class object.
If a class loader L1 delegates loading of a class C to another loader L2, then for any type T that occurs as the direct superclass or a direct superinterface of C, or as the type of a field in C, or as the type of a formal parameter of a method or constructor in C, or as a return type of a method in C, L1 and L2 should return the same Class object.
A malicious class loader could violate these properties. However, it could not undermine the security of the type system, because the Java Virtual Machine guards against this.
Mind the last sentence. A JVM will guard against violations of these requirements. With the repeated occurrences of the same symbolic references within your example code, there are two possibilities
The JVM remembers the result of the first resolution of this symbolic reference within this context and just reuses it on the next occurrence without asking a class loader again.
The JVM remembers the result of the first resolution of this symbolic reference within this context and compares it with the result of subsequent resolutions of the same reference and throws an error if they mismatch.
Since both approaches imply remembering the result, the first approach is usually used when it comes to resolving the same reference within the same context, as it is simpler and more efficient. When it comes to different symbolic references that resolve to classes using the same reference, the JVM will indeed throw an error when the class loader constraints are violated.
So expressions like Main.class == Main.class or new Main().getClass() == new Main().getClass() will never evaluate to false. Most likely, the resolution of the symbolic reference to Main will go a short-cut, using the same runtime class regardless of what the class loader would do. But even when it does not take the short-cut and the ClassLoader is misbehaving, returning a different class object for the next query, the JVM would detect it and throw an error, so the expression would not evaluate to a boolean result at all. In neither case could it result in false.
In a single classloader, the Class object is the same.
Is the class loader always 'well-behaved' and why (not)?
It really depends on the implementation. If it is done deliberately that always the classloader always returns a new Class-Object, it won't be well-behaved.
At least all classloaders of OpenJDK are well-behaving.
In other words: are Class instances singleton? The other way around: can a Class of the same type be a different instance?
In one single classloader, every Class instance is a singleton. With multiple classloaders, following will evaluate to false:
ClassLoaderA.getInstance().loadClass("foo.Bar")==ClassLoaderB.getInstance().loadClass("foo.Bar");
The other way around: can a Class of the same type be a different instance?
Only if loaded by two different, conforming,well-behaved classloaders.
As a side-step, but by no means the main question: because the singleton pattern's legitimate uses are point of debate, would Java's Class be a good candidate to apply the singleton pattern to?
This is quite opinion-based, but I think, it's no good candidate to apply the singleton pattern, as most singletons are implemented like this:
class Foo{
public static final Foo INSTANCE=new Foo();
private Foo(){
ìf(INSTANCE!=null)
throw new IllegalAccessException("No Foo instances for you!");
}
}
So more that it is really ONE object of a Class, many that only differ by some small things like a different Classloader.
It seems like the FOREIGN_THREAD_START_ROUTINE class (which appears to be the JNA representation for the LPTHREAD_START_ROUTINE class in C) may be broken and/or not a full implementation of the class. In no way as-is have I found it to be functional or even successfully created an instance of it.
The Kernel32 function CreateRemoteThread requires it as a parameter, however I've found no way of actually creating an instance of it and any makeshift, identical classes of it which I've made have thrown an "invalid memory access" exception. When creating a new instance of it, it always throws an Exception with the following error message:
Exception in thread "main" java.lang.Error: Structure.getFieldOrder() on class com.sun.jna.platform.win32.WinBase$FOREIGN_THREAD_START_ROUTINE returns names ([foreignLocation]) which do not match declared field names ([])
But it also has ONLY a no-arg constructor and is not declared abstract, so having to override the getFieldOrder method AND re-declare the foreignLocation member (It is already declared in the class, but it's declared private and getFieldOrder is not overridden in the class itself so the foreignLocation member is therefore unavailable to the getFieldOrder method declared in the Structure class) in the instance itself seems like bad design to me.
In short:
is the FOREIGN_THREAD_START_ROUTINE class actually functional, and if it is, how can it be instantiated successfully?
Any help would be greatly appreciated!
When I read the documentation about Class, as to forName() method, the documentation said:
Class.forName ("Foo")
is equivalent to:
Class.forName ("Foo", true, this.getClass().GetClassLoader())
I don't know what the meaning of this.getClass().GetClassLoader() and why it works in this way, I just know it is a ClassLoader to load class when JVM complier the code.
A ClassLoader is an object capable of loading bytecode as a class into the VM. See here for the offical docs.
Class.forName(String name) allows you to load a class at runtime - the supplied String can by determined at runtime. To actually load a class one needs a ClassLoader thus it was chosen that the ClassLoader the class of the calling object was loaded with is the default one. You access that ClassLoader with this.getClass().getClassLoader().
The second parameter - defaulting to true - determines if static intialization is performed for the class if necessary (if it hasn't been performed earlier).
class.forName returns the Class object associated with the class or interface with the given string name. Invoking this method is equivalent to:
Class.forName(className, true, currentLoader)
where currentLoader denotes the defining class loader of the current class.
I have difficulty in using a generated bytecode class which is loaded by Unsafe.defineAnonymousClass(). I am wondering how to use an object of anonymous class to initiliaze another class (or anonymous class).
Take an example class Callee below for example, its constructor accepts Callee2 as parameter.
Class Callee{
Callee2 _call2;
public Callee(Callee2 callee2){
...
}
}
During runtime, I generated new classes for both Callee2 and Callee, and both new classes are loaded by Unsafe.defineAnonymousClass(). For new Callee, the constructor is also changed to be:
public test.code.jit.asm.simple.Callee(test.code.jit.asm.simple.Callee2.1506553666);
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=2
0: aload_0
1: invokespecial #65 // Method java/lang/Object."<init>":()V
....
8: return
while the generated class name of Callee2 is:
class test.code.jit.asm.simple.Callee2/1506553666
I created an instance of `Callee2/1506553666' and want to create instance of new Callee with it, but fail:
newCls.getConstructor(args).newInstance(objs);
where
args = [class test.code.jit.asm.simple.Callee2/1506553666]
and
objs= [test.code.jit.asm.simple.Callee2/1506553666#39b0a038]
The args[0] is meanless as this class is loaded by anonymous loader (Anonymous classes are not referenced by any class loaders). So it really puzzles me how to pass objects in objs array to a method invocation..
The exception occurs on the invocation of getConstructor (args) with message:
java.lang.NoClassDefFoundError: test/code/jit/asm/simple/Callee2/1506553666
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2483)
at java.lang.Class.getConstructor0(Class.java:2793)
at java.lang.Class.getConstructor(Class.java:1708)
at code.jit.asm.util.ReflectionUtil.adapt2GeneratedObject(ReflectionUtil.java:36)
at code.jit.asm.services.BytecodeGenerator.generator(BytecodeGenerator.java:164)
The exception is clearly for me since the anonymous class is transient to any classloader. But in my case, I do need initialize the new Callee (also anonymous class) by new Callee2 instance (The bytecodes in Callee's constructor will reads Callee2's field members), so is there any workaround to pass new callee2 instance for the new callee's constructor?
Have a look at the signature and documentation comment, which is not available in the standard API documentation as it’s not part of the official API:
Define a class but do not make it known to the class loader or system dictionary.
For each CP entry, the corresponding CP patch must either be null or have the a format that matches its tag:
Integer, Long, Float, Double: the corresponding wrapper object type from java.lang
Utf8: a string (must have suitable syntax if used as signature or name)
Class: any java.lang.Class object
String: any object (not just a java.lang.String)
InterfaceMethodRef: (NYI) a method handle to invoke on that call site's arguments
… (params:)
cpPatches where non-null entries exist, they replace corresponding CP entries in data
public native Class<?> defineAnonymousClass(
Class<?> hostClass, byte[] data, Object[] cpPatches);
In other words, you may provide an array of the same size as the constant pool of the class you’re going to define. Keep nulls where you don’t want to modify it. Right at the places where your constant pool has a CONSTANT_Class_info representing an anonymous class, you simply pass the associated Class object in the array. So there’s no lookup for the class then, you don’t even have to provide the correct class name in the class bytes.
There are some obvious limitations:
Problem will arise if you have circular dependencies as you need an already existing Class object to patch the pool of another class. Well, for class uses that are known to be resolved lazily, it might work
You can only patch CONSTANT_Class_info to a Class which is sufficient for, e.g. accessing members of that class or creating new instances of it. But it doesn’t help when an anonymous class is part of a signature, i.e. you want to declare a field of that type or use a method having it as parameter or return type. But you may access such methods using the option of patching a CONSTANT_InterfaceMethodref_info entry via a MethodHandle (ahem, once implemented as I guess “NYI” means “not yet implemented”)…
We can get class Class object by 3 methods:
MyClass.class
obj.getClass
Class.forName("className")
I don't understood the difference between: MyClass.class and Class.forName("className").
Because both will need Class Name.
Class.forName("className");
forName is a static method of class "Class".
we require to provide the fully qualified name of the desired class.
this can be used when name of class will come to known at runtime.
ClassName.class;
.class is not a method it is a keyword and can be used with primitive type like int.
when Name of Class is known in advance & it is added to project, that time we use ClassName.class
I don't understood the difference between: MyClass.class and Class.forName("className").
Because both will need Class Name.
The big difference is when they need it. Since Class.forName accepts a string, the class name can be determined at runtime. Whereas of course, MyClass.class is determined at compile-time. This makes Class.forName useful for dynamically loading classes based on configuration (for instance, loading database drivers depending on the settings of a config file).
Rounding things out: obj.getClass() is useful because you may not know the actual class of an object — for instance, in a method where you accept an argument using an interface, rather than class, such as in foo(Map m). You don't know the class of m, just that it's something that implements Map. (And 99% of the time, you shouldn't care what its class is, but that 1% crops up occasionally.)
Class.forName("className");
It dynamically load the class based on fully qualified class name string.
obj.getClass
Returns the java.lang.Class object that represents the runtime class of the object.
MyClass.class:
A class literal is an expression consisting of the name of a class, interface, array,
or primitive type, or the pseudo-type void, followed by a'.' and the token class.
The type of C.class, where C is the name of a class, interface, or array type is Class<C>.
http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf
One important difference is:
A.class will perform loading and linking of class A.
Class.forName("A") will perform loading, linking and initialization of class A.