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

◇◆丶佛笑我妖孽 提交于 2021-02-10 13:33:47

问题


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?


回答1:


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.




回答2:


As it is mentioned in Java Doc of public URLClassLoader(URL[] urls, ClassLoader parent):

Constructs a new URLClassLoader for the given URLs. The URLs will be searched in the order specified for classes and resources after first searching in the specified parent class loader.

I assume you should create a CustomClassLoader ccl = new CustomClassLoader(); or use another constructor by passing an AccessControlContext object - URLClassLoader(URL[] urls, ClassLoader parent, AccessControlContext acc) or URLClassLoader(URL[] urls, AccessControlContext acc).

There are some articles on creating new class loaders:

https://www.baeldung.com/java-classloaders

https://www.javaworld.com/article/2077260/learn-java-the-basics-of-java-

https://www.oodlestechnologies.com/blogs/Creating-Custom-Class-Loader-In-JAVA/class-loaders.html



来源:https://stackoverflow.com/questions/56786034/how-to-load-java-util-timezone-more-then-once-in-jvm

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!