Why won't JRockit find my classes
This is the second post by Mattis, diving deep into JVM specifics. NoClassDefFoundErrors are a drag. The classloader mechanism in the Java specification is very powerful, but it also gives you plenty of ways to mess things up. In which jar did you put that class file, and why isn't your classloader looking in that jar? In rare cases, you might even have an application that works using Sun Java, but throws a NoClassDefFoundError with JRockit. Surely, this must be a JRockit bug? Not necessarily. There is a slight difference in how the two JVMs work that can explain this behaviour, especially if you modify your classloaders during runtime. Let's take an example: In a separate folder "foo", create a file Foo.java:
public class Foo {
public Foo () {
System.out.println("Foo created");
}
}
Now, in your root folder for this experiment, create the file ClasspathTest.java:
import java.io.File;
import java.net.URLClassLoader;
import java.net.URL;
import java.lang.reflect.Method; public class ClasspathTest {
private static final Class[] parameters = new Class[]{URL.class}; // Adds a URL to the classpath (by some dubious means)
// method.setAccessible(true) is not the trademark of good code
public static void addURL(URL u) throws Exception {
Method method = URLClassLoader.class.getDeclaredMethod("addURL", parameters);
method.setAccessible(true);
method.invoke((URLClassLoader) ClassLoader.getSystemClassLoader(), new Object[]{u});
} public static void main(String[] arg) throws Exception{
// Add foo to the classpath, then create a Foo object
addURL(new File("foo").toURL());
Foo a = new Foo();
}
}
This class has a method "addURL" that basically adds a URL to the classpath of the system classloader. The main method uses this method to first add the folder "foo" to the classpath and then creates a Foo object. When you compile this method, add "foo" to the classpath:
> javac -classpath .;foo Test.java
But when you run the program, don't add foo, simply run
> java Test
Using Sun Java, this will work fine. In the first line of main, we add the foo-folder to the classpath. When we create our first Foo-object, we find the Foo class in the foo folder. Using JRockit however, you get:
Exception in thread "Main Thread" java.lang.NoClassDefFoundError: Foo
at ClasspathTest.main(ClasspathTest.java:20)
To understand this behaviour, you have to first understand how Sun and JRockit runs code. Sun Java is an interpreting JVM. This means that the first time you run a method, the JVM will interpret every line step by step. Therefore, Sun will first interpret and run the first line of main, adding "foo" to the classpath, and then the second line, creating the Foo object. JRockit however uses another strategy. The first time a method is run, the entire method is compiled into machine code. To do this, all classes used in the method needs to be resolved first. Therefore, JRockit tries to find the Foo class BEFORE the "foo" folder is added to the classpath, resulting in the NoClassDefFoundError (still thrown just before trying to use the class). So, who is right? Actually, according to the Java spec, both are. Resolving the classes can be done either right before the class is used or as early as during method invocation. For most developers, this is just trivia, but from time to time we see problems with this from customers. The solution? Don't modify your classloaders in the same method as you need the change to load a class. In the example, the following change works fine in both Sun and JRockit:
public static void main(String[] arg) throws Exception{
// Add foo to the classpath, then create a Foo object in another method
addURL(new File("foo").toURL());
useFoo();
}
public static void useFoo() {
Foo a = new Foo();
}
Here, using JRockit, the class is not resolved until the method useFoo is compiled, which will be AFTER "foo" is added to the classpath. /Mattis PS: Adding URLs to the system classloader during runtime might not be a good idea. But when using your own defined classloaders, modifying these during runtime could very well be according to design.
Why won't JRockit find my classes的更多相关文章
- 代码的坏味道(9)——异曲同工的类(Alternative Classes with Different Interfaces)
坏味道--异曲同工的类(Alternative Classes with Different Interfaces) 特征 两个类中有着不同的函数,却在做着同一件事. 问题原因 这种情况往往是因为:创 ...
- eclipse中的classes文件夹同步问题
问题: 在同步项目时,由于误操作将classes文件夹加入到了同步版本中,这样会导致每次更新程序编译后,会有很多class文件显示在同步清单中. 解决方案: 将classes文件不设置为同步. 1. ...
- Introduction of OpenCascade Foundation Classes
Introduction of OpenCascade Foundation Classes Open CASCADE基础类简介 eryar@163.com 一.简介 1. 基础类概述 Foundat ...
- 6.Configure Domain Classes(配置领域类)【EF Code-First 系列】
在前面的部分中,我们学习了Code-First默认约定,Code-First使用默认的约定,根据你的领域类,然后生成概念模型. Code-First模式,发起了一种编程模式:约定大于配置.这也就是说, ...
- app:clean classes Exception
Error:Execution failed for task ':app:clean'.> Unable to delete directory: C:\Users\LiuZhen\Deskt ...
- Android framework编译出来的jar包classes.jar的位置
在源码环境下编译 Android framework编译出来的jar包classes.jar的位置 out/target/common/obj/JAVA_LIBRARIES/framework_in ...
- yii 核心类classes.php详解(持续更新中...)
classes.php在yii运行的时候将被自动加载,位于yii2文件夹底下. <?php /** * Yii core class map. * * This file is automati ...
- Top 15 Java Utility Classes
In Java, a utility class is a class that defines a set of methods that perform common functions. Thi ...
- Eclipse下无法自动编译,或者WEB-INF/classes目录下没文件,编译失败的解决办法(转载)
文章来源:http://www.cnblogs.com/xfiver/archive/2010/07/07/1772764.html 1. IOException parsing XML docum ...
随机推荐
- Oracle 10 Recycle Bin回收站
这个功能从10g开始有了. (1)什么是Recycle Bin实际上,Recycle Bin只是一个保存被drop的对象的一个数据字典表.所以,可以通过如下语句查询回收站中的信息:select * f ...
- 在centos7上搭建mongodb副本集
1.安装副本集介绍 副本集(Replica Set)是一组MongoDB实例组成的集群,由一个主(Primary)服务器和多个备份(Secondary)服务器构成.通过Replication,将数据的 ...
- 重置mysql的root用户密码
/etc/rc.d/init.d/mysql status /etc/rc.d/init.d/mysql stop mysqld_safe --skip-grant-tables& mysql ...
- "网页安全政策"(Content Security Policy,缩写 CSP)的来历
作者:阿里聚安全链接:https://www.zhihu.com/question/21979782/answer/122682029来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...
- fileinput模块可以循环一个或多个文本文件的内容
fileinput模块可以循环一个或多个文本文件的内容. [默认格式] fileinput.input (files=None, inplace=False, backup='', bufsize=0 ...
- Elasticsearch-2.4.3的单节点安装(多种方式图文详解)
前提: Elasticsearch-2.4.3的下载(图文详解) 1.新建es安装目录 [root@djt002 local]# mkdir elasticsearch [root@djt002 lo ...
- PHP 动态添加 Mcrypt 扩展库
简介: PHP 动态添加 Mcrypt 扩展库,这是一个支持多种加密.解密算法.模式的扩展库. shell > php -m | grep mcrypt # 如果没有输出,就是缺少这个扩展 sh ...
- Mysql 源码编译安装 ( 5.5 、5.6 共存 )
简介: 如何在一台服务器同时运行两 ( 多 ) 个 MySQL 服务. 1.MySQL 5.6 shell > useradd -r -s /sbin/nologin mysql shell & ...
- think in avalon
1.不要设计,也不要通过DOM操作去改变你的页面 你用jQuery去设计一个页面,并让它动起来.这是因为jQuery就是让一切简单的事情变复杂的罪魁祸首. 但是用avalon,你必须从零开始去构思你的 ...
- jquery 报错 Uncaught TypeError: Illegal invocation
遇到这个错误 请检查你的ajax提交方法的参数 1 参数是否都有定义 2 参数个数是否一致 3参数是否都有值(******)