简体   繁体   中英

Java: What happens when I create the same package as API

I'm curious what would happen if I create the exact same package that exists in an API that the project has (eg java.util from core Java API). Would the compiler give me an error or something?

If the compiler allows this, what would happen if I create a class with a name that the original API has?

Also, does that mean that package-private fields and methods are accessible if the compiler doesn't complain?

I was curious enough that I did my own testing. I created java.util.concurrent and created a Test class with this method:

public static Object getResult(CompletableFuture<?> cf) {
    return cf.result;
}

Then I called it somewhere else in a main method. There is no compile error. Running that causes this:

Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.util.concurrent at java.lang.ClassLoader.preDefineClass(ClassLoader.java:662) at java.lang.ClassLoader.defineClass(ClassLoader.java:761) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) at java.net.URLClassLoader.access$100(URLClassLoader.java:73) at java.net.URLClassLoader$1.run(URLClassLoader.java:368) at java.net.URLClassLoader$1.run(URLClassLoader.java:362) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:361) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)

So, it does seem like it has to do with classloader... or so I thought... Until I took a look at ClassLoader.preDefineClass() :

// Note:  Checking logic in java.lang.invoke.MemberName.checkForTypeAlias
// relies on the fact that spoofing is impossible if a class has a name
// of the form "java.*"
if ((name != null) && name.startsWith("java.")) {
    throw new SecurityException
        ("Prohibited package name: " +
         name.substring(0, name.lastIndexOf('.')));
}

So, it's stopping me because Java wants to protect all the packages starting with java !

I went and tried something else. I added javafx.scene package and another Test class with this method:

public static boolean getBoundsChange(Node n) {
    return n.boundsChanged;
}

Again, there is no compile errors, but it throws this at runtime:

Caused by: java.lang.IllegalAccessError: tried to access field javafx.scene.Node.boundsChanged from class javafx.scene.TestNode at javafx.scene.TestNode.getBoundsChange(TestNode.java:7) at testFX.start(testFX.java:29) at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863) at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326) at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191) ... 1 more

Seems like Java does protect against these, but does so only at runtime.

I created another interface in javafx.scene and just let it extend Consumer<T> . I can use it just like the original Consumer<T> , so there is nothing stopping me from using that package for my new classes.

如果禁止使用包名(例如java ,或者试图闯入被分发在JAR文件中密封的包,则将被类加载器阻止。

Java packages are backed by folders on the file system, therefore you cannot create a copy of a package as it would just be the same folder.

There is nothing stopping you from creating a java.util package in your own project and using that. It would be a unique package name, and have nothing to do with the Java API.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM