标签: classloader

WAS 6.1 java.lang.VerifyError:违反了类加载约束

环境是Linux上的WAS 6.1,部署了一个使用xercesImpl.jar类的webapp.

由于公司政策限制,必须使用以下设置部署应用:

Class Loader Order
    Classes loaded with parent class loader first
->  Classes loaded with application class loader first

WAR class loader policy
    Class loader for each WAR file in application
->  Single class loader for application
Run Code Online (Sandbox Code Playgroud)

WAR文件包含xercesImpl.jar的副本,与编译应用程序时类路径中的相同.

启动webapp时,当Spring尝试解析其配置时,它会抛出:

java.lang.VerifyError: class loading constraint violated 
    (class: org/apache/xerces/jaxp/DocumentBuilderImpl 
    method: parse(Lorg/xml/sax/InputSource;)Lorg/w3c/dom/Document;)
Run Code Online (Sandbox Code Playgroud)

因此分析

看来WAS提供了org.apache.xerces.jaxp.DocumentBuilderImpl的实现,因为我们可以从WAR文件中删除xercesImpl.jar并仍然得到相同的错误(不是ClassNotFoundException).因此,WAS似乎使用自己的副本来解析引用,该副本与我们编译的类文件中的引用不兼容.但是,我能找到的'xercesImpl.jar'的唯一其他实例(除了使用我们的应用程序部署的副本)位于目录中 deploytool,这似乎在应用服务器之外.

我用WAS(所有1300个)扫描了所有的罐子

for i in `find . -name \*.jar`; do jar tvf $i|grep -qi xerces && echo $i ; done
Run Code Online (Sandbox Code Playgroud)

并发现它./java/jre/lib/xml.jar包含所有类org.apache.xerces.*,因此这可能是类加载器解析引用的地方.

这是肮脏的部分:

如果我们改为"父类加载器第一",我们看不到异常.这与预期的行为背道而驰.我们希望使用"application …

java websphere classloader verifyerror

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

我应该向Proxy.newProxyInstance(...)提供哪种ClassLoader?

我已经阅读了文档,但我仍然不明白我应该提供哪个类加载器作为参数.我尝试了一些选项,但这似乎对编译或代理行为没有影响.我可以将任何东西作为类加载器参数传递,包括null,并且代码仍然可以正常工作,这有点令人不安.任何人都可以解释这一点,并告诉我如果我为类加载器提供一个错误的参数会出现什么样的错误?我应该补充一点,我对Java或一般的类加载器没有一个非常直观的想法.

java reflection classloader

10
推荐指数
1
解决办法
2577
查看次数

JMX:如何防止servlet容器中的Classloader内存泄漏?

我想知道是否或如何处理直接或间接从我的应用程序注册的MBean,该应用程序部署在servlet容器上.

在大多数情况下,有两个选项可用于检索MBeanServer可用于注册的选项

  • 创建自己的MBeanServer使用MBeanServerFactory.createMBeanServer()

  • 使用 ManagementFactory.getPlatformMBeanServer()

使用第一个选项时,可以轻松取消注册所有MBean:只需调用即可MBeanServer.releaseMBeanServer(myMBeanServer).

但是,在许多第三方应用程序中经常使用的第二个选项呢?(顺便说一句,这也是Sun/Oracle的推荐方式).

因为使用了平台MBeanServer,所以当servlet上下文被销毁时它不会被注销 - 但更糟糕的是它仍然保留了对web应用程序类加载器的引用.
因此,Web应用程序的所有静态引用都不会被释放,从而导致泄漏.

如果您想测试一下:只需部署一个简单的Web应用程序,该应用程序分配一个100MB阵列,该阵列是静态引用,并使用oracle jdbc驱动程序(它将使用平台mbean服务器注册诊断MBean),部署在tomcat上.停止应用程序并重新启动它 - 重复此操作,然后你就可以了OutOfMemoryError.

问题:

  • 我是否必须处理这些问题,或者是servlet容器和/或第三方库的问题?

  • 有没有办法获取MBeanServer特定类加载哪些类的所有MBean ClassLoader

  • 我该怎么做才能防止这种情况发生?我是否必须跟踪平台的所有已注册MBean并在MBeanServer此期间取消注册contextDestroyed()

java memory-leaks jmx servlets classloader

10
推荐指数
1
解决办法
2042
查看次数

Java/JSF/Tomcat/Spring - Proxy-Object与原始对象有不同的方法

今天我遇到了这个问题,这真的让我烦恼,因为几乎代码已经运行了(并且即使在恢复到旧版本之后也停止了工作).

我正在Facelets-Page上访问一个Spring-Bean.Spring在Proxies中包装这些对象以使用方面和其他一些东西.

问题是,我在尝试访问bean的属性时遇到异常.例外是这样的:

javax.el.PropertyNotFoundException: /customers.xhtml @23,27 value="#{customerBean.customer}": Property 'customer' not found on type $Proxy88
Run Code Online (Sandbox Code Playgroud)

我肯定知道(!!)有相应的getter/setter方法.到目前为止我尝试的事情:

  • 将应用程序部署到另一个tomcat安装
  • 清除所有tomcat-caches,webapp目录
  • 清理eclipse项目
  • 使用javap(以及那里的方法/属性)检查相应的方法
  • 更改bean的范围
  • 更改bean的类名
  • 更改spring bean-id
  • 更改bean的serialVersionUID

无论我做什么,类都不正确地被类加载器正确包装或者没有正确加载.

有谁知道什么可能导致像这样的问题?我不知道该怎么做,所以任何建议都非常感谢!

提前致谢!

问候,罗伯特

java spring proxy-classes classloader tomcat7

10
推荐指数
1
解决办法
1662
查看次数

JVM如何开始寻找类?

  • 我很好奇JVM查找执行程序的所有位置?我更感兴趣的是了解JVM查找类文件的顺序和位置,比如查看java库,扩展库,类路径等任何目录,比如调用java的当前目录?我对JVM行为更感兴趣,而不是类加载器加载类的方式,我知道它有直到root的父委托机制.

  • 如果从编译类保存在文件系统上的目录以及同一目录中的jar文件中执行类,那么JVM是加载两个还是只加载一个?

  • 假设你有一个不安全的线程Vector,如果我们比较它的性能ArrayList,哪一个会更好,为什么?

java jvm classloader

10
推荐指数
2
解决办法
6079
查看次数

JavaCompiler具有自定义ClassLoader和FileManager

我希望在没有机器上存在依赖关系的情况下编译源代码.
示例:文件A.java:

import some.pkg.B; 
public class A extends B {...}
Run Code Online (Sandbox Code Playgroud)

我没有B源存在,我希望挂钩JavaFileManager或自定义ClassLoader以获取有问题的符号(包'some.package'和B类)然后使用我有的服务检索源串.

编译代码:(inputFiles有A.java)

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
CustomClassLoader classLoader = new CustomClassLoader();
StandardJavaFileManager standardfileManager = compiler.getStandardFileManager(this, null, null);
JavaFileManager fileManager = new CustomFileManager(standardfileManager, output, classLoader);
CompilationTask task = compiler.getTask(null, fileManager, this, null, null, inputFiles);
boolean result = task.call();
Run Code Online (Sandbox Code Playgroud)

JavaFileManager(getFileForInput ..)和我的类加载器(findClass,loadClass ..)上的钩子在编译时没有触发,我收到错误消息:

A.java:#: package some.pkg does not exist
A.java:#: cannot find symbol
symbol: class B
Run Code Online (Sandbox Code Playgroud)

编辑

在使用API​​之后,浏览JavaCompiler(旧版本)源代码并阅读编译概述我仍然找不到可以用来向语法树提供符号的API钩子.似乎API需要根据kschneid建议的包名获取所有资源.
我想到的一个解决方法是运行JavaCompiler并分析缺失符号的错误消息.这样我就会知道需要哪些符号,获取它们并重新编译.
还有其他解决方法/解决方案吗?

java classloader java-compiler-api

10
推荐指数
1
解决办法
2325
查看次数

ANT - 无法加载依赖类com/jcraft/jsch/Logger

我的Ant脚本有问题.

我需要将文件复制到Linux服务器

<copy file="../Ant/lib/jsch-0.1.50.jar" tofile="${ant.home}/lib/jsch-0.1.50.jar" />

<scp todir="${server.user}:${server.password}@${server.dev}:${server.dev.dir.config}" trust="true" verbose="true">
    <fileset dir="${src.home}/Config/">
        <include name="**/*" />
    </fileset>
</scp>
Run Code Online (Sandbox Code Playgroud)

文件已正确复制,但我收到此错误:

BUILD FAILED
C:\dev.xml:179: Problem: failed to create task or type scp
Cause: Could not load a dependent class com/jcraft/jsch/Logger
       It is not enough to have Ant's optional JARs
       you need the JAR files that the optional tasks depend upon.
       Ant's optional task dependencies are listed in the manual.
Action: Determine what extra JAR files are needed, and place them in one of: …
Run Code Online (Sandbox Code Playgroud)

java ant classloader

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

在自主计算领域,以下Java代码如何有用?

在我正在学习的一本书中,他们展示了这个Java代码:

Class c = ClassLoader.getSystemClassLoader().loadClass(name);
Class type = this.getClass().getClassLoader().loadClass(name);
Object obj = type.newInstance();
Run Code Online (Sandbox Code Playgroud)

此代码用于动态加载Java类.这本书继续:

卸载模块引发了一个问题.类加载器无法卸载类.卸载类需要卸载类加载器本身.这就是为什么程序员...倾向于定义几个类加载器.

使用此类代码有什么好处?自主计算的想法通常是"自主系统管理".这与Java程序如何受JVM控制有何关系?

来源:自主计算原理设计第166页(Lalanda撰写)

java classloader

10
推荐指数
1
解决办法
356
查看次数

为什么Android类加载器允许从另一个包反射访问包私有类的公共字段?

似乎Android应用程序类加载器允许反射性地获取对public static包私有类的字段的引用,甚至来自不同的包(比上面定义的类中的那个),而Sun JDK类加载器例如没有.

更具体地说,给定以下类定义:

package org.example.a

class PackagePrivateClass {
    public static final Parcelable.Creator<PackagePrivateClass> CREATOR = generateCreator();
}
Run Code Online (Sandbox Code Playgroud)

以下代码在一个单独的包中:

package org.example.b

public class TestClass {
    public void testMethod() {
        final Class classRef = Class.forName("org.example.a.PackagePrivateClass");
        final Field creatorFieldRef = classRef.getField("CREATOR");
        creatorFieldRef.get(null);  // throws here (unless on Android)
    }
}
Run Code Online (Sandbox Code Playgroud)

在Sun JVM上执行时,它会抛出IllegalAccessException最后一行:

java.lang.IllegalAccessException: Class org.example.b.TestClass can not access a member of class org.example.a.PackagePrivateClass with modifiers "public static final"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
...
Run Code Online (Sandbox Code Playgroud)

但是,当在Android设备(5.1 Lollipop FWIW)上运行时,它会在不抛出的情况下执行,并creatorFieldRef.get(null)实际返回对该CREATOR字段的有效引用.

我的问题是:为什么会这样?它是Android类加载器的错误还是功能?(或者,如果适用的话,我的例子中出了什么问题?)

java android classloader dexclassloader

10
推荐指数
1
解决办法
270
查看次数

作为隐藏类加载时,Lambda 表达式和匿名类不起作用

我正在尝试在运行时编译和加载动态生成的 Java 代码。由于 ClassLoader::defineClass 和 Unsafe::defineAnonymousClass 在这种情况下都有严重的缺点,因此我尝试通过Lookup::defineHiddenClass使用隐藏类。这对于我尝试加载的所有类都适用,但调用 lambda 表达式或包含匿名类的类除外。

调用 lambda 表达式会引发以下异常:

Exception in thread "main" java.lang.NoClassDefFoundError: tests/HiddenClassLambdaTest$LambdaRunner/0x0000000800c04400
    at tests.HiddenClassLambdaTest.main(HiddenClassLambdaTest.java:22)
Caused by: java.lang.ClassNotFoundException: tests.HiddenClassLambdaTest$LambdaRunner.0x0000000800c04400
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:636)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:182)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:519)
    ... 1 more
Run Code Online (Sandbox Code Playgroud)

执行实例化匿名类的代码会引发以下错误:

Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    tests/HiddenClassLambdaTest$LambdaRunner+0x0000000800c00400.run()V @5: invokespecial
  Reason:
    Type 'tests/HiddenClassLambdaTest$LambdaRunner+0x0000000800c00400' (current frame, stack[2]) is not assignable to 'tests/HiddenClassLambdaTest$LambdaRunner'
  Current Frame:
    bci: @5
    flags: { }
    locals: { 'tests/HiddenClassLambdaTest$LambdaRunner+0x0000000800c00400' }
    stack: { uninitialized 0, uninitialized …
Run Code Online (Sandbox Code Playgroud)

java classloader invokedynamic jep java-15

10
推荐指数
1
解决办法
900
查看次数