简体   繁体   English

ClassLoader:如何从另一个项目加载类

[英]ClassLoader: how to load class from another project

I want to access a class from another project using ClassLoader. 我想使用ClassLoader从另一个项目访问一个类。 How can I specify the path to that class and get that class file? 如何指定该类的路径并获取该类文件?

I want to be able to do this through code as I will be loading many different class files through my application and the path for the different classes will be constantly changing. 我希望能够通过代码执行此操作,因为我将通过我的应用程序加载许多不同的类文件,并且不同类的路径将不断变化。

I am using a CustomClassLoader which is loading class files but only if they are in the project and not in another project 我正在使用CustomClassLoader,它正在加载类文件,但前提是它们在项目中而不在另一个项目中

import java.io.FileInputStream;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;

public class CustomClassLoader extends ClassLoader {

String repoLocation = "C:/TempBINfolder/bin/";

public CustomClassLoader() {
}

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

@Override
protected Class<?> findClass(final String name)
        throws ClassNotFoundException {

    AccessControlContext acc = AccessController.getContext();

    try {
        return (Class) AccessController.doPrivileged(
                new PrivilegedExceptionAction() {

                    public Object run() throws ClassNotFoundException {

                        FileInputStream fi = null;
                        try {

                            String path = name.replace('.', '/');
                            fi = new FileInputStream(repoLocation + path
                                    + ".class");
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            byte[] buffer = new byte[8192]; // a big chunk
                            int read;
                            while ((read = fi.read(buffer)) > 0)
                                baos.write(buffer, 0, read);
                            byte[] classBytes= baos.toByteArray();

                            return defineClass(name, classBytes, 0,
                                    classBytes.length);
                        } catch (Exception e) {
                            throw new ClassNotFoundException(name);
                        }
                    }
                }, acc);
    } catch (java.security.PrivilegedActionException pae) {
        return super.findClass(name);
    }
}
}

Calling the class 打电话给上课

for (Class singleClass : listOfClasses) {
            try {

                ClassLoader classLoader = new CustomClassLoader(ClassLoader.getSystemClassLoader());
                Class stringClass = null;
                try {
                    stringClass = classLoader.loadClass(singleClass.getName());
                } catch (ClassNotFoundException ex) {
                    Logger.getLogger(CompilerForm.class.getName()).log(Level.SEVERE, null, ex);
                }
                try {
                    stringClass.newInstance();
                } catch (InstantiationException ex) {
                    Logger.getLogger(CompilerForm.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IllegalAccessException ex) {
                    Logger.getLogger(CompilerForm.class.getName()).log(Level.SEVERE, null, ex);
                }


                Class cls = Class.forName(stringClass.getName());

If i try to do Class cls = Class.forName(stringClass.getPackage()+"."+stringClass.getName()); 如果我尝试做Class cls = Class.forName(stringClass.getPackage()+"."+stringClass.getName()); the package is null 包是null

EDIT: The following worked for me 编辑:以下为我工作

URL classUrl;
classUrl = new URL("file:///"+ccl.getRepoLocation());    //This is location of .class file
URL[] classUrls = {classUrl};
URLClassLoader ucl = new URLClassLoader(classUrls);
Class cls = ucl.loadClass(stringClass.getName());    // Current .class files name

使用URLClassLoader为您完成此操作。

That code looks good (I've myself did something similar a long time ago). 那段代码看起来不错(很久以前我自己做了类似的事)。 Altough there's a little bug: 还有一个小虫子:

If you do 如果你这样做

byte[] classBytes = new byte[fi.available()];
fi.read(classBytes);

You are only reading so many bytes as bytes available with no blocking are. 您只读取如此多的字节,因为可用字节没有阻塞 It is, you're not reading the whole file. 是的,你不是在阅读整个文件。 In fact, read method doesn't assure the complete byte buffer will be read. 实际上,read方法并不能保证读取完整的字节缓冲区。

Try to do: 试着做:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[8192]; // a big chunk
int read;
while ((read = fi.read(buffer)) > 0)
   baos.write(buffer, 0, read);
byte[] bytesClass = baos.toByteArray();

or use Streams.copy from Apache. 或者使用Apache的Streams.copy It's a convenience method to do the same. 这是一种方便的方法。

Package definition 包装定义

ClassLoader has a definePackage method. ClassLoader有一个definePackage方法。 I'd bet that you should call that method for every new package you need. 我敢打赌,你应该为你需要的每个新包调用该方法。 Otherwise ClassLoader has no way to define a package but from the full classname and it seems it's not enough. 否则ClassLoader无法定义一个包,但是从完整的类名来看,它似乎还不够。

So code get to this: 所以代码得到这个:

// being package the name of the package for the new class
// being definedPackages a Set<String> member of the classloader

if (!this.definedPackages.contains(package)) {
   definePackage(package,"","","","","","",null);
   this.definedPackages.add(package);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[8192]; // a big chunk
int read;
while ((read = fi.read(buffer)) > 0)
   baos.write(buffer, 0, read);
byte[] bytesClass = baos.toByteArray();

Thanks for the Above Code which Helped me . 感谢上面的代码帮助了我。

SUB : calling same class available in two different locations SUB:在两个不同的位置调用同一个类

I have a class say Abc in classpath jar file and dynamically I generate the same class Abc in local directory with some code changes. 我在classpath jar文件中有一个类说Abc并动态地在本地目录中生成相同的类Abc并进行一些代码更改。

I need to create instance and use the class Abc in local directory , Below is the Working Code , 我需要创建实例并在本地目录中使用类Abc,下面是工作代码,

class CustomClassLoader extends ClassLoader { class CustomClassLoader扩展ClassLoader {

String repoLocation = "./";
//C:/TempBINfolder/bin/
 CustomClassLoader() {
}

 CustomClassLoader(ClassLoader parent) {
    super(parent);
}

@Override
protected Class<?> findClass(final String name)   throws ClassNotFoundException {

    AccessControlContext acc = AccessController.getContext();

    try {
        return (Class) AccessController.doPrivileged(
                new PrivilegedExceptionAction() {

                    public Object run() throws ClassNotFoundException {

                        FileInputStream fi = null;
                        try {

                            String path = name.replace('.', '/');
                            fi = new FileInputStream(repoLocation + path+ ".class");
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            byte[] buffer = new byte[8192]; // a big chunk
                            int read;
                            while ((read = fi.read(buffer)) > 0)
                                baos.write(buffer, 0, read);
                            byte[] classBytes= baos.toByteArray();

                            return defineClass(name, classBytes, 0,
                                    classBytes.length);
                        } catch (Exception e) {
                            throw new ClassNotFoundException(name);
                        }
                    }
                }, acc);
    } catch (java.security.PrivilegedActionException pae) {
        return super.findClass(name);
    }
}
}

calling the CustomClassLoader class, 调用CustomClassLoader类,

    ClassLoader classLoader = new CustomClassLoader(ClassLoader.getSystemClassLoader());
    Class stringClass = (new CustomClassLoader(ClassLoader.getSystemClassLoader())).findClass(packageName+"."+javaFileName);
    Object  t = (Object) stringClass.newInstance();

Thanks, Murwath 谢谢,Murwath

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何使用ClassLoader从另一个项目中加载类 - How can i load a class from another project using ClassLoader 如何使用JUnit在Maven项目中通过自定义类加载器两次加载同一类 - How to load same class by custom classloader twice in Maven project with JUnit 如何从另一个没有包名的类加载器中加载一个类? - How to load a class from another classloader which doesn't have a package name? 如何通过编程方式通过bootstrap类加载器加载另一个类? - How to load another class via bootstrap classloader programmatically? 如何使用 ClassLoader 从另一个 jar 加载 bean XML 文件 - How to load the bean XML file from another jar using ClassLoader 如何使用类加载器将类文件从服务器加载到客户端 - How to use classloader to load class file from server to client 如何使用ClassLoader将项目包含在另一个项目中 - How to include a project in another project using ClassLoader 如何使用ClassLoader或Class以编程方式加载类 - How to use ClassLoader or Class to programatically load a Class 将 java 对象/类从一个类加载器复制到另一个类加载器 - Copy java object/class from one classloader to another classloader 如何使用classLoader动态加载类 - How to load a class dynamically using classLoader
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM