Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Динамическая загрузка классов, defineClass странно себя ведет 
V
    Опции темы
rith2
Дата 12.4.2009, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 83
Регистрация: 29.4.2008

Репутация: нет
Всего: нет



Код

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, 19:47
PM MAIL   Вверх
rith2
Дата 12.4.2009, 20:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 83
Регистрация: 29.4.2008

Репутация: нет
Всего: нет



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



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


Это сообщение отредактировал(а) powerOn - 12.4.2009, 22:01
PM MAIL   Вверх
ivg
Дата 12.4.2009, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Autonomous R&D
**


Профиль
Группа: Участник
Сообщений: 686
Регистрация: 8.2.2006
Где: Екатеринбург

Репутация: 33
Всего: 81



В 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.

PM MAIL   Вверх
rith2
Дата 13.4.2009, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 83
Регистрация: 29.4.2008

Репутация: нет
Всего: нет



Цитата

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


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

2 Модератор - извиняйте, типо так пошутить неудачно пытался smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0428 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.