标签: classloader

首次使用后让Classloader保持打开状态

我正在创建一个URLClassloader来加载一些罐子.每个jar都从不同的类加载器中正确加载,每个jar包含一个带有方法run()的类.现在,这个run()的主体可以在其中创建一个匿名内部类.但是,因为我在try-with-resources块中创建了我的URLClassloader,它会自动关闭,并且在运行时尝试加载匿名内部类时会抛出NoClassDefFoundError,因为类加载器已经关闭.

现在我的问题是,这些情况的正常做法什么?是否可以让类加载器保持打开状态,以便以后需要加载其他内容时,它可以吗?有没有办法重新打开一个封闭的类加载器?
如果我打开类加载器,编译器会向我发出有关潜在资源泄漏的警告所以我觉得这就像溪流,你不应该让它们无限期地开放.但是由于类加载器的性质,如果它不是加载匿名类的相同类加载器,则它不能在外部类中使用

这是创建类加载器的代码

public Player(File codePath) throws PlayerException {

   try (URLClassLoader loader = new URLClassLoader(new URL[] { codePath.toURI().toURL() })) {

   //load class from Jar where run() method creates anonymous class that comes in the jar too


   } catch (ClassCastException | IOException | ClassNotFoundException | InstantiationException
| IllegalAccessException | IllegalArgumentException | InvocationTargetException
| SecurityException exc) {
throw new PlayerException("Error loading player's code", exc);

}
Run Code Online (Sandbox Code Playgroud)

java classloader

9
推荐指数
1
解决办法
1718
查看次数

Spring注释如何工作?

动机

作为我之前关于类加载的问题的后续跟进

我很好奇注释如何在流行的Spring框架中工作.

可能解决方案

据我了解,可能会使用两种机制:

1.字节码上的字节码注入

Spring可以使用自己的类加载器来加载所需的类.在运行时,当加载类并且Spring确定它具有一些适当的注释时,它会注入字节码以向类添加其他属性或行为.

因此,@Controller可以更改注释的控制器以扩展某些控制器基类,并且可以更改函数以在注释时实现路由@RequestMapping.

@Controller
public class HelloWorldController {

    @RequestMapping("/helloWorld")
    public String helloWorld(Model model) {
        model.addAttribute("message", "Hello World!");
        return "helloWorld";
    }
}
Run Code Online (Sandbox Code Playgroud)

2.用于实例化的反射

@Autowired 可以通过BeanFactory在运行时反射来读取,以处理实例化顺序并实例化已配置的属性.

public class Customer 
{
    private Person person;

    @Autowired
    public void setPerson(Person person) {
        this.person = person;
    }
}
Run Code Online (Sandbox Code Playgroud)

Spring注释如何真正起作用?

spring annotations classloader spring-ioc

9
推荐指数
1
解决办法
5103
查看次数

如何在maven中使用不同的JAR进行编译和测试?

我编译我的程序对javaee-api.但是对于Junit测试,我必须使用像glassfish的javaee.jar这样的特定实现来避免像java.lang.ClassFormatError这样的错误:在类文件javax/persistence/Persistence中不是本机或抽象的方法中的Absent Code属性(另请参见1).

因此,请避免使用仅在glassfish实现中可用的方法,我想使用常规api编译我的工件,但是使用实现jar运行junit.但两者都提供相同的命名类和推理,因此类加载器遇到麻烦.

解决这个问题的最佳方法是什么?我可以用maven解决这个问题吗?

非常感谢

maven-2 unit-testing jar classloader dependency-management

8
推荐指数
1
解决办法
3088
查看次数

如何在类路径中找到.jar中的资源?

如果我在类路径的目录中有一组资源文件,我可以使用它来枚举它们ClassLoader.getResources(location).

例如,如果我/mydir/myresource.properties在类路径上,我可以调用类加载器getResources("mydir")并获取包含的URL的枚举myresource.properties.

当我将完全相同的资源打包到.jar中时,在进行调用时,我在URL的枚举中没有得到任何内容.我只用一个包含那些文件夹的jar替换了文件夹结构(它是一个webapp,所以jar进入/WEB-INF/lib).我还有一些其他的电话getResourceAsStream(location)用于通过名字单独获取其他资源,他们都工作正常.

当资源在.jar中时,枚举资源有什么不同?


更新 - 我复制了(ish)容器外的行为.以下代码段的结果在dirProperties设定为在包装中的资源名称具有对象键,但如果包是在一个.jar抛出Properties.load(InputStream的)方法中一个NullPointerException.

Properties dirProperties = new Properties();
dirProperties.load(this.getClass().getClassLoader().getResourceAsStream(location));
Run Code Online (Sandbox Code Playgroud)

容器上的相同代码(Tomcat 5.5)不会抛出异常,但是当文件位于.jar中时会生成一个空的Properties对象.

java resources classpath classloader

8
推荐指数
1
解决办法
4286
查看次数

使JVM使用My Own Class Loader

我写了自己的类加载器.我需要使用类加载器加载所有类.我已通过VM以下内容:-Djava.system.class.loader=MyClassLoader

只使用我的类加载器加载我的包中第一个引用的类.我的包中的其他类正在使用AppClassLoader.

这是MyClassLoader看起来像:

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;

public class MyClassLoader extends ClassLoader {

  public MyClassLoader() {
    super(MyClassLoader.class.getClassLoader());
  }

  public MyClassLoader(ClassLoader parent) {
    super(parent);
  }

  @Override
  public Class<?> loadClass(String name) throws ClassNotFoundException {
    System.out.println("MyClassLoader is loading " + name);
    return super.loadClass(name);
  }//loadClass

  @Override
  public synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    System.out.println("MyClassLoader is loading " + name + " with resolve = " + resolve);
    return super.loadClass(name, resolve);
  }

  @Override …
Run Code Online (Sandbox Code Playgroud)

java classloader

8
推荐指数
1
解决办法
5385
查看次数

如何在JBoss 5.x上使用JPA2?(或如何消除类加载隔离问题?)

我希望JBoss只使用我的war文件中的依赖项.每次我部署这个war文件时,JBoss仍然使用自己的jar.

这是jboss-web.xml我用的:

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
    <class-loading java2ClassLoadingCompliance="false">
        <loader-repository>
            my.package:loader=my-app.war
           <loader-repository-config>
              java2ParentDelegation=false
           </loader-repository-config>
        </loader-repository>
    </class-loading>
</jboss-web>
Run Code Online (Sandbox Code Playgroud)

jboss-classloading.xml:

<?xml version="1.0" encoding="UTF-8"?>
<classloading 
    xmlns="urn:jboss:classloading:1.0"
    export-all="NON_EMPTY"
    import-all="true"
    parent-first="false"/>
Run Code Online (Sandbox Code Playgroud)

JBoss 5.1.0.GA

java war classloader jboss5.x

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

应用程序运行后是否需要java .class文件?

我很难写这个问题的标题,但这是我的情况,我要问的是:

  • 我有一个Java项目,我运行"ant test"来运行测试
  • 测试大约需要10分钟
  • 我可以在运行这些测试的过程中切换到不同的Git分支而不会产生任何后果吗?
  • 我希望测试完成原始代码,并允许我在发生这种情况时简单地在不同的分支上工作.

我想我的问题的根源是:在加载并运行应用程序后是否需要.class文件? 类只是存储在内存中,我不再需要文件系统上的文件了吗?或者它仍然访问/读取文件系统上的东西?

任何洞察或更好地理解java正在运行的应用程序需要什么是值得赞赏的.

java git classloader

8
推荐指数
1
解决办法
286
查看次数

如何在类初始化之前避免因访问静态字段而产生的问题?

我有这个代码:

public abstract class Person {

    public static final class Guy extends Person {

        public static final Guy TOM = new Guy();
        public static final Guy DICK = new Guy();   
        public static final Guy HARRY = new Guy();
    }

    public static final List<Guy> GUYS = ImmutableList.of(Guy.TOM, Guy.DICK, Guy.HARRY);
}
Run Code Online (Sandbox Code Playgroud)

我知道,看起来它应该是一个枚举,它会是,但它需要继承自Person,一个抽象类.

我的问题是:如果我试图访问Guys列表,我没关系.但是我尝试特别访问任何一个Guy,我有一个问题:Guy之前加载Person.但是,由于Guy继承Person,Person加载和尝试访问TOM,但由于Guy已经加载,因此无法再次开始加载,因此我们有一个空引用.(并且ImmutableList不接受null,所以我们得到一个例外.)

所以我知道为什么会这样,但我不知道如何避免它.我可以将List移动​​到Guy类中,但是我将有多个实现Person,并且我想拥有类中所有Persons 的主列表Person.

我觉得很有可能加载静态内部类而不加载它的包含类,但我想这是有道理的.有什么方法可以解决这个问题吗?

java static classloader

8
推荐指数
1
解决办法
255
查看次数

Classloader是JVM的一部分还是JRE的一部分?

我对java还是比较陌生,所以如果这个问题看起来很“傻”,请原谅我。我知道JVM (Java虚拟机)包含在JRE (Java运行时环境)中但是我不确定类加载器和执行引擎是否是JVM的一部分。

我读过的大多数资料都没有说明这一点。相反,在描述JVM的组件时,它们仅讨论运行时数据区 的5个组件(即,堆,JVM堆栈,方法区域,PC寄存器和本机方法堆栈)。虽然我的常识告诉我们要使其成为完整的虚拟机,但它需要输入,内存和处理,但我仍然需要验证这些组件的确切位置。

java jvm classloader

8
推荐指数
1
解决办法
294
查看次数

Java 9,ClassLoader.getSystemClassLoader的兼容性问题

下面的代码将jar文件添加到构建路径,它适用于Java 8.但是,它会抛出Java 9的异常,该异常与转换为URLClassLoader有关.有什么想法可以解决这个问题吗?最佳解决方案将对其进行编辑以与Java 8和9一起使用.

private static int AddtoBuildPath(File f) {
    try {
        URI u = f.toURI();
        URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
        Class<URLClassLoader> urlClass = URLClassLoader.class;
        Method method = urlClass.getDeclaredMethod("addURL", URL.class);
        method.setAccessible(true);
        method.invoke(urlClassLoader, u.toURL());
    } catch (NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException | MalformedURLException | IllegalAccessException ex) {
        return 1;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

java classloader urlclassloader java-9

8
推荐指数
2
解决办法
5405
查看次数