Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Class.getResourceAsStream on bootstrap class not finding resource

I have the following code:

public class Test {
    public static void main(String[] args) {
        System.out.println(Integer.class.getResourceAsStream("Test.class"));
    }
}

in Test.java. When I compile and run this as java Test, the code prints null.

However the documentation for Class.getResourceAsStream (for Java 21) clearly states

If this Class object was loaded by the bootstrap class loader, the method delegates to ClassLoader.getSystemResourceAsStream(java.lang.String).

As far as I understand, the system loader will load classes in the current directory. And indeed, calling ClassLoader.getSystemResourceAsStream("Test.class") correctly returns a stream. So why does calling Integer.class.getResourceAsStream("Test.class") not work?

On Java 8, but not Java 21, calling int.class.getResourceAsStream("Test.class") does actually return a stream. Integer.class.getResourceAsStream("Test.class"), however, still returns null.

like image 586
user1280483 Avatar asked Dec 22 '25 13:12

user1280483


1 Answers

Before the part you quoted, the documentation says

If this class is in a named Module then this method will attempt to find the resource in the module. This is done by delegating to the module's class loader findResource(String,String) method, invoking it with the module name and the absolute name of the resource.

java.lang.Integer is in the named module java.base, so getResourceAsStream would try to find the resource in the java.base module. The part of the documentation you quoted only applies to Classes in the unnamed module.

In Java 8, there are no modules, so the part you quoted does apply. However, the documentation also says,

Before delegation, an absolute resource name is constructed from the given resource name using this algorithm:

  • If the name begins with a '/' ('\u002f'), then the absolute name of the resource is the portion of the name following the '/'.

  • Otherwise, the absolute name is of the following form:

    modified_package_name/name
    

Where the modified_package_name is the package name of this object with '/' substituted for '.' ('\u002e').

For Integer.class, the absolute name of the resource would be java/lang/Test.class, which obviously is not what you wanted. On the other hand, int.class does not have a package name, so the absolute name for the resource is the same as the string you passed.

like image 91
Sweeper Avatar answered Dec 24 '25 02:12

Sweeper



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!