Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以让类加载器动态地查找Java类吗?_Java_Jvm_Jvm Codecache_Jvm Classloader - Fatal编程技术网

我可以让类加载器动态地查找Java类吗?

我可以让类加载器动态地查找Java类吗?,java,jvm,jvm-codecache,jvm-classloader,Java,Jvm,Jvm Codecache,Jvm Classloader,我希望根据运行时条件动态选择不同的类实现。假设我有一个完全限定类名为C的类。我运行的系统可能有许多C类的定义,每个定义都在自己的jar中。我有一个运行时条件(保存在ThreadLocal中),它告诉我应该选择哪个定义 有人在评论中要求我澄清原始要求,因此我将尽我所能澄清要求。有多个团队编写软件为这个系统做出贡献——在许多独立模块中大约有4000个类。更重要的是,他们可以随着时间的推移而改变。它们目前在单独的JVM中运行,因此类重叠没有问题。现在我们正在考虑在同一个JVM中运行它们,同时在同一个J

我希望根据运行时条件动态选择不同的类实现。假设我有一个完全限定类名为C的类。我运行的系统可能有许多C类的定义,每个定义都在自己的jar中。我有一个运行时条件(保存在ThreadLocal中),它告诉我应该选择哪个定义

有人在评论中要求我澄清原始要求,因此我将尽我所能澄清要求。有多个团队编写软件为这个系统做出贡献——在许多独立模块中大约有4000个类。更重要的是,他们可以随着时间的推移而改变。它们目前在单独的JVM中运行,因此类重叠没有问题。现在我们正在考虑在同一个JVM中运行它们,同时在同一个JVM上运行多个版本;所使用的特定实现集由ThreadLocal区分。因此,最初的问题是如何允许线程一次运行一组实现,另一次运行另一组实现

我有一个tomcat应用程序,目前正在使用OpenJDK 8

我相信我可以编写一个自定义类加载器,根据ThreadLocal操作类路径来选择不同的C定义。但是我担心结果会被缓存在某个地方,比如JVM代码缓存。除非我也可以重写该行为,否则下一次需要该类时,运行时条件可能已更改,缓存中的版本可能会错误


有什么方法可以完成我需要做的吗?

好吧,简单的解决方案是不要有多个类C的定义,而是有“类C1”、“类C2”等(即它们不重叠,可以同时加载),然后运行时属性根据需要选择正确的一个。这是最简单的解决办法,所以首先要慎重考虑。但它可能无法满足您的需求


如果你真的需要一个“C类”有多个单独的实现,那么你实际上谈论的是一个“热插拔”场景。幸运的是,Tomcat和其他工具在很久以前的热交换方面做得很好(有局限性)。您可能已经知道这一点,但是“热插拔”满足了开发人员编写“C类”代码、将其部署到容器中、进行尝试、意识到它有问题、进行快速代码编辑并希望在不重新启动容器的情况下运行修改后的代码的需要。热交换基本上通过在JVM中覆盖新的实现来实现这一点。它只在一定程度上起作用,因为每次“重新部署”都会污染JVM的“类空间”,最终会运行“类空间内存”和/或JVM开始变得不稳定。不过,根据您的需要和容差,热交换可能会起作用。

好吧,简单的解决方案是不要有多个C类定义,而是有“C1类”、“C2类”等(即它们不重叠,可以同时加载),然后您的运行时属性会根据需要选择正确的一个。这是最简单的解决办法,所以首先要慎重考虑。但它可能无法满足您的需求


如果你真的需要一个“C类”有多个单独的实现,那么你实际上谈论的是一个“热插拔”场景。幸运的是,Tomcat和其他工具在很久以前的热交换方面做得很好(有局限性)。您可能已经知道这一点,但是“热插拔”满足了开发人员编写“C类”代码、将其部署到容器中、进行尝试、意识到它有问题、进行快速代码编辑并希望在不重新启动容器的情况下运行修改后的代码的需要。热交换基本上通过在JVM中覆盖新的实现来实现这一点。它只在一定程度上起作用,因为每次“重新部署”都会污染JVM的“类空间”,最终会运行“类空间内存”和/或JVM开始变得不稳定。不过,根据您的需要和容差,热交换可能会起作用。

完成所需操作的干净方法是将C定义为接口,然后您可以加载和使用实现接口C的任何类。

完成所需操作的干净方法是将C定义为接口,然后您可以加载和使用实现接口C的任何类

“缓存”一词不合适。类只链接一次。代码及其链接不依赖于线程。线程局部变量中的条件首先是代码气味,但依赖它进行链接根本不起作用。使用术语“自定义类装入器”和“类路径”在同一句话中,你还没有理解类加载是如何工作的。也许你是对的,我不理解类加载,但我看不出这句话是如何产生的。自定义类加载程序不会从整体上编写的:它将是tomcat的WebappLoader的子类,它的loadClass方法将是暗示根据需要操作类路径,然后调用super.loadClass。这可能是错误的,但请告诉我原因。@HolgerA类路径是一个全局系统属性。为了在单个线程中执行单个类加载操作而对其进行操作会破坏所有可能同时发生的其他类加载操作。并且如果自定义类加载器不需要类路径,就没有必要乱搞全局配置,因为它可以从jar文件中读取类文件,并用两行代码生成一个类。使用class
URLClassLoader
而不是自己实现它,甚至可以免费提供。但这无助于解决问题这种链接不能重复一次。它看起来像一个。忘记你关于条件类加载的想法,从你实际想用条件类加载解决的问题开始…现在这很有用。JVM将通过定义类的加载程序来解决依赖关系。所以当你