5
votes

I studied java classloader rencently. Now I want to write a class that has the same package name and class name as one of class in rt.jar. For example, write a java.lang.String class by myself, and how to break the parents delegation model to make the jvm load my java.lang.String instead of the one in rt.jar.

Re-edit
Thx, tried. And ↓↓↓


    D:\>java -verbose -Xbootclasspath/p:D:/myrt.jar -jar exe.jar
    [Opened D:\myrt.jar]
    [Opened C:\java\jre\lib\rt.jar]
    [Loaded java.lang.Object from C:\java\jre\lib\rt.jar]
    [Loaded java.lang.String from D:\myrt.jar]
    [Loaded java.io.Serializable from C:\java\jre\lib\rt.jar]
    [Loaded java.lang.reflect.GenericDeclaration from C:\java\jre\lib\rt.jar]
    [Loaded java.lang.reflect.Type from C:\java\jre\lib\rt.jar]
    [Loaded java.lang.reflect.AnnotatedElement from C:\java\jre\lib\rt.jar]
    [Loaded java.lang.Class from C:\java\jre\lib\rt.jar]
    Invalid layout of java.lang.String at value
    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    #  Internal Error (javaClasses.cpp:136), pid=6968, tid=4116
    #  fatal error: Invalid layout of preloaded class
    #
    # JRE version:  (7.0_45-b18) (build )
    # Java VM: Java HotSpot(TM) 64-Bit Server VM (24.45-b08 mixed mode windows-amd64
     compressed oops)
    # Failed to write core dump. Minidumps are not enabled by default on client vers
    ions of Windows
    #
    # An error report file with more information is saved as:
    # D:\\hs_err_pid6968.log
    #
    # If you would like to submit a bug report, please visit:

2
U want to create class name same as java.lang.String ?Kick
Yes Niks, that's what he said. It's a good way to learn about ClassLoader.Paul Hicks
Unfortunately the security manager won't allow you to create a class that resides in package that starts with java.lang. What you are trying to achieve?Maxim Kirilov
The only way to do this is through the use of the -Xbootclasspath/p: option. I would mark this as a duplicate, but the similar question does not have an answer marked as correct, despite having the correct answer. However, note that using this option breaks the terms and condition of using Java (as mentioned in Oracle's official page on JVM options which I cannot seem to find).FThompson

2 Answers

7
votes

You can do this using the -Xbootclasspath/p option at JVM startup:

-Xbootclasspath/p:/path/to/yourimpl.jar

/p stands for "prepend".

Note: -Xbootclasspath isn't a standard java option, so JVMs by different vendors may not support it.

0
votes

Have a look at the java.lang.instrumentation API: you can implement a ClassFileTransformer which ignores the passed-in byte array and returns a bute array containing your own implementation of java.lang.String instead.

Better make sure that it's completely binary compatible with the original though or you will not get very far.