Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.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_Multithreading_Jakarta Ee_Osgi - Fatal编程技术网

Java线程上下文类加载器-它是如何工作的?

Java线程上下文类加载器-它是如何工作的?,java,multithreading,jakarta-ee,osgi,Java,Multithreading,Jakarta Ee,Osgi,我在internet上找到了OSGi的以下加载程序结构 引导类加载器(来自jre/lib/rt.jar的Java标准库 etc)^扩展类加载器^系统 类加载器(即$CLASSPATH上的东西,OSGi核心代码)^(** 从父类加载器对类型的访问受限通用OSGi 类加载器: --|--bundle1->(导入包映射->类加载器)的OSGi类加载器 --|--bundle2->(导入包映射->类加载器)的OSGi类加载器 --|--bundle3->的OSGi类加载器(导入包映射->类加载器) 上面

我在internet上找到了OSGi的以下加载程序结构

引导类加载器(来自jre/lib/rt.jar的Java标准库 etc)
^
扩展类加载器
^
系统 类加载器(即$CLASSPATH上的东西,OSGi核心代码)
^(** 从父类加载器对类型的访问受限
通用OSGi 类加载器:
--|--bundle1->(导入包映射->类加载器)的OSGi类加载器
--|--bundle2->(导入包映射->类加载器)的OSGi类加载器
--|--bundle3->的OSGi类加载器(导入包映射->类加载器)

上面说

在执行线程上设置的上下文类加载器。默认情况下为 始终设置为System classloader或从新 已创建线程实例

从上面的结构中,我们看到系统加载器(=上下文加载器)具有更高的位置,而且据我所知,父类加载器从不询问其子类


因此,我的问题是,请解释当前线程如何与当前捆绑包中的类一起工作?

在OSGi中,线程上下文类加载器(TCCL)只是未定义的。您不能期望或断言它将是任何特定的。事实上,很多时候它将是
null

TCCL是在Java1.2中添加的一种支持J2EE的技术。具体来说,它是支持实体bean之类的东西所必需的;在现代世界,它被用来支持JPA、JAXB、Hibernate等技术

父委托的问题是,虽然底部的应用程序类可以看到父类加载器中的所有类,但不幸的是,父类加载器加载的类不能看到应用程序类。实际上,这意味着您的应用程序代码可以加载(例如)组成Hibernate的类,但Hibernate将无法加载域类,因为它们在层次结构中位于域类之下

因此,TCCL被发明了。在J2EE应用服务器中,TCCL被创建为线程局部变量,并且它可以查看所有应用程序类。Hibernate/JPA/JAXB等可以查阅TCCL以查找应用程序类。在J2EE中,这很容易做到,因为应用服务器控制所有入口点:它控制web服务器控制RMI端点,作为应用程序开发人员,您不允许创建自己的线程

然而,OSGi的编程环境受的约束要小得多。任何捆绑包都可以创建自己的网络端点、启动自己的线程,或者几乎可以做任何事情。因此,OSGi没有机会干预并强制使用具有应用程序类可见性的TCCL。此外,“应用程序”的概念一个应用程序由多个bundle组成…但是如何定义哪些bundle可以为TCCL提供类呢


所以OSGi基本上是在这个问题上下赌注。TCCL是未定义的,所以你永远不应该依赖它。幸运的是,大多数试图使用它的库只是作为它们尝试从中加载类的一系列位置之一。在OSGi中,线程上下文类加载器(TCCL)只是未定义。您不能期望或断言它将是任何特定的内容。事实上,很多时候它将是
null

TCCL是在Java1.2中添加的一种支持J2EE的技术。具体来说,它是支持实体bean之类的东西所必需的;在现代世界,它被用来支持JPA、JAXB、Hibernate等技术

父委托的问题是,虽然底部的应用程序类可以看到父类加载器中的所有类,但不幸的是,父类加载器加载的类不能看到应用程序类。实际上,这意味着您的应用程序代码可以加载(例如)组成Hibernate的类,但Hibernate将无法加载域类,因为它们在层次结构中位于域类之下

因此,TCCL被发明了。在J2EE应用服务器中,TCCL被创建为线程局部变量,并且它可以查看所有应用程序类。Hibernate/JPA/JAXB等可以查阅TCCL以查找应用程序类。在J2EE中,这很容易做到,因为应用服务器控制所有入口点:它控制web服务器控制RMI端点,作为应用程序开发人员,您不允许创建自己的线程

然而,OSGi的编程环境受的约束要小得多。任何捆绑包都可以创建自己的网络端点、启动自己的线程,或者几乎可以做任何事情。因此,OSGi没有机会干预并强制使用具有应用程序类可见性的TCCL。此外,“应用程序”的概念一个应用程序由多个bundle组成…但是如何定义哪些bundle可以为TCCL提供类呢


所以OSGi基本上是在这个问题上下赌注的。TCCL是未定义的,所以你永远不应该依赖它。幸运的是,大多数试图使用它的库只是作为它们尝试从中加载类的一系列位置之一。在OSGi
Thread.currentThread().getContextClassLoader()中
返回一个特殊的OSGI包类加载器。在Equinox中,它是一个
org.eclipse.OSGI.framework.internal.core.BundleClassLoader
。该类加载器由OSGI容器设置,只知道导入的包和类,这些包和类由
MANIFEST.MF
中的
包类路径定义(默认为
=>捆绑jar本身)@drkunibar我不知道Equinox,但在felix Thread.currentThread()中。getContextClassLoader()返回sun.misc.Launcher$AppClassLoader@2f0f94a0,以及这个.getClass()