标签: classloader

类加载器和与 Apache Tomcat 共享 .jar 文件

如果我有需要在我的 webapp 和 Tomcat 之间共享的类(例如自定义领域和主体),那么包含这些类的 .jar 文件应该放在哪里?

目前我将 .jar 放在 ${CATALINA_HOME}/lib 中。当从相同类型的类分配引用时,此结果是 ClassCastException。下面是一个例子:

MyCustomPrincipal principal = (MyCustomPrincipal)FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
Run Code Online (Sandbox Code Playgroud)

上面的方法抛出一个 ClassCastException。该方法返回一个实际的 MyCustomPrincipal 类型(因为这是我的自定义领域在执行身份验证时给 Tomcat 的),显然,它是由不同的类加载器创建的。我该如何解决这个问题,以便 Tomcat 和我的 web 应用程序都可以使用 MyCustomPrincipal?

http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html

任何帮助表示赞赏。安德鲁

java tomcat classloader

3
推荐指数
1
解决办法
2373
查看次数

如何优先于Weblogic域中的JAR而不是来自weblogic系统的JAR

我正在使用Weblogic Server 12.1.1并将一些JAR复制到我的域的lib文件夹中.其中一个JAR是一个org.apache.commons.io罐子.现在我遇到的问题是Weblogic本身在其系统类路径中带有不同版本的commons-io,因此我得到了NoSuchMethodErrors.有没有办法配置Weblogic来优先选择来自域的库而不是来自Weblogic系统的库?

Filtering Classloader仅适用于随application(WEB-INF/lib)提供的那些JAR .

java weblogic classloader java-ee weblogic12c

3
推荐指数
1
解决办法
1万
查看次数

Java 在静态方法中读取文件,使用 ClassLoader 给出 FileNotFoundException

我想在我的 java 类中读取一个文件。我的问题与类似,但有两个不同之处。首先,我使用不同的项目布局:

/src/com/company/project
/resources

在资源文件夹中,我有一个名为“test.txt”的文件:

/资源/测试.txt

在项目文件夹中,我有一个类 test.java

/src/com/company/project/test.java

我希望 mu java 类能够以静态方法读取 test.txt 的内容。我尝试了以下方法:

private static String parseFile()
{
    try
    {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

        String fileURL = classLoader.getResource("test.txt").getFile();

        File file = new File(fileURL);


        ...
    }   
}
Run Code Online (Sandbox Code Playgroud)

以及以下路径:

File file1 = new File("test.txt");
File file2 = new File("/test.txt");
File file3 = new File("/resources/test.txt");
Run Code Online (Sandbox Code Playgroud)

但是当我想读取文件时,它们都会抛出 FileNotFoundException 。如何根据我的项目设置以及该方法需要是静态的这一事实,在上面的代码片段中正确声明我的文件的路径?

java file classloader

3
推荐指数
2
解决办法
1万
查看次数

使用 ClassLoader.getResource() 的正确路径?

我制作了一个函数(Java),它应该bytes从文件中读取并将它们打印到控制台:

public void loadPixels(int size){
    ClassLoader cl = this.getClass().getClassLoader();
    pixels = new byte[size];
    try{
        InputStream stream = cl.getResource("res/" + fileName).openStream();
        stream.read(pixels);
        System.out.println(pixels.toString());
        stream.close();
    }catch(Exception e){
        e.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,我要NullPointerException上线了

InputStream stream = cl.getResource("res/" + fileName).openStream();
Run Code Online (Sandbox Code Playgroud)

对于我尝试打开的文件,名称是“font.spt”,这也是fileName. 该文件位于项目根目录的“res”文件夹中,我目前使用的是 Eclipse IDE。

我对文件路径的方法是错误的,还是其他问题?

回顾一下:fileName指向“font.spt”,它位于 bin 目录中的“res”文件夹下。

编辑:包含 .spt 文件的“res”文件夹现在位于项目的“bin”下,而不是根目录下,但我仍然收到错误消息。当从 IDE 运行或作为导出的 .jar 运行时,我仍然得到NullPointerException,我应该把这些文件放在哪里?有人可以给我截图或示例吗?

java classloader getresource

3
推荐指数
1
解决办法
3987
查看次数

java字符串文字可以被垃圾收集吗?如果是,如何证明?

java 字符串文字可以"abc"垃圾一样收集吗?如果是,我们如何以编程方式证明他们是GCed?

java string garbage-collection classloader

3
推荐指数
1
解决办法
175
查看次数

JPA/EclipseLink:了解ClassLoader问题

编辑:虽然给出并给出了一个(好的)答案,但这只涉及我的问题中一个相当不重要的部分.这个问题的主要部分仍然是开放的.

我在云项目中使用EclipseLink(2.6.2).该项目是一个打包为WAR文件并部署在Apache Tomcat 8上的Web应用程序.持久化上下文是使用Java代码设置的,我在其中指定要使用的实体entityManagerFactoryBean.setPackagesToScan(packagesToScan).此配置通常按预期工作,其中确切地找到指定包中的实体类.

我现在无法理解何时使用哪个类加载器,尤其是在考虑Tomcat,运行测试和使用不同的连接池实现时.

在包含Tomcat连接池的Apache Tomcat上运行时,DataSource使用spring-cloud-connectorplugin(spring-cloud-spring-service-connector)创建实例.在这个设置中,一切都按预期工作,只要我不改变下面描述的类加载器(否则我面对ClassNotFoundException实体类).

当的帮助下运行单元测试JUnitspring-testDataSource实例使用的内存数据库H2(使用创建EmbeddedDatabaseBuilderspring-jdbc).在此设置中,我必须指定JPA以使用用于DataSource实例的类加载器(eclipselink.classloaderJPA属性映射中的键),否则我得到"对象...不是已知的实体类型".

在嵌入式Apache Tomcat 8中运行测试时,我看不到任何指示正在使用的连接池的消息.在这个设置中,我还必须为单元测试设置类加载器.

如果我将commons-dbcp(2.1.1)添加到我的项目并显式配置spring-cloud-connector插件以使用它而不是Tomcat的连接池,我可以在Tomcat上运行应用程序而无需配置类加载器,但它也适用于上述类加载器规范.

对于测试,commons-dbcp与上面概述的情况相比,没有任何改变(因为没有使用相应的配置).

摘要:

  • Tomcat(Tomcat CP):仅对JPA使用未修改的类加载器
  • Tomcat(DBCP):两种变体
  • 测试:仅使用DataSourceJPA的类加载器

你能帮我理解这里的不同之处,并建议一个适合所有情况的简单解决方案吗?我假设DBCP和Spring使用与Tomcat(和Tomcat的连接池)不同的类加载器.

如果您需要更多信息,我很乐意添加它.

编辑:我添加了一个示例项目,其中包含有关如何重现的大型自述文件.

https://github.com/C-Otto/classloaderexample

java jpa classloader eclipselink apache-commons-dbcp

3
推荐指数
1
解决办法
799
查看次数

两次调用 Class.forName()

我目前正在阅读类加载器及其层次结构功能。如果我调用下面的代码 -

ClassA a=  Class.forName("com.test.ClassA")
Run Code Online (Sandbox Code Playgroud)

根据我的理解,现在它将在应用程序类加载器的帮助下初始化并加载到内存中。我有以下问题:

  1. 如果我再次调用上面的代码会发生什么?是否会在内存中为“ClassA”创建新实例,还是会返回相同的加载类引用?
  2. 如果是,根据javarevisited 的这篇文章,“通过使用单独的 ClassLoader,您还可以从多个源加载相同的类,它们将在 JVM 中被视为不同的类” 它将有什么用?

java class classloader

3
推荐指数
1
解决办法
1326
查看次数

如何在非 maven 项目中在运行时查看 java 类路径上的类?

我在 Eclipse 中有两个具有相同声明依赖项的项目。一组单元测试有效,另一组无效。我收到一个错误No tests matching [*methodname*]。一些谷歌搜索表明库问题,但我无法确定可以在哪里引入这些问题。项目几乎相同,测试框架(junit、powermock、mockito)应该相同。在首选项中查看 java 构建路径 -> java 构建路径显示相同的引用。我怀疑 eclipse 菜单没有反映在运行时加载的实际类。有没有办法在运行时回显类路径,以便我可以扫描它以查找重复项?

更新:潜在的问题是我在类路径上有 junit 和 powermock 的版本冲突。我能够通过从 eclipse 构建路径配置面板中删除、重新添加和重新排序 jar 来解决这个问题。这是非常乏味的,下面接受的解决方案会显着减少解决时间。

这个问题被标记为重复,但链接的文章特定于 maven,并没有解决在运行时看到类路径的潜在问题。公认的解决方案适用于 maven 和非 maven 项目。

java eclipse junit classpath classloader

3
推荐指数
1
解决办法
2666
查看次数

如何以编程方式通过引导类加载器加载另一个类?

我知道有一个“引导类加载器”从 jre/lib(rt.jar 等)加载所有类。是否有可能让我使用这个“引导类加载器”以便从另一个非 java 包加载额外的类?

我说的是引导程序类路径,它与此答案中描述的常规类路径非常不同:我应该如何在运行时动态加载 Jars?

java classloader bootclasspath

3
推荐指数
1
解决办法
2013
查看次数

通过反射访问 classLoader 字段

我们有一个带有自定义类加载器的应用程序,我需要访问给定类的 classLoader 字段。但是,无法通过反射访问此字段:-(

JavaDoc forjava.lang.Class很清楚:

// This field is filtered from reflection access, i.e. getDeclaredField
// will throw NoSuchFieldException
Run Code Online (Sandbox Code Playgroud)

所以这就是我在调用时getDeclaredField("classLoader") 得到的结果 可以以某种方式获得(我看到 IntelliJ 调试以某种方式这样做;如何?)

也许是一些byteBuddy诡计?

java reflection classloader byte-buddy

3
推荐指数
1
解决办法
780
查看次数