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


Автор: sabvi 1.3.2004, 12:56

Программа генерирует и записывает в файл код класса.
Например в файл: MyClass.java

Как можно выполнить трансляцию этого класса (программно) и создать экземпляр класса в этой же программе.
т.е.: MyClass myClass = new MyClass();

Автор: DarkDS 1.3.2004, 13:48
Кросспост:
Если пытаться генерить исходный код (файл с расширением ява) то тут одно из 2-х. Либо через шелл запускать компилятор, а потом подгружать через рефлексию полученный файл, либо писать свой компилятор и писать в файл уже скопилированный класс.

ЗЫ. Вообще то не желательно создавать дублирующиеся темы...

Автор: OlegsDP 1.3.2004, 16:53
Самомодифицирующийся код - самый надежный способ сделать программу неотлаживаемой.

Автор: DarkDS 1.3.2004, 20:11
Кстати... А зачем тебе это? Может ты велосипед изобретаешь? smile.gif

Автор: AntonSaburov 2.3.2004, 11:08
В принципе такое возможно.
Как-то мне попалась статья от SUN. Постараюсь ее сократить smile.gif

Итак, начнем с кода примера. Сама форма предназначена только для ввода данных, поэтому конструктор и метод main представляет мало интереса (если Вы конечно не совсем новичок в SWING). Самое интересное находится в методе doCompile в самом низу программы.

Код

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.lang.reflect.*;

public class RunIt extends JFrame
{
 JPanel contentPane;
 JScrollPane jScrollPane1 = new JScrollPane();
 JTextArea source = new JTextArea();
 JPanel jPanel1 = new JPanel();
 JLabel classNameLabel = new JLabel("Class Name");
 GridLayout gridLayout1 = new GridLayout(2,1);
 JTextField className = new JTextField();
 JButton compile = new JButton("Go");
 Font boldFont = new java.awt.Font("SansSerif", 1, 11);

 public RunIt()
 {
   super("Editor");
   setDefaultCloseOperation(EXIT_ON_CLOSE);
   contentPane = (JPanel) this.getContentPane();
   this.setSize(400, 300);
   classNameLabel.setFont(boldFont);
   jPanel1.setLayout(gridLayout1);
   compile.setFont(boldFont);
   compile.setForeground(Color.black);
   compile.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e)
     {
       try {
         doCompile();
       }
       catch (Exception ex) {
         System.err.println("Error during save/compile: " + ex);
         ex.printStackTrace();
       }
     }
   });  
   contentPane.add(jScrollPane1, BorderLayout.CENTER);
   contentPane.add(jPanel1, BorderLayout.NORTH);
   jPanel1.add(classNameLabel);
   jPanel1.add(className);
   jScrollPane1.getViewport().add(source);
   contentPane.add(compile, BorderLayout.SOUTH);
 }

 public static void main(String[] args)
 {
   Frame frame = new RunIt();
   // Center screen
   Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
   Dimension frameSize = frame.getSize();
   if (frameSize.height > screenSize.height) {
     frameSize.height = screenSize.height;
   }
   if (frameSize.width > screenSize.width) {
     frameSize.width = screenSize.width;
   }
   frame.setLocation(
     (screenSize.width - frameSize.width) / 2,
     (screenSize.height - frameSize.height) / 2);
   frame.show();
 }
 
 private void doCompile() throws Exception
 {
   // write source to file
   String sourceFile = className.getText() + ".java";
   FileWriter fw = new FileWriter(sourceFile);
   fw.write(source.getText());
   fw.close();
   // compile it
   int compileReturnCode =
     com.sun.tools.javac.Main.compile(new String[] {sourceFile});

   if (compileReturnCode == 0) {
     // run it
     Object objectParameters[] = {new String[]{}};
     Class classParameters[] = {objectParameters[0].getClass()};
     Class aClass = Class.forName(className.getText());
     Object instance = aClass.newInstance();
     Method theMethod = aClass.getDeclaredMethod("main", classParameters);
     theMethod.invoke(instance, objectParameters);
   }
 }
}


После того как текст набран, его надо скомпилировать. Заметьте, что добавлена дополнительная библиотека tools.jar. Она лежит в SDK - поищите. Т.к. у меня установлена переменная окружения JAVA_HOME, то я ей и воспользовался.

Код
javac -classpath .;%JAVA_HOME%\lib\tools.jar RunIt.java


Если все скомпилировалось, то можно запустить наше приложение.

Код
java -classpath .;%JAVA_HOME%\lib\tools.jar RunIt


ВАЖНО - запускайте именно через java, а не javaw - нам понадобится наблюдать за окном, где запущена сама java.
Перед вами обычная форма у которой верхнее поле ввода для имени класса, второе поле - для тела (программы).

Введите в верхнее поле Sample а в нижнее поле
Код

public class Sample
{
 public static void main(String args[])
 {
   System.out.println(new java.util.Date());
 }
}

и нажмите кнопку Go. И можно будет увидеть с окне, где запущена java сегодняшнюю дату. Дело сделано.

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