Java um "PlugIns" erweitern

Hallo,

ich habe leider überhaupt keine Ahnung, wie ich folgendes Problem angehen könnte und bitte euch darum um Hilfe.

Und zwar habe ich eine Funktion, die variabel erweitert werden soll.

Diese Funktion fragt einen request ab (ist eine JEE-Anwendung), welchen Wert der Parameter "filter" beinhaltet.

Dann wird sinngemäß entsprechend abgefragt

Code:
if (request.getParameter("filter").equals("tbl_index1"))
{
//mache
}

Diese Routine würde ich gerne auslagern. Sodass (z.B.) in einem bestimmten Verzeichnis x Dateien liegen, mit Namen tbl_index1.xxx und so weiter. Diese Dateien werden dann ausgelesen und der Code entsprechend eingefügt.

Das Problem bei der Sache ist, dass ich in den "Subroutinen" auch mit Variablen aus der eigentlichen Funktion arbeiten muss.

Ich möchte also in der Datei (z.B. tbl_index1) frei programmieren können, mit allen Variablen, die auch der Hauptfunktion zur Verfügung stehen.

Lautet der "filter" nun nicht mehr tbl_index1, sondern tblAdressIndex, so wird eine Datei (und der entsprechende Code) tblAdressIndex.xxx geladen und ausgeführt.

Das mag alles enorm bescheiden klingen, nur finde ich einfach keine richtigen Worte um das Problem besser zu beschreiben.

Ich hoffe man kann mich halbwegs verstehen und ein paar entsprechende Schlagworte nennen.


Grüße, KK
 
Hi

ich nehme an, zwischen den einzelnen "//mache" wird es größere Unterschiede geben?
Mach pro Möglichkeit eine eigene Java-Klasse in einer eigenen Datei,
die bei Bedarf erzeugt (Reflection) und gestartet wird.

Damit alle Klasse das selbe Schema haben (zB. eine Methode start mit xy Parametern)
kommt noch ein Interface dazu, das jede Klasse implementiert.

Zu den Variablen aus der Hauptmethode:
Da gibts doch immer die selben Variablen, unabhängig von dem if-Zeug, oder?
Übergib die Variablen einfach zu start (oder wie du es nennst).
Wenns sehr viel sind, mach ein Objectarray oder so.
 
Ich danke dir, Reflections waren das Mittel zum Zweck!

Ich versuche nun zur Laufzeit mittels JavaCompiler eine Java-Datei zu übersetzen und einzubinden, danach invoke ich die noch unbekannte Methode. Allerdings beinhaltet diese Java-Datei (meine oben genannte .xxx-Datei) eine Zeile zum Importieren des Pakets javax.servlet.ServletRequest. Dieses Paket kennt der javac im jdk natürlich nicht.

Wo müsste ich die servlet-api.jar wohl einspielen, damit der javac darauf zugreifen kann?

Vielen Dank schon mal für die Hilfe!!

edit: Hmpf

Code:
private List<String> _options = Arrays.asList( "-d", "../webapps/ROOT/WEB-INF/classes", "-classpath", "../lib/servlet-api.jar");

Sehr geil, es kann weiter gehen!
 
Zuletzt bearbeitet von einem Moderator:
Dir ist aber schon klar, dass nicht jeder Computer mit Java auch einen Compiler hat!?

Zum Jar: Classpath, Manifest, Jar mitgeben

edit: Genau, dieser Classpath...
 
Das mit dem Compiler ist ok, wir liefern bei jeder Installation ein eigenes Java-Paket mit aus.

Viel mehr bereitet mir gerade Sorgen, dass ich die Java-Datei zwar kompiliert bekomme, allerdings Änderungen daran nicht übernommen werden.

Die class-Datei wird im Moment jedes Mal neu generiert, beim Start des Tomcat (ist wie gesagt eine JEE-Anwendung) ist die Klasse noch nicht bekannt, wird also generiert und eingebunden, sodass ein Zugriff per Reflection möglich ist.

Nur wird bloß der erste Zustand der Datei verwendet, alle Änderungen verpuffen im Nirvana, bzw. werden erst wirksam, wenn die Webanwendung neu gestartet wird.

Den aktuellen Quelltext habe ich aus diesem Beispiel in abgewandelter Form übernommen

http://www.java-forum.org/codeschnipsel-u-projekte/61076-code-laufzeit-generieren.html

Bei mir wird die java-Datei halt nicht zur Laufzeit generiert, sondern eine bestehende java-Datei kompiliert.
 
Hmm...weiß schon was du meinst, hab aber dafür selbst keine Lösung.
Hab mit EE ziemlich wenig zu tun.
Warten wir auf den Java-Guru...
 
Die class-Datei wird im Moment jedes Mal neu generiert, beim Start des Tomcat (ist wie gesagt eine JEE-Anwendung) ist die Klasse noch nicht bekannt, wird also generiert und eingebunden, sodass ein Zugriff per Reflection möglich ist.

Nur wird bloß der erste Zustand der Datei verwendet, alle Änderungen verpuffen im Nirvana, bzw. werden erst wirksam, wenn die Webanwendung neu gestartet wird.

Hast Du Tomcat auch für das "hot deployment" konfiguriert? Hierzu genügt es, die Konfiguration für den Host auf autoDeploy="true" und deployOnStartup="false" zu setzen.
 
Soweit ich weis ist das so eine Macke des ClassLoaders. So lange deer ClassLoader einer bestimmten Klasse aktiv ist werden Änderungen ignoriert da die Klasse im RAM gehalten wird.
Was man noch als work-around versuchen könnte wäre eine Wraper-Klasse die die eigentliche Hauptklasse über einen URLClassLoader läd und nach abarbeitung wieder entläd *Java7 : URLClassLoader.close()* ... aber ob das so auch mit Tomcat funktioniert weis ich nicht.
 
Hallo,

erst mal danke für die zahlreiche Resonanz!

Leider hat keiner der Tipps geholfen.

Mein aktueller ClassLoader sieht wie folgt aus

Java:
	URLClassLoader classLoader = null;
	public Class<?> getCompiledClass() throws ClassNotFoundException, MalformedURLException
	{
		URL url = new URL("file://" + file.getAbsolutePath());
		classLoader = new URLClassLoader(new URL[]{url}, getClass().getClassLoader() );
		return classLoader.loadClass(file.getName().replace(".java", ""));
	}

	public void close() throws IOException
	{
		classLoader.close();
		classLoader = null;
	}

Ich verwende also schon den URLClassLoader.

Der Tomcat ist auch so konfiguriert, wie oben vorgeschlagen, nur ebenfalls ohne Erfolg.

Mit OSGi habe ich noch nicht gearbeitet, es wirkt anfangs allerdings exterm oversized für diese Problemstellung.
 
Zurück