我看过几个地方"Class.getClassLoader()返回用于加载该特定类的ClassLoader",因此,我对以下示例的结果感到困惑:
package test;
import java.lang.*;
public class ClassLoaders {
public static void main(String[] args) throws java.lang.ClassNotFoundException{
MyClassLoader mcl = new MyClassLoader();
Class clazz = mcl.loadClass("test.FooBar");
System.out.println(clazz.getClassLoader() == mcl); // prints false
System.out.println(clazz.getClassLoader()); // prints e.g. sun.misc.Launcher$AppClassLoader@553f5d07
}
}
class FooBar { }
class MyClassLoader extends ClassLoader { }
Run Code Online (Sandbox Code Playgroud)
不应该声明clazz.getClassLoader()== mcl返回true吗?有人可以解释我在这里缺少的东西吗?
谢谢.
我试图动态地将类加载到组件中.我正在使用文件选择器来选择将要加载的.JAR文件,然后使用选项窗格来获取类的名称.
我已经在互联网上搜索如何将java文件转换为URL以便在URLClassLoader中加载它我已经提出:
File myFile = filechooser.getSelectedFile();
String className = JOptionPane.showInputDialog(
this, "Class Name:", "Class Name", JOptionPane.QUESTION_MESSAGE);
URL myUrl= null;
try {
myUrl = myFile.toURL();
} catch (MalformedURLException e) {
}
URLClassLoader loader = new URLClassLoader(myUrl);
loader.loadClass(className);
Run Code Online (Sandbox Code Playgroud)
我现在收到一个'无法找到符号'错误,将URL加载到URLClassLoader中
是否有(兼容的,如果可能的话)确定加载类的绝对路径的方法?
当然,这并不总是可行的(如果你想到动态创建的类),但如果加载的Class在jar中,如何获取这个jar的绝对路径?
Eclipse的JDT编译器提供了一个接口INameEnvironment,该接口定义了findType(...)使您能够进行级联编译的方法.奇怪的是我想知道是否有任何方法可以使用标准的JDK编译工具包来做到这一点?
注意,该场景是一个模板引擎,它在内存编译中为模板文件生成的类进行相互依赖,并且它无法预测您遇到模板文件的顺序,因此Foo可能需要先编译才能进行父Bar编译,因此你需要一个机制来进行级联编译,这意味着在编译期间Foo你需要生成另一个源Bar并首先编译它以便继续Foo编译:一些代码如下:
private NameEnvironmentAnswer findType(final String name) {
try {
if (!name.contains(TemplateClass.CN_SUFFIX)) {
return findStandType(name);
}
char[] fileName = name.toCharArray();
TemplateClass templateClass = classCache.getByClassName(name);
// TemplateClass exists
if (templateClass != null) {
if (templateClass.javaByteCode != null) {
ClassFileReader classFileReader = new ClassFileReader(templateClass.javaByteCode, fileName, true);
return new NameEnvironmentAnswer(classFileReader, null);
}
// Cascade compilation
ICompilationUnit compilationUnit = new CompilationUnit(name);
return new NameEnvironmentAnswer(compilationUnit, null);
}
// So it's …Run Code Online (Sandbox Code Playgroud) 我需要以编程方式计算给定jar文件中编译的类,接口和枚举的数量(所以我需要三个单独的数字).哪种API对我有帮助?(我不能使用第三方库.)
我已经尝试了相当棘手的方案,似乎并不总是正确的.也就是说,我将每个ZipEntry读入一个byte [],然后将结果提供给我的自定义类加载器,它扩展了标准的CalssLoader,并将此byte []发送到ClassLoader.defineClass(这是保护,无法直接从应用程序代码调用).完整代码在Pastebin上.
有人可以解释类加载和实例化类之间的区别.当我们使用Static变量加载一个类时,它是否也在Class加载的同时实例化?毕竟静态代码是类的一部分而不是它的个别实例.如果有人提供了一个例子来帮助我更好地理解这一点,那将会很有帮助.
我们有一个可执行的JAR文件,有时包含其他JAR文件.(整个事情依赖于其他四个下载的JAR,位于太空中巨型部署乌龟的背面.)在运行时,我们动态加载嵌套的JAR文件,执行以下操作:
// wearyingly verbose error handling elided
URL nestedURL = the_main_system_classloader.getResource("path/to/nested.jar");
File temp = File.createTempFile (....);
// copy out nestedURL contents into temp, byte for byte
URL tempURL = temp.toURI().toURL();
URLClassLoader loader = URLClassLoader.newInstance(new URL[]{ tempURL });
Class<?> clazz = loader.loadClass("com.example.foo.bar.baz.Thing");
Thing thing = (Thing) clazz.newInstance();
// do stuff with thing
Run Code Online (Sandbox Code Playgroud)
这种技术之前已在这里提出过; 链接包括这一个和这个.我们目前的代码有效...
...大多.我真的想找到一些方法来避免临时文件的创建和复制(以及最终的清理,因为众所周知,deleteOnExit是邪恶的).毕竟,在开始时获得的URL指向JAR:
URL nestedURL = the_main_system_classloader.getResource("path/to/nested.jar");
// nestedURL.toString() at this point is
// "jar:file:/C:/full/path/to/the/executable.jar!/path/to/nested.jar"
URLClassLoader loader = URLClassLoader.newInstance(new URL[]{ nestedURL …Run Code Online (Sandbox Code Playgroud) 为什么以下代码会导致ClassNotFoundException?
public class App02 {
public static class A {
}
public static void main(String[] args) throws ClassNotFoundException {
try {
System.out.println("A.class.getCanonicalName() = " + A.class.getCanonicalName());
Class c = Class.forName("tests.App02.A"); //error on this line
System.out.println(c.getName());
}
catch(Exception e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
A.class.getCanonicalName() = tests.App02.A
java.lang.ClassNotFoundException: tests.App02.A
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:190)
at tests.App02.main(App02.java:15)
Run Code Online (Sandbox Code Playgroud) 昨天我将我的第一个Grails(2.3.6)应用程序部署到开发服务器并开始监控它.我刚刚得到一个自动监视器,说明CPU被固定在这台机器上,所以我连接到它.我跑了top,发现是我的Java应用程序的PID固定服务器.我也注意到内存是40%.几秒钟后,CPU停止固定,降至正常水平,内存恢复到~20%范围内.经典主要GC.
在收集的同时,我做了堆转储.在GC之后,我在JVisualVM中打开了转储,并看到大部分内存都是为一个org.codehaus.groovy.runtime.metaclass.MetaMethodIndex.Entry类分配的.总共有近250,000个这样的实例,占用了大约25 MB的内存.
我用Google搜索了这个课程并看了一下它是非常有帮助的Javadocs.所以我仍然不知道这门课做了什么.
但谷歌搜索它也带来了大约十几篇涉及这个类的相关文章(其中一些是SO问题)和Grails/Groovy应用程序的PermGen/classloader泄漏.虽然看起来我的应用程序确实用GC清理了这些250K实例,但仍然令人不安的是它有如此多的实例,并且GC将CPU固定超过5分钟.
我的问题:
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled帮助这个特殊问题?下面的这段代码,我从" / resource "文件夹中的文件夹中获取文件,在Java 8中对我来说很好用:
//e.g fileName = "folder0/file1.extension2"
ClassLoader classLoader = ResourceLoader.class.getClassLoader();
InputStream in = classLoader.getResourceAsStream(fileName);
Scanner scanner = new Scanner(in, "UTF-8");
Run Code Online (Sandbox Code Playgroud)
在Java 9中没有,classLoader.getResourceAsStream(fileName)返回null:
java.lang.NullPointerException: source
Run Code Online (Sandbox Code Playgroud)
但是,如果我直接使用" / resource "文件夹中的文件,这可以正常工作:
fileName = "file0.extension1"; // It works!
Run Code Online (Sandbox Code Playgroud)
我的问题很明显,说实话,有两个:
这是我的项目结构:
*.jar输出结构:
*.jar:
- javaFolder1
-javaFolder1.1
-ResourceLoader.class
-jclass1.1.2.class
-jclass1.1.3.class
-javaFolder1.2
- javaFolder2
- ..
- ..
- unreachableResourceFolderImTryingToAccess1
-resource1.1.ext
-resource1.2.ext
- unreachableResourceFolderImTryingToAccess2
- ..
- unreachableResourceFolderImTryingToAccess3
- ..
-resource0.1.ext
-resource0.2.ext
- ..
- somedll1.dll
- …Run Code Online (Sandbox Code Playgroud) classloader ×10
java ×10
jar ×3
classpath ×1
dynamic ×1
getresource ×1
grails ×1
groovy ×1
in-memory ×1
java-9 ×1
memory-leaks ×1
reflection ×1
swing ×1