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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> компиляция Java кода средствами Java, нужен нибольшой туториал 
:(
    Опции темы
Ratman
Дата 26.8.2007, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Имеется нужда компилировать формулы прямо в рантайме. Побегал по форуму и нашол 2 варианта
1 - com.sun.tools.javac.Main.compile
2 - javax.util.JavaCompiler

Про первый вычитал только что он устаревший, ненадежный, недокументированый и еще и меняется в каждой новой йдке  smile 
Про второй нинашол ничего кроме суновского javadoc'a. Но несмотря на то, что все там написаное я могу пересказать на русском (с англиским у мну хорошо, с головой плохо smile ), все равно нивкурил как им пользоваться. smile 

Выкиньте пожалуйста пример кода который:
1 - компилирует класс из файла ForCompile.class
2 - все сообщения компилятора выводит в ЛЮБОЙ не-стандартный-консоль потов вывода.
2 - запускает метод someFunc() описанный в этом классе.
PM MAIL   Вверх
Alexandr87
Дата 27.8.2007, 08:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


дыкий псых
***


Профиль
Группа: Завсегдатай
Сообщений: 1459
Регистрация: 27.11.2004
Где: Алматы, Казахстан

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



Цитата(Ratman @  26.8.2007,  16:06 Найти цитируемый пост)
1 - com.sun.tools.javac.Main.compile
2 - javax.util.JavaCompiler

как вариант, можно javac вызывать из программы.
PM Jabber   Вверх
y3u
Дата 27.8.2007, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



а версию JDK сменить не пробовал? В 6 версии с компиляцией теперь богато и документаровано. 

Вот, к примеру ксассег

http://java.sun.com/javase/6/docs/api/java...g/Compiler.html

Вот еще, может пригодится:
Механизм Java Extension

http://java.sun.com/javase/6/docs/technote...ions/index.html

Скриптинг для Java

http://java.sun.com/javase/6/docs/technote...ting/index.html


--------------------
В нашей стране настаивать на кореньях, черной смородине, лимонных корках - гораздо эффективнее, чем на правах
PM MAIL   Вверх
hfnvfy
Дата 8.9.2007, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Добавлено @ 22:00
начитался явадока
ничего не выходит

Код

class Loader extends ClassLoader{//получаем доступ к protected методам
    public Class<?> newClass(String name, byte[] b) {
        return defineClass(name, b, 0, b.length);
    }
    public Class<?> load(String name) throws ClassNotFoundException{
        return loadClass(name,true);
    }
}
public class Test {
    
    public static void main(String[] args){
        Loader l=new Loader();
        byte[] b= "public class Pr{public void print(){System.out.println(\"It works!\");}}".getBytes(); //наш класс
        Compiler.compileClass(l.newClass("Pr", b));//компилируем наш класс
        try {
            Object o = l.load("Pr").newInstance();//создаем экземпляр класса
//            o.print(); - ошибка, этот метод не определен...
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        
    }
}


в чем я ниправ?

Это сообщение отредактировал(а) hfnvfy - 8.9.2007, 22:01
PM MAIL   Вверх
hfnvfy
Дата 10.9.2007, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



ладно, поставим вопрос по другому:
Если кто-нибудь имеет хоть какой-нибудь обрывок кода, в котором реализована ран-тайм компиляция, выложите пожалуйста. Буду благодарен
 smile 

PM MAIL   Вверх
powerOn
Дата 11.9.2007, 00:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


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

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



Цитата(hfnvfy @  8.9.2007,  22:56 Найти цитируемый пост)
Object o = l.load("Pr").newInstance();//создаем экземпляр класса
//            o.print(); - ошибка, этот метод не определен...

да, метод print() не определён в классе Object. А что тут удивительного? smile
Попробуй через Reflection дернуть метод.


--------------------
user posted image нет времени думать - нужно писать КОД!

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


Новичок



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

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



Ура, разобрался. Всем спасибо за помощь. Если вдруг кому понадобиться - выкладываю код:

допустим надо откомпилировать следующий класс

Код
public class TestClass{
    public void ptest(){
        System.out.println("It works! "+this.toString());
    }
}

записываем этот текст в файл TestClass.java в текущем каталоге


Код
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;


class SomeLoader extends ClassLoader{
    /*
     * зараза нихатит создавать объекты класса ClassLoader,
     * т.к. у того нет публик конструкторов
     * поэтому будем создавать объекты этого класса
     */
}
public class Test{
    public static void main(String[]args){
        //это список файлов для компиляции
        ArrayList<String> files1 = new ArrayList<String>();
        files1.add("TestClass.java");

        
        //получаем стандартный JIT компилятор и файловый менеджер
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
        
        
        //получаем список чего-то, наследующего JavaFileObject
        //список можно получать как из коллекции имен файлов, так и собстно файлов
        Iterable<? extends JavaFileObject> compilationUnits1 =
            fileManager.getJavaFileObjectsFromStrings(files1);
        
        
        //получили задачу для компилятора и запустили его на выполнение
        //в итоге в текущем каталоге будет создан TestClass.class
        compiler.getTask(null, fileManager, null, null, null, compilationUnits1).call();
        
        try {
            fileManager.close();
            
            ClassLoader l = new SomeLoader();
            Class<?> clazz = l.loadClass("TestClass");
            //следующие две строки задают массив параметров (в нашем случае пустых)
            Class<?> cl[]=null;
            Object ob[]=null;
            Method ptest = clazz.getMethod("ptest", cl);
            Object o = clazz.newInstance();
            //ну и соссно вызываем метод, определенный в нашем классе
            ptest.invoke(o, ob);
            
        }catch(IOException e){
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        

    }
}


вся эта байда в данном случае предназначена чисто для "разобраться". Тут файл с кодам предварительно создан вручную, используется стандартный файловый менеджер, стандартный поток вывода для сообщений компилятора.

Это сообщение отредактировал(а) Ratman - 12.9.2007, 15:55
PM MAIL   Вверх
YuG
Дата 12.9.2007, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



2Ratman
А где лежат javax.tools.* классы?

PM WWW ICQ Skype   Вверх
Ratman
Дата 12.9.2007, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



пакет включён в jdk SE 1.6 и, естесвенно все более поздние версии.

...\jdk\jre\lib\rt.jar\javax\tools

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


Бывалый
*


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

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



А у меня ToolProvider.getSystemJavaCompiler(); возвращает null. В чём дело?

--------------------
А всё оказывается гораздо проще: пассивные наноструктуры - активные наноструктуры - системы наносистем - молекулярные наносистемы - сингулярность! По пять лет на каждый этап.
PM MAIL   Вверх
pompei
Дата 13.9.2007, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



А я понял почему не работает - потому что у меня jre, а в ней нет компилятора. Работать будет только в jdk!!!

Вопрос: а можно сделать чтобы работало и в jre тоже?

Например компилятор полностью написаный на java, что-то типа:
Код


String code = " public class xxx implements IMy { public void f() { System.out.println( \"Hi!!!\" ); } }";

InputStream in = getInputStreamFromString( code );

byte buffer[] = new byte[1000000000];

OutputStream out = createOutToByteBuffer( buffer );

SuperPuperJavaCompiler wow = new SuperPuperJavaCompiler();

wow.compile( in, out );
// теперь у нас в буфере лежит байт-код

loadClassFromBuffer( buffer );

IMy cool = (IMy)createInstance( "xxx" );

cool.f();




Это сообщение отредактировал(а) pompei - 13.9.2007, 13:23
--------------------
А всё оказывается гораздо проще: пассивные наноструктуры - активные наноструктуры - системы наносистем - молекулярные наносистемы - сингулярность! По пять лет на каждый этап.
PM MAIL   Вверх
Metal_Heart
Дата 13.9.2007, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


а почему бы и нет?
**


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

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



Цитата(pompei @  13.9.2007,  13:10 Найти цитируемый пост)
Вопрос: а можно сделать чтобы работало и в jre тоже?

А смысл где?
Ты хочешь компилить, но не хочешь иметь компилятор? 




--------------------
 не стыдно учиться, а стыдно не учиться 
PM ICQ   Вверх
Ratman
Дата 13.9.2007, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(pompei @ 13.9.2007,  13:10)
А я понял почему не работает - потому что у меня jre, а в ней нет компилятора. Работать будет только в jdk!!!

Плохо, и странно.
пакет javax.tools лежит именно в jre, то есть если у тебя установлена ява-машина (ты можешь запускать .class файлы) вся эта байда должна у тебя работать...


ЗЫ: откомпилировать классы Test и SomeLoader ты, конечно, не сможешь. Вот они откомпилированные в архиве... Закинь это все на С: (или куда там у тя класспас ведет), и попробуй запустить.

Добавлено через 6 минут и 59 секунд
Цитата(pompei @ 13.9.2007,  12:31)
А у меня ToolProvider.getSystemJavaCompiler(); возвращает null. В чём дело?

могу придумать только 1 вариант: у тебя не установлена ява машина
Если она есть, то в неё по умолчанию встроен компилятор, он и запускается одновременно с запуском машины. Ссылку на него и выдает ToolProvider.getSystemJavaCompiler();

ЗЫ: поправляйте меня, если я ошибаюсь. Слишком много всего перечитал за ограниченное время - могу и напутать


Это сообщение отредактировал(а) Ratman - 13.9.2007, 21:47

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  test.rar 2,01 Kb
PM MAIL   Вверх
Ratman
Дата 18.7.2008, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Продолжаем наш концерт по заявкам..


Имеем кусок кода
Код

File tmp = new File("SomeCalc.java");
String inline;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw;
ClassLoader cl;
Class<?> someCalc;
Method m;
Class<?> s[] = null;
Object ob[] = null;
try{
    while (true){
                //Читаем строку из консоли
        inline = br.readLine();
        if (inline.compareToIgnoreCase("exit")==0) break;
                
                //Делаем .java файл, в котом описан некоторый класс
                //В этом классе есть только один метод - он печатает ту самую нашу строку.
        tmp.createNewFile();
        bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tmp)));
        bw.write("public class SomeCalc extends FunctionKeeper{" +
            "public static void showRes(){System.out.println(");
        bw.write(inline);
        bw.write(");}}");
        bw.close();

                //файл успешно компиллируется
        compiler.getTask(null, null, null, null, null, 
          compiler.getStandardFileManager(null,null,null).getJavaFileObjects(tmp)).call();
        tmp.delete();
    
                //класс успешно загружается
        cl = new SomeLoader();
        someCalc = cl.loadClass("SomeCalc");

                //Метод успешно вызывается, и в консоль выводится наша строка
        someCalc.getMethod("showRes", s).invoke(null, ob);
        
    }
    br.close();
}catch(IllegalAccessException e){
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (IllegalArgumentException e) {
    e.printStackTrace();
} catch (SecurityException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
} catch (NoSuchMethodException e) {
    e.printStackTrace();
};


Цикл бесконечный - мы пишем в консоль:
"This is a first Line"
он пишет в консоль :
This is a first line
Мы пишем дальше:
"This is our second line"
а он выводит:
This is a first line

Зараза без проблем пересоздает файл .java уже с новым содержимым, успешно компилирует новый файл, но загружает класс из самого первого. В результате, чтобы вывести другую строку - надо перезапускать программу.

Я никак не могу понять, почему свеже скомпиллированный класс не заменяет старый, а просто исчезает!
PM MAIL   Вверх
Shaggie
Дата 20.7.2008, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 570
Регистрация: 21.12.2006
Где: outer space

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



Цитата(Ratman @  26.8.2007,  14:06 Найти цитируемый пост)
нашол 2 варианта

Вот те третий: Java Compiler Interface.


--------------------
Цитата(alina3000 @  6.3.2014,  10:47 Найти цитируемый пост)
Сорри что не по теме 
PM MAIL ICQ GTalk Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

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

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


 




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


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

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