如果我有需要在我的 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
任何帮助表示赞赏。安德鲁
我正在使用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 类中读取一个文件。我的问题与此类似,但有两个不同之处。首先,我使用不同的项目布局:
/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),它应该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 字符串文字可以像"abc"垃圾一样收集吗?如果是,我们如何以编程方式证明他们是GCed?
编辑:虽然给出并给出了一个(好的)答案,但这只涉及我的问题中一个相当不重要的部分.这个问题的主要部分仍然是开放的.
我在云项目中使用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实体类).
当的帮助下运行单元测试JUnit和spring-test的DataSource实例使用的内存数据库H2(使用创建EmbeddedDatabaseBuilder的spring-jdbc).在此设置中,我必须指定JPA以使用用于DataSource实例的类加载器(eclipselink.classloaderJPA属性映射中的键),否则我得到"对象...不是已知的实体类型".
在嵌入式Apache Tomcat 8中运行测试时,我看不到任何指示正在使用的连接池的消息.在这个设置中,我还必须为单元测试设置类加载器.
如果我将commons-dbcp(2.1.1)添加到我的项目并显式配置spring-cloud-connector插件以使用它而不是Tomcat的连接池,我可以在Tomcat上运行应用程序而无需配置类加载器,但它也适用于上述类加载器规范.
对于测试,commons-dbcp与上面概述的情况相比,没有任何改变(因为没有使用相应的配置).
摘要:
DataSourceJPA的类加载器你能帮我理解这里的不同之处,并建议一个适合所有情况的简单解决方案吗?我假设DBCP和Spring使用与Tomcat(和Tomcat的连接池)不同的类加载器.
如果您需要更多信息,我很乐意添加它.
编辑:我添加了一个示例项目,其中包含有关如何重现的大型自述文件.
我目前正在阅读类加载器及其层次结构功能。如果我调用下面的代码 -
ClassA a= Class.forName("com.test.ClassA")
Run Code Online (Sandbox Code Playgroud)
根据我的理解,现在它将在应用程序类加载器的帮助下初始化并加载到内存中。我有以下问题:
我在 Eclipse 中有两个具有相同声明依赖项的项目。一组单元测试有效,另一组无效。我收到一个错误No tests matching [*methodname*]。一些谷歌搜索表明库问题,但我无法确定可以在哪里引入这些问题。项目几乎相同,测试框架(junit、powermock、mockito)应该相同。在首选项中查看 java 构建路径 -> java 构建路径显示相同的引用。我怀疑 eclipse 菜单没有反映在运行时加载的实际类。有没有办法在运行时回显类路径,以便我可以扫描它以查找重复项?
更新:潜在的问题是我在类路径上有 junit 和 powermock 的版本冲突。我能够通过从 eclipse 构建路径配置面板中删除、重新添加和重新排序 jar 来解决这个问题。这是非常乏味的,下面接受的解决方案会显着减少解决时间。
这个问题被标记为重复,但链接的文章特定于 maven,并没有解决在运行时看到类路径的潜在问题。公认的解决方案适用于 maven 和非 maven 项目。
我知道有一个“引导类加载器”从 jre/lib(rt.jar 等)加载所有类。是否有可能让我使用这个“引导类加载器”以便从另一个非 java 包加载额外的类?
我说的是引导程序类路径,它与此答案中描述的常规类路径非常不同:我应该如何在运行时动态加载 Jars?
我们有一个带有自定义类加载器的应用程序,我需要访问给定类的 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诡计?
classloader ×10
java ×10
byte-buddy ×1
class ×1
classpath ×1
eclipse ×1
eclipselink ×1
file ×1
getresource ×1
java-ee ×1
jpa ×1
junit ×1
reflection ×1
string ×1
tomcat ×1
weblogic ×1
weblogic12c ×1