Hier ist eine alternative Antwort, ohne einen neuen Prozess durch Runtime.getRuntime().exec(...) zu erstellen - und Sie können auch Ihre System.in/out-Kanäle beibehalten. Wie auch immer, wenn Sie neu in der Welt der Java-Programmierung sind und versuchen, die Grundlagen zu erlernen, würde ich vorschlagen, dem Rat von camickr zu folgen und sich nicht mit dem ClassLoader herumzuschlagen, wie unten beschrieben.
Ich gehe davon aus, dass die Klasse, die Sie ausführen müssen, in sich geschlossen ist (keine inneren Klassen verwendet) und sich nicht bereits in Ihrem Klassenpfad oder Ihrer Jarfile befindet, so dass Sie einfach eine Instanz erstellen und deren main() aufrufen können. Wenn mehrere Klassendateien beteiligt sind, wiederholen Sie einfach die Methode für das Laden dieser Dateien.
Also, in der ActionListener, dass Ihr JButton addActionListener()-ed zu ...
public void actionPerformed (ActionEvent e) {
String classNameToRun = e.getActionCommand(); // Or however you want to get it
try {
new MyClassLoader().getInstance(classNameToRun).main (null);
} catch (ClassNotFoundException ce) {
JOptionPane.showMessageDialog (null, "Sorry, Cannot load class "+classNameToRun,
"Your title", JOptionPane.ERROR_MESSAGE);
}}
Sie benötigen eine neue Klasse MyClassLoader, die sich bereits in Ihrem Klassenpfad befindet. Hier ist ein Pseudocode:
import java.io.*;
import java.security.*;
public class MyClassLoader extends ClassLoader {
protected String classDirectory = "dirOfClassFiles" + File.separator,
packageName = "packageNameOfClass.";
/**
* Given a classname, get contents of the class file and return it as a byte array.
*/
private byte[] getBytes (String className) throws IOException {
byte[] classBytes = null;
File file = new File (classDirectory + className + ".class");
// Find out length of the file and assign memory
// Deal with FileNotFoundException if it is not there
long len = file.length();
classBytes = new byte[(int) len];
// Open the file
FileInputStream fin = new FileInputStream (file);
// Read it into the array; if we don't get all, there's an error.
// System.out.println ("Reading " + len + " bytes");
int bCount = fin.read (classBytes);
if (bCount != len)
throw new IOException ("Found "+bCount+" bytes, expecting "+len );
// Don't forget to close the file!
fin.close();
// And finally return the file contents as an array
return classBytes;
}
public Class loadClass (String className, boolean resolve)
throws IOException, ClassNotFoundException,
IllegalAccessException, InstantiationException {
Class myClass = findLoadedClass (packageName + className);
if (myClass != null)
return myClass;
byte[] rawBytes = getBytes (className);
myClass = defineClass (packageName + className,
rawBytes, 0, rawBytes.length);
// System.out.println ("Defined class " +packageName + className);
if (myClass == null)
return myClass;
if (resolve)
resolveClass (myClass);
return myClass;
}
public Object getInstance (String className) throws ClassNotFoundException {
try {
return loadClass (className, true).newInstance();
} catch (InstantiationException inExp) { inExp.printStackTrace();
} catch (IllegalAccessException ilExp) { ilExp.printStackTrace();
} catch (IOException ioExp) { ioExp.printStackTrace();
}
return null;
}
}
Anmerkungen: Dies funktioniert gut, wenn sich die Klasse, die Sie zu laden versuchen, auf Ihrem lokalen Rechner befindet und Sie Java von der Befehlszeile aus ausführen. Ich war nie erfolgreich bei dem Versuch, ein Applet dazu zu bringen, eine Klassendatei von einem Servlet herunterzuladen und zu laden - die Sicherheit lässt das nicht zu. In diesem Fall besteht die Abhilfe darin, ein anderes Applet in einem anderen Fenster auszuführen, aber das ist ein anderes Thema. Das oben beschriebene Laden von Klassen löst das Problem, dass man jede einzelne Klassendatei, die man vielleicht braucht, in ein Jar packen muss - nur um die GUI zu starten. Viel Glück, - M.S.