Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Динамическая загрузка классов


Автор: rith2 12.4.2009, 19:41
Код

public class CompilingClassLoader extends ClassLoader{

    private byte[] getBytes(String filename) throws IOException { // Считывание данных из файла класса
        System.out.println("ComlilClassLoader.getBytes");
        File file = new File(filename);
        long len = file.length();
        FileInputStream fin = new FileInputStream(file);
        return createByteArray(fin);
    }

    private byte[] createByteArray(InputStream in) throws IOException { //преобразование в последовательность байт
        final int bufferSize = 2024;
        byte result[] = new byte[bufferSize];
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int len = 0;
        while((len = in.read(result)) != -1) out.write(result, 0, len);
        return out.toByteArray();
    }

    private boolean compile(String javaFile) throws IOException {   //компиляция файла
        System.out.println("CompilClassLoader.compile");
        System.out.println("Compiling " + javaFile);
        Process process = Runtime.getRuntime().exec("javac " + javaFile);
        int returnCode = process.exitValue();
        return returnCode == 0;
    }


    public Class loadClass(String name, boolean resolve) throws ClassNotFoundException { //загрузка класса
        Hashtable ClassCache = null;
        Class clas = null;
        System.out.println("CompilClassLoader.loadClass");

        clas = findLoadedClass(name);                     //возможно этот класс уже вызывался
        String fileStub = name.replace(".", "/");
        String javaFileName = fileStub+".java";        //получаем имя класса .class
        String classFileName = fileStub+".class";      //получаем имя файла .java

        File javaFile = new File(javaFileName);
        File classFile = new File(classFileName);

        if (javaFile.exists() && (!classFile.exists() || javaFile.lastModified() > classFile.lastModified())) {    //если сущестует .java и отсутствует .class  .......................................................................................................................................................либо .java был изменен и .class уже неактуален
            try {
                compile(javaFileName);            //то компилим .java
            }catch(IOException e) {
                System.out.println("CompilClassLoader.loadClass exception - " + e);
            }
        } 

        byte raw[] = null;
        try {
            raw = getBytes(classFileName);    //получаем набор байт
            clas = defineClass(name, raw, 0, raw.length);    // проблема здесь (более подробно описана ниже)
            if (clas != null) {                                                
                resolveClass(clas);
            }
        }catch(IOException e) {
            System.out.println(e);
        }
        if (clas == null) {                             //Ищем в системных классах
            clas = findSystemClass(name);
        }
        if (clas == null) {
            throw new ClassNotFoundException(name);
        }
        return clas;
    }

}


Вплоть до defineClass все работает нормально - переменная name - содержит имя класса, raw - набор байт. Но почемуто когда доходит до выполнения этой команды, то класс loadClass заново вызывается и переменная name (которая должна содержать имя вызываемого файла .class) уже содержит java\lang\Object.class (откуда он взялся не понятно). Вот полный вывод - 
run:

CompilClassLoader.loadClass
ComlilClassLoader.getBytes
CompilClassLoader.loadClass
ComlilClassLoader.getBytes
java.io.FileNotFoundException: java\lang\Object.class (Системе не удается найти указанный путь)
CompilClassLoader.loadClass
ComlilClassLoader.getBytes
java.io.FileNotFoundException: java\awt\image\RenderedImage.class (Системе не удается найти указанный путь)
CompilClassLoader.loadClass
ComlilClassLoader.getBytes
java.io.FileNotFoundException: java\lang\String.class (Системе не удается найти указанный путь)
CompilClassLoader.loadClass
ComlilClassLoader.getBytes
java.io.FileNotFoundException: java\io\IOException.class (Системе не удается найти указанный путь)
CompilClassLoader.loadClass
ComlilClassLoader.getBytes
java.io.FileNotFoundException: java\awt\AWTException.class (Системе не удается найти указанный путь)
BUILD SUCCESSFUL (total time: 0 seconds)

все это что идет после java.io.FileNotFoundException: какимто образом попадает в "name".  Помогите!   Этот примерчик нашел в книге, юзал гугл в том числе испольовал многие моменты из вашего ФАКа. Но странное поведение defineClass так и осталось.

Юзаю NetBeans 6.5 Java: 1.5.0_17

Автор: rith2 12.4.2009, 20:15
Снова и снова пошагово выполняю... есть подозрения что считывание в массив байт как то не так идет.... переделываю... с другой стороны тогда бы ексепшн выдавал, а тут просто мой класс где вызывается defineClass заново стартует с другими значениями. Сколько читал статей никто не знает как она работает smile))))



 ! 
powerOn
Модератор: Давайте выражать свои мысли цензурными словами.

Автор: ivg 12.4.2009, 20:29
В JavaDoc'е ведь всё написано.
Цитата

The methods and constructors of objects created by a class loader may reference other classes. To determine the class(es) referred to, the Java virtual machine invokes the loadClass method of the class loader that originally created the class. 

И это 
Цитата

The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader. When requested to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself.

Автор: rith2 13.4.2009, 15:31
Цитата

В JavaDoc'е ведь всё написано.


Блин.. читал ведь все это и даже внимание не обратил. Спасибо, разобрался в задаче, все работает!

2 Модератор - извиняйте, типо так пошутить неудачно пытался smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)