Search code examples
javaclassloader

How to load java.util.TimeZone more then once in JVM


I create my custom class loader :

new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());

where urls is a new Url("java.util.TimeZone")

After that I load class by name :

Class<?> newTimeZoneClass = loader.loadClass("java.util.TimeZone");

and newTimeZoneClass==TimeZone.class returns true.

The main reason of that my class loader load class from parent loader. How to fix it?


Solution

  • You cannot do this. The Java security model prevents any class loader creating a class in the "java.*" hierarchy. This is hard-coded in the native code of the JVM, so there is no workaround.

    Additionally, the standard class loaders follow the delegation model of asking the parent class loader to load the class before they try to, so you always get the same class instance. Special class loaders are used by application containers to invert this delegation for application specific classes.

    There are a few ways to do this anyway.

    First, TimeZone is an abstract class and the actual implementation is normally sun.util.calendar.ZoneInfo. As this is not in the "java.*" hierarchy, you can create multiple copies in your class loaders.

    Second, you can sub-class TimeZone, and delegate all methods to a JVM provided instance, adding your own functionality as you do so. I've used this to make TimeZone instances singletons in some of my applications.

    Third, as the JDK is open source, you can copy the all the code for TimeZone and its sub-classes into your own application, and then you can have as many versions of the class as you like.

    If you want to change the TimeZone instances returned by the static methods in TimeZone, these delegate to ZoneInfo and you will have to either use reflection to change the outcome. If you know Aspect-J or equivalent, you could also intercept the call.