# In einem Plugin main einer anderen Klasse aufrufen



## StefanTmp (18. Okt 2009)

Hallo zusammen, 

wie ist es möglich, während des Ausführens eines Plugins eine main zu starten? Zur Information: Der Benutzer erstellt ein neues File mit der Endung ".test", der eigens erstellte Editor springt an. Jetzt tippt der Benutzer drauf los, speichert und betätigt "Generate" im Kontextmenü des Editors. Nun soll die Klasse Generate aufgerufen werden, welche nicht teil des Plugins ist. Aufteilung der Java-Klassen: Java-Projekt Editor (alles zum Editor) und Java-Projekt Generator (alles zum Generator). Die Generatorklasse besitzt eine main-Methode.

Danke für eure Hilfe. 

Gruß
StefanTmp


----------



## faetzminator (18. Okt 2009)

Entweder du kennst die Klasse während dem programmieren und kannst dann direkt [c]Klasse.main(args)[/c] aufrufen oder du holst dir mit Reflection die Klasse, Methoden etc.


----------



## StefanTmp (18. Okt 2009)

Hallo faetzminator, 

danke für deine schnelle Antwort. Wenn ich versuche, den Generator mittels Generator.main(args) aufzurufen, wird mir die EventTable.class geöffnet, welche Source not found anzeigt. "The JAR of this class file belongs to container 'Plug-in Dependencies' which does not allow modifications to source attachments on its entries".


----------



## faetzminator (18. Okt 2009)

Von was für Plugins sprichst du eigentlich? In welcher Umgebung?


----------



## StefanTmp (18. Okt 2009)

Es handelt sich um ein Eclipse Plugin, dabei habe ich beim Anlegen des Plugins das Template "Plugin with an editor" gewählt, welches einen simplen xml Editor ohne Funktionen erzeugt. Dieses Plugin habe ich nun um Content-Assist-, Formatting- und Outline-Funktionen erweitert. Nun soll die im ersten Post beschriebene Funktionalität noch ergänzt werden


----------



## Wildcard (19. Okt 2009)

Ist doch erstmal egal ob da Source bei ist, oder nicht.


----------



## StefanTmp (19. Okt 2009)

Hallo, 

ich verstehe den Post nicht ganz. Folgendermaßen sieht der Code bisher aus:


```
public void run(IAction action) {
		String[] lArguments={"C:\\PfadZuArgument1\\argument1",  "C:\\PfadZuParsendemFile\\test.a4l",  "C:\\PfadZuOutput\\output" };
		JavaGenerator.main(lArguments);
	}
```

Generiert wird allerdings nichts..
Ich kann auch nicht durch den Generator debuggen, da ich nur die Source angezeigt kriege.


----------



## StefanTmp (19. Okt 2009)

Hallo, 

das oben beschriebene Problem konnten wir lösen, indem wir einfach die Klassen in ein Plugin gepackt und dieses Plugin dann zu den dependencies des Editor-Plugins hinzugefügt haben. Problem ist nun, dass der Generator einige System.exits besitzt, welche den Editor auch beenden, was natürlich nicht sein soll. 

Man kann doch mittels 


```
Runtime.getRuntime().exec("command");
```

externe Programme laden, ginge das nicht auch mit der main() einer Java Klasse?


----------



## Wildcard (19. Okt 2009)

Ja, das geht. ProcessBuilder benutzen, java starten und die Klasse als Argument übergeben


----------



## StefanTmp (19. Okt 2009)

Puh, ein Codebeispiel hast du nicht zufällig zur Hand?
Will nicht unverschämt sein, bin bloß neu in der Thematik

Grüße


----------



## Wildcard (19. Okt 2009)

ProcessBuilder hilft dir nur die Commandline richtig zu escapen, ist also einfacher als Runtime#exec. Ansonsten ist es genau das gleiche, du musst nur den Konsolenaufruf bauen, also zB 
	
	
	
	





```
java -jar -Xmx256m DeinJar.jar
```


----------



## StefanTmp (19. Okt 2009)

DeinJar.jar setzt doch voraus, dass ich das Projekt zu einem Archiv zusammengefügt habe. Wäre bei einer Klasse dann der Parameter java -class -Xmx256m?? MeineKlasse.class nötig?


----------



## Wildcard (19. Okt 2009)

Du kannst Klassen natürlich auch direkt aufrufen, das ist kein Problem


----------



## StefanTmp (20. Okt 2009)

Morgen, 

folgendes Testprogramm:

Klasse starter:
klasse1.class befindet sich direkt in Laufwerk C. 


```
public class starter {
	public static void main(String[] args) throws IOException {
		ProcessBuilder lProcess = new ProcessBuilder("java", "-cp", "C:/",
				"klasse1.class");
		lProcess.start();

	}
}
```

Klasse klasse1:


```
public class klasse1 {
	public static void main(String args[]) throws IOException {
		System.out.println("test");

	}
}
```

Wenn er klasse1 aufrufen würde, müsste doch auch test in der Console ausgegeben werden?


----------



## Wildcard (20. Okt 2009)

Nein, das Process handle hat einen OutputStream (getOutputStream). System.out.println landet in diesem Stream


----------



## StefanTmp (21. Okt 2009)

Ah ok, jetzt habe ich die Sache verstanden. Vielen Dank dafür. 

Eine Frage habe ich noch:

Gibt es die Möglichkeit, diesen Prozess auch zu debuggen?


----------



## Wildcard (21. Okt 2009)

Ja, Stichwort Remote Debugging. Eclipse hat damit kein Problem, du musst nur ein paar zusätzliche Parameter an die VM mitgeben und dich dann mit dem Eclipse debugger verbinden


----------



## StefanTmp (22. Okt 2009)

Hallo, 

zu dem Debugger mein Code bisher:


```
ProcessBuilder builder = new ProcessBuilder().command(
				"java",
				"parser.Generator",
				"Argument1", "Argumen2", "Argument3", 
				"-agentlib:jdwp=transport=dt_socket,server=y,address=8000");
		Map<String, String> environment = builder.environment();

		environment.put("path", ";"); // Clearing the path variable;
		environment.put("path", "java.home");

		builder
				.directory(new File(
						"C:\\PfadZuDerGeneratorClass\\bin\\"));
		builder.redirectErrorStream(true);
		try {
			Process javap = builder.start();
System.out.println(javap.waitFor());
```

Damit stoppt die Ausführung der Klasse, welche den ProcessBuilder aufruft, bei println. Wie geht es jetzt weiter? Ich muss also via Debug -> Configurations -> Remote Java Application eine neue Config GeneratorDebug für die Generatorklasse anlegen?


----------



## StefanTmp (22. Okt 2009)

Update: 
RemoteDebug haut hin, hab mir ein paar Tutorials angeschaut. 

Danke für die Info
Gruß 
StefanTmp


----------

