Kann man irgendwie Java-Quellcode der zum Beispiel in einer TXT-Datei gespeichert wird, während der Laufzeit einlesen und ausführen. Falls "Ja" - gibts es Seiten mit guten Beispielen :?:
afaik kann man den java compilier sogar im quelltext aufrufen (und ich meine nicht so, wie man ein beliebiges externes programm aufruft). ich habe mal gelesen, dass es dafür eine klasse geben soll...
Kann man irgendwie Java-Quellcode der zum Beispiel in einer TXT-Datei gespeichert wird, während der Laufzeit einlesen und ausführen. Falls "Ja" - gibts es Seiten mit guten Beispielen
Nein, das will ich natürlich nicht. Mein Problem ist nur das ich grade an einem Programm schreibe, dass die Prüfziffern von Bankkontonummer ermittelt. Leider gibt es zur Zeit über 100 verschiedene Verfahren und es werden Jahr für Jahr mehr (Mathematiker brauchen ja schließlich auch ne Aufgabe :wink: ). Jedes Verfahren einzeln zu implementieren schloss ich von Anfang an aus und so entschied ich mich, da viele Verfahren sehr ähnlich sind, die typischen Parameter eines Verfahren in einer Datei zu speichern. Das Funktionierte am Anfang auch ganz gut - später merkte ich dass die Idee doch nicht so genial war.... :cry: .Die beste Lösung wäre es nun den Code eines Verfahren extern zu speichern - so wäre es sehr leicht das Programm zu updaten ohne groß den Quellcode des Programms zu ändern.
du erstellst dir ein Interface mit dem das Hauptprogramm arbeitet. Alle Prüfdinger implementieren das Interface. In einer config Datei oder so gibst du an welches verfahren aktuell verwendet wird. Die entsprechende Klasse wird dynamisch geladen und dann im Programm verwendet....
irgendwo habe ich auch mal ein Beispiel für einen selbst geschriebenen Classloader gesehen, der direkt Java Sources einlesen kann und dann "automatisch" kompliliert
Bei IBM habe ich ein (sehr) gutes Beispiel gefunden wie man einen eigenen ClassLoader schreibt (Wobei das Tutorial aus Java 1.2 Zeiten stammt) - Jetzt muss ich es nur noch verstehen.... :wink:
Naja - da das mit dem Dynamischen-Laden schon ganz gut klappt, hab ich mir gedacht "Schreibst ein kleines Wizard Tool, dass dir die .class Datein erzeugt". Also hab ich mir eine Test-Anwendung geschrieben, in der man in ein JTextArea Quellcode eingeben kann und danach auf einen Button drücken kann. Sobald man auf den Button drückt - soll die TextArea ausgelesen werden und daraus eine .java Datei geschrieben werden. Diese Datei soll dann compeliert werden, nur treten dabei einige Fehler auf.....
Code:
....//Weil ich zu faul war immer wieder den Test-Code einzugeben - hab ich ihn vorher schon definiert.
JTextArea jtfEingabe = new JTextArea("public class hello { \n"+
"public static void main(String[] args)\n {System.out.println(\"HEllo\");\n }\n}");
....
public void actionPerformed(ActionEvent event)
{
//jBuDoIt ist der Button auf dem an drücken kann
if(event.getSource() == jBuDoIt)
{
try
{
System.out.println("Schriebe:");
DataOutputStream out = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("c:\\javatemp\\hello.java")));
out.writeBytes(jtfEingabe.getText().replaceAll("\n",""));
out.close();
}
catch(Exception e)
{
System.out.println("Error: " + e.toString());
}
File fi = new File("c:\\javatemp\\hello.java");
if(fi.exists())
{
try {
System.out.println("Compeliere: ");
Process p = Runtime.getRuntime().exec( "javac "+ "c:\\javatemp\\hello.java");
try {
p.waitFor();
} catch (InterruptedException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
Und hier die Fehlerausgabe:
java.io.IOException: CreateProcess: javac c:\javatemp\hello.java error=2
at java.lang.Win32Process.create(Native Method)
at java.lang.Win32Process.<init>(Unknown Source)
at java.lang.Runtime.execInternal(Native Method)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at WizDialog.actionPerformed(WizDialog.java:128)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Wenn ich auf at java.lang.Win32Process.create(Native Method) klicke (ich benutze Eqlipse) - öffnet
sich ein Class Editor für die Klasse Win32Process.class in der mir gesagt wird, dass die Datei rt.jar
kein "source attachment" hat und ich dieses per klick auf einen Button hinzufügen kann. Allerdings
bin ich mir dabei etwas unsicher, da ich nicht weiß was ich da hinzufüge.
Wird sich das Problem auflösen wenn ich das hinzufüge oder gibt es eine andere Lösung für das Problem bzw.
Ursache?
Ich hab jetzt mal die rt.jar über den Class Editor hinzugefügt - leider ohne Ergebnis :cry: bzw. er sagt es wäre nicht die richtige rt.jar - leider hab ich aber keine andere.
Stimmt, aber deswegen wird es in der finalen Version des Wizards eine Config-GUI geben in der man, unter anderem, den Pfad der javac angeben kann(wird dann in einer Config-File gespeichert) und der Wizard wird prüfen bevor er compeliert, ob die javac am angegeben Pfad ist (wird doch über file.exists() möglich sein?).
Jein. file.exists kann prüfen, ob eine Datei namens "javac" abgelegt ist. Die Prüfung, ob es sich um den Compiler handelt geht an der Stelle natürlich nicht...!