Methodenaufruf aus der Kommandozeile

Status
Nicht offen für weitere Antworten.

guni

Bekanntes Mitglied
Hallo, ich habe eine Klasse, die
a) von anderen Klassen aufgerufen wird
b) Methoden besitzt, die aus der Kommandozeile aufgerufen werden sollen

wie kann ich meine Klasse entwerfen, dass ich in der Kommandozeile eine Art direkten Aufruf machen kann; also sowas wie:

java domain.packagename.class.method1(param1, param2)

... wie gesagt soll method1 aber auch von anderen Klassen aufgerufen werden können.
ich könnte natürlich hergehen und eine eigene Klasse schreiben, die nur eine void main enthält und dort dann sowas wie
Java:
Class c = Class.forName(args[0])
if (args[1].equals("method1") {
   c.method1(args[2],args[3],...);
...
schreiben, aber das is irgendwie etwas unschön, oder?!
was habe ich da noch für Möglichkeiten?!

liebe grüße, guni
 

guni

Bekanntes Mitglied
hmm ... jaaa .... bin grad auf das command-Pattern gestoßen.
Könnte meinen Zweck erfüllen.
Kann ich in einer Jar-Datei mehrere Klassen mit einer main-Methode haben?!
lg
 

mvitz

Top Contributor
ginge auch z.B. so:

Java:
package reflection;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Methods {

    public static void main(String[] args) throws ClassNotFoundException,
            SecurityException, NoSuchMethodException, IllegalArgumentException,
            IllegalAccessException, InvocationTargetException,
            InstantiationException {
        // Testdaten
        String className = "reflection.Methods";
        String methodName = "test";
        String parameterValue = "test";
        // Klasse und Methode holen
        Class<?> clazz = Class.forName(className);
        Method method = getMethod(clazz, methodName);
        // instanz erstellen
        Object object = clazz.newInstance();
        method.invoke(object, parameterValue);
    }

    // funktioniert nur richtig, wenn die Methode nicht überladen ist!!!
    private static Method getMethod(Class<?> theClass, String theMethodName)
            throws NoSuchMethodException {
        Method[] methods = theClass.getMethods();
        for (Method method : methods) {
            if (method.getName().equals(theMethodName)) {
                return method;
            }
        }
        throw new NoSuchMethodException("Couldn't found method: "
                + theMethodName + " for class: " + theClass.getCanonicalName());
    }

    public void test(String test) {
        System.out.println(test);
    }
}
 

guni

Bekanntes Mitglied
@habi55:

warum schreibst du eine getMethod-Methode?????
ich könnte doch genausogut clazz.getMethod sagen, oder?!
den rest hab ich im Grunde genommen verstanden.
aber was kann ich bei überladenen Methoden tun?!

und noch was: die Invoke-Methode braucht ja ein Objekt.
In deinem Code holst du dir dieses Objekt mit clazz.newInstance.
wie aber holt man sich das Objekt einer Klasse, die Singleton ist?!

lg, guni
 

mvitz

Top Contributor
Da bin ich jetzt auch stellenweise überfragt :D

Wieso ich da eine eigene Methode draus gemacht habe ist recht einfach.

Bei der Methode getMethod() die man auf einem Class Object aufrufen kann musst du als parameter folgendes mitgeben:
- Name der Methode
- 1-x Klassen die der Klasse der erwarteten Paramter entsprehcen müssen. In meinem Beispiel ginge also auch:
Java:
Method method = clazz.getMethod(methodName, String.class);
Dann müsstest du für deinen Fall jedoch diese Klassen der Parameter auch noch aus der Usereingabe extrahieren.

Singleton ginge dann z.B. so:

Java:
Class<?> clazz = Class.forName("test.Klasse");
Method method = clazz.getMethod("getInstance", new Object[] { null });
Object object = method.invoke(new Object[] { null }, new Object[] { null});
Method method2 = clazz.getMethod("test", String.class);
method2.invoke(object, "Test");
 

guni

Bekanntes Mitglied
Bei der Methode getMethod() die man auf einem Class Object aufrufen kann musst du als parameter folgendes mitgeben:
- Name der Methode
- 1-x Klassen die der Klasse der erwarteten Paramter entsprechen müssen.
da hast du allerdings recht.
das könnte mühsam werden.
ich werde also wie du eine getMethod schreiben ;-)
mal schaun wie weit ich mit meinem Code komme *gg*
 

guni

Bekanntes Mitglied
... leider funktioniert das Ganze nicht - ich versteh nicht wieso ...
hier mein Code:
Java:
String classname = "com.guni.connections.Database";
String methodname = "dbmsSignal";

String param1 = "TESTCONNECTION";
String param2 = "Hallo Welt";

Class c = Class.forName(classname);
Object instance;

try { 
	instance = getMethod(c, "getInstance");
} catch (NoSuchMethodException e) {
	instance = c.newInstance();
}

Method m = getMethod(c,methodname);
m.invoke(instance,new Object[]{param1, param2});
... ich bekomm folgenden Fehler:
Java:
java.lang.IllegalArgumentException: object is not an instance of declaring class
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:324)
... woran kann das liegen?
 

Schandro

Top Contributor
Imho musst du per c.newInstance eine neue Instanz der Klasse erschaffen um nicht-statische Methoden aufzurufen
 

guni

Bekanntes Mitglied
@schandro: das mach ich doch, oder?!
in meinem try-catch-block sag ich:
wenn die klasse eine getInstance-Methode hat (d.h. sie ist ein Singleton), dann erzeuge die Instanz über eine getInstance-Methode; sollte keine getInstance-Methode existieren, gehen wir davon aus, dass es sich bei der Klasse nicht um einen Singleton handelt und versuchen sie mit newInstance zu erzeugen.
Wo also liegt der Fehler?!
 

guni

Bekanntes Mitglied
@schandro:
... oder wolltest du damit sagen, dass die Reflection-API nur ein erzeugen über ein class.newInstance unterstützt?!
getInstance ist doch statisch! die muss ich doch auch so aufrufen können -> ???
 

Schandro

Top Contributor
Du musst auch noch die Methode getInstance aufrufen und dessen return Wert als instance benutzen...
€dit: Bis jetzt speicherst du die Methode an sich in instance.
 

guni

Bekanntes Mitglied
ja ... nur kann ich keine Methode aufrufen, solang ich keine instanz hab, weil die invoke-methode ein object der gegebenen klasse fordert!
order hab ich da irgendwas übersehn?!

lg, guni
 

guni

Bekanntes Mitglied
... ok. hab gerade gesehen, dass dieses objekt bei statischen methoden null sein darf ;-)
 

guni

Bekanntes Mitglied
hmm ... noch hab ich das Problem aber nicht ganz gelöst.
meine Konstruktoren, die ich aufrufen möchte, übernehmen teilweise Argumente ...

kann ich in
Java:
instance = c.newInstance();
irgendwie sagen, dass ich bestimmte Argumente übergeben möchte?!

danke, guni
 

guni

Bekanntes Mitglied
hallo,

habe meinen Aufruf über Kommandozeile jetzt weitgehend gelöst.
Mein Problem ist jetzt, dass ich meinen Runner in eine JAR-Datei gepackt hab und darüber hinaus noch ein paar andere jar Dateien hab.

wenn ich jetzt ein java -jar runner.jar <klasse_aus_einer_anderen_jar> methode argument

mache, bekomme ich einen class not found fehler.
woran kann das liegen?!

(die jar-Datei binde ich im classpath natürlich ein)

mfg, guni
 
S

Spacerat

Gast
mit der Option "-jar" wird die Klasse mit der Main-Methode ausschliesslich in diesem Archiv "gesucht" (... wird nicht gesucht, sondern durch das folgende Argument bestimmt!). Wenn "runner.jar" im Klassenpfad liegt, kann mit "java -jar anderes.jar packet.Clazz method argument" die Methode "method" mit den Argument "argument" der Klasse "Clazz" aufgerufen werden. "Clazz" muss dazu selber eine Main-Methode besitzen, in welcher "Clazz" dann auch instanziert werden kann.
 

guni

Bekanntes Mitglied
hmm.
das verstehe ich jetzt nicht ganz.

meine runner.jar HAT eine main-Methode.
dieser Main Methode übergeb ich eine Klasse und deren Methode mit Parametern.
Das Problem scheint zu sein, dass die Klasse, die ich als String an die Main Methode übergebe in einer JAR-Datei liegt!
 

mvitz

Top Contributor
hallo,

habe meinen Aufruf über Kommandozeile jetzt weitgehend gelöst.
Mein Problem ist jetzt, dass ich meinen Runner in eine JAR-Datei gepackt hab und darüber hinaus noch ein paar andere jar Dateien hab.

wenn ich jetzt ein java -jar runner.jar <klasse_aus_einer_anderen_jar> methode argument

mache, bekomme ich einen class not found fehler.
woran kann das liegen?!

(die jar-Datei binde ich im classpath natürlich ein)

mfg, guni

Wie bindest du denn die Klasse im classpath ein?

Versuche es doch mal so:
Code:
java -cp andere.jar -jar runner.jar <klasse_aus_einer_anderen_jar> methode argument
 
S

Spacerat

Gast
hmm.
das verstehe ich jetzt nicht ganz.

meine runner.jar HAT eine main-Methode.
dieser Main Methode übergeb ich eine Klasse und deren Methode mit Parametern.
Das Problem scheint zu sein, dass die Klasse, die ich als String an die Main Methode übergebe in einer JAR-Datei liegt!
Ok... dann eben anders: Deine "runner.jar" besitzt keine Klasse aus "andere.jar". Daher kommt die ClassNotFoundException. Hinzukommt, das möglicherweise auch keine Manifest-Datei in "runner.jar existiert, die auf die Klasse mit der "main"-Methode zeigt. Die Klasse hinter "java -jar runner.jar" zeigt auf jeden Fall auf die Klasse mit der "main"-Methode die man innerhalb des angegebenen Archives ausführen will. Die Klassenbezeichnung müsste man also "tarnen". Z.B. kann man statt Punkten Unterstriche verwenden. In der "main"-Methode in der "runner.jar" müssen diese dann wieder durch Punkte ersetzt werden.
 

guni

Bekanntes Mitglied
tut mir leid - das versteh ich nicht.
ich versuch's mal mit ein bisschen code:

meine Runner.class sieht ca. so aus:
Java:
public class Runner {
   public static void main(String[] args) {

      String classname = args[0];
      String methodname = args[1];
      Object[] objects = new Object[args.length-2];
      Class[] paramClasses = new Class[args.length-2];
      for (int i=2; i<args.length; 
         objects[i-2] = args[i];
         paramClasses[i-2] = String.class;
      }

      Class c = Class.forName(classname);
      Method m = c.getMethod(methodname,paramClasses);
      m.invoke(methodname,objects)
   }
}

so. so circa sieht sie aus. sie liegt in der runner.jar.

dann hab ich noch eine andere Klasse; sagen wir einfach mal Hallo.
sie sieht dann meinetwegen so aus:

Java:
package domain.server;

public class Hallo {
   public void hallo(String name) {
      System.out.println("Hallo "+name);
   }
}

die Hallo.class liegt jetzt meinetwegen in einer hallo.jar

mein Aufruf sieht dann so aus:

java -classpath hallo.jar;. -jar runner.jar domain.server.Hallo hallo Max

... wie müsste ich das denn umbauen, dass es funktioniert?

mfg, guni

ps.: ich hab die klassen jetzt mal einfach so im posting-fenster vom java-forum runtergeschrieben. kann sein, dass ich mich irgendwo bös vertippt hab ;-)
 
S

Spacerat

Gast
Der Klassenname kommt nicht als Argumet in "runner.class" an, weil... siehe oben.
Zeile 4 der "runner.class" wie folgt abändern:[highlight=java]String classname = args[0].replace("_", ".");[/highlight]Bei der Kommandozeile die Punkte des Klassennamens in Unterstriche umwandeln. Wermutstropfen: Die Klassen die verwendet werden sollen, dürfen keinen Unterstrich im Paket- und/oder Klassennamen haben.
@Edit: man kann allerdings auch zwei Klassen in der Eingabeaufforderung eingeben. Die Erste ist dann immer die "Runner.class".
 
Zuletzt bearbeitet von einem Moderator:

guni

Bekanntes Mitglied
hmm ... ich habe jetzt ehrlich gesagt einfach mal den Weg bevorzugt, die fehlenden JAR's in meine MANIFEST.MF zu schreiben.
das sieht jetzt so aus:

Manifest-Version: 1.0
Main-Class: domain.host.package.Class
Class-Path: general.jar, classes12.jar

mein Problem ist: sobald ich mehr als eine Klasse in meinem Class-Path anführ geht es nicht mehr. Hab es auch schon mit Strichpunkt zwischen den Klassen probiert. Woran kann das liegen?!

mfg, guni
 
S

Spacerat

Gast
Mennooooo... Dann eben noch mal anders.
1. Der Code für Runner:[highlight=java]import java.lang.reflect.Method;

public final class Runner
{
public static void main(String[] args)
throws Throwable
{
Class c = Class.forName(args[0]);
Object o = c.newInstance();
String[] arguments = new String[args.length - 2];
System.arraycopy(args, 2, arguments, 0, arguments.length);
Method i = null;
for(Method m : c.getMethods()) {
if(args[1].equals(m.getName())) {
i = m;
break;
}
}
if(i == null) throw new NoSuchMethodException(args[1]);
o = i.invoke(o, new Object[] {arguments});
System.out.println(o);
}
}[/highlight]2. Der Code mit der auszuführenden Methode (z.B.):[highlight=java]package execmethoddemo;

public final class ExecuteMethodDemo
{
public String myMethod(String ... args)
{
for(String arg : args) System.out.println(arg);
return args.length + " Arguments";
}
}[/highlight]3. Die Kommandozeile:
Code:
WINDOWS:
java -cp runner.jar;ExecuteMethodDemo.jar;. Runner execmethoddemo.ExecuteMethodDemo myMethod firstarg
LINUX:
java -cp runner.jar:ExecuteMethodDemo.jar:. Runner execmethoddemo.ExecuteMethodDemo myMethod firstarg
4. Ausgabe:
Code:
firstarg
1 Arguments
Noch 'ne kleine Anmerkung: Runner kann in der Manifestdatei als Startklasse aufgeführt sein, so viel es will. Fakt ist, das der 1. Klassenname hinter dem Java-Kommando diese Vorgabe "überlagert" (bzw. "überschreibt").
 
Zuletzt bearbeitet von einem Moderator:
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
C Methodenaufruf mit geänderten Argumenten Java Basics - Anfänger-Themen 10
S Methoden Methodenaufruf rekursiv zählen Java Basics - Anfänger-Themen 4
N methodenaufruf for each geht nicht Java Basics - Anfänger-Themen 2
K Methodenaufruf /-ausgabe Java Basics - Anfänger-Themen 5
O Methodenaufruf Java Basics - Anfänger-Themen 5
V Neue Ausgabe von toString nach Methodenaufruf Java Basics - Anfänger-Themen 9
Queiser Methodenaufruf Java Basics - Anfänger-Themen 2
J Vererbung und Methodenaufruf Java Basics - Anfänger-Themen 11
I Java Methodenaufruf Java Basics - Anfänger-Themen 9
A OOP Methodenaufruf in einer anderen Klasse Java Basics - Anfänger-Themen 2
G Methoden Probleme beim Methodenaufruf Java Basics - Anfänger-Themen 2
M Methodenaufruf über SQL UPDATE Java Basics - Anfänger-Themen 8
M Methodenaufruf in der Main Datei funzt nicht Java Basics - Anfänger-Themen 13
BadBat Klassen instanz als variable + methodenaufruf Java Basics - Anfänger-Themen 4
M Methodenaufruf in Methode Java Basics - Anfänger-Themen 6
M Objekt Name für MethodenAufruf nachträglich zuweisen? Java Basics - Anfänger-Themen 2
J if() mit Methodenaufruf kombiniert (Pixelerkennung) Java Basics - Anfänger-Themen 3
A Probleme beim Methodenaufruf von Object[] ! Java Basics - Anfänger-Themen 12
A Probleme beim Methodenaufruf von char[] ! Java Basics - Anfänger-Themen 10
T Rekursiver Methodenaufruf funktioniert nicht Java Basics - Anfänger-Themen 7
D Methoden g.setColor funktioniert nicht bei Methodenaufruf in anderer Klasse Java Basics - Anfänger-Themen 1
M Methoden Methodenaufruf allgemein Java Basics - Anfänger-Themen 3
H Ist Math.Random() eine Methode oder ein Methodenaufruf (Klausurfrage) Java Basics - Anfänger-Themen 4
O Methodenaufruf Java Basics - Anfänger-Themen 6
F Methodenaufruf Java Basics - Anfänger-Themen 1
F Erste Schritte Label Text vor Methodenaufruf setzen Java Basics - Anfänger-Themen 17
J Array mit Methodenaufruf Java Basics - Anfänger-Themen 2
S Problem bei Vererbung und Methodenaufruf Java Basics - Anfänger-Themen 3
OnDemand Methodenaufruf Java Basics - Anfänger-Themen 3
A Methoden Benutzerdefinierter Methodenaufruf Java Basics - Anfänger-Themen 4
O Methodenaufruf - Inhaltsveränderung Java Basics - Anfänger-Themen 23
G Methodenaufruf anderer Klasse Java Basics - Anfänger-Themen 18
L Einfacher Methodenaufruf vs. Objekt Java Basics - Anfänger-Themen 4
O Methodenaufruf im Konstruktor Java Basics - Anfänger-Themen 6
G was ist ein Methodenaufruf mit (){}? Java Basics - Anfänger-Themen 6
S Methoden Klassen Definition - Methodenaufruf Java Basics - Anfänger-Themen 7
K Methoden Methodenaufruf für BufferedWriter .. Java Basics - Anfänger-Themen 5
feardorcha Methodenaufruf Übergabe- und Rückgabewert Java Basics - Anfänger-Themen 5
W Methodenaufruf innerhalb einer Klasse - static vs. this Java Basics - Anfänger-Themen 3
A Problem bei Methodenaufruf Java Basics - Anfänger-Themen 6
B Parameterausführung bei Methodenaufruf Java Basics - Anfänger-Themen 8
A Methodenaufruf Java Basics - Anfänger-Themen 4
P Vererbung Methodenaufruf funktioniert aber Wertzuweisung von Variablen nicht Java Basics - Anfänger-Themen 9
S methodenaufruf Java Basics - Anfänger-Themen 8
G Erste Schritte Methodenaufruf, Variablen-Deklaration Java Basics - Anfänger-Themen 6
L Methodenaufruf in main() Java Basics - Anfänger-Themen 3
M Methodenaufruf in for-Schleife - nur 1 mal ausgegeben Java Basics - Anfänger-Themen 3
I Externer Methodenaufruf, Punkt-Notation Java Basics - Anfänger-Themen 11
I Methoden Rückverfolgung Methodenaufruf Java Basics - Anfänger-Themen 15
E Methoden Wie kann ich eine Methode so schreiben, dass Methodenaufruf polymorph erfolgen kann? Java Basics - Anfänger-Themen 8
M Methoden Methodenaufruf mit .class. Java Basics - Anfänger-Themen 2
J rekursiver Methodenaufruf Java Basics - Anfänger-Themen 12
K Klassen this-Referenz und Klassen/Methodenaufruf Syntax Java Basics - Anfänger-Themen 3
T Java mehrfacher Methodenaufruf Java Basics - Anfänger-Themen 15
L Methodenaufruf aus anderer Klasse Java Basics - Anfänger-Themen 5
B Quicksort --> Methodenaufruf Java Basics - Anfänger-Themen 10
O Methodenaufruf Java Basics - Anfänger-Themen 4
A nullPointerException bei Methodenaufruf Java Basics - Anfänger-Themen 16
J Vererbung, Methodenaufruf Java Basics - Anfänger-Themen 4
M Problem bei Methodenaufruf aus ActionListener Java Basics - Anfänger-Themen 5
N Methodenaufruf funtioniert nicht Java Basics - Anfänger-Themen 3
C Methodenaufruf mit Variablen die gesetzt werden Java Basics - Anfänger-Themen 10
Antoras mit ActionListener/Methodenaufruf Textfelder zeichnen Java Basics - Anfänger-Themen 4
G Dynamischer Methodenaufruf Java Basics - Anfänger-Themen 3
G Methodenaufruf über ein Objekt einer anderen Klasse Java Basics - Anfänger-Themen 7
H ungültige methodenaufruf Java Basics - Anfänger-Themen 16
G Methodenaufruf Java Basics - Anfänger-Themen 3
G Frage zu Oberklasse bei Methodenaufruf Java Basics - Anfänger-Themen 2
V Dynamischer Klassen bzw. Methodenaufruf Java Basics - Anfänger-Themen 6
V Wie und wieso geht dieser Methodenaufruf? Java Basics - Anfänger-Themen 2
S Methodenaufruf Java Basics - Anfänger-Themen 6
G Methodenaufruf in der for-Schleife mit Array Java Basics - Anfänger-Themen 7
L hsqldb Methodenaufruf Java Basics - Anfänger-Themen 10
K synchron und asynchroner Methodenaufruf Java Basics - Anfänger-Themen 17
R Fehler bei Methodenaufruf Java Basics - Anfänger-Themen 2
G Methodenaufruf Java Basics - Anfänger-Themen 3
T NullPointerException bei Methodenaufruf Java Basics - Anfänger-Themen 2
G Methodenaufruf Java Basics - Anfänger-Themen 10
K Klassenübergriefendes Methodenaufruf Problem Java Basics - Anfänger-Themen 6
S methodenaufruf. Java Basics - Anfänger-Themen 16
G methodenaufruf Java Basics - Anfänger-Themen 4
E Methodenaufruf mittels variable? kA Java Basics - Anfänger-Themen 5
G methodenaufruf Java Basics - Anfänger-Themen 3
G methodenaufruf Java Basics - Anfänger-Themen 5
W Überschreiben und Methodenaufruf Java Basics - Anfänger-Themen 3
L Methodenaufruf zwischen Klassen Java Basics - Anfänger-Themen 3
C Methodenaufruf mit throws IOException Java Basics - Anfänger-Themen 2
L Beim Java Programmstart, mehrere Parameter über die Kommandozeile übergeben Java Basics - Anfänger-Themen 9
P Variablen Optionaler Parameter auf der Kommandozeile Java Basics - Anfänger-Themen 12
C Classpath Compiler lässt sich nur bedingt von Kommandozeile aus starten Java Basics - Anfänger-Themen 17
U Was bedeutet $@ in der Linux Kommandozeile Java Basics - Anfänger-Themen 3
B Kommandozeile Übergangsmechanismus args Java Basics - Anfänger-Themen 5
T Input/Output Überschreibung von Kommandozeile Java Basics - Anfänger-Themen 3
T Variable in Windows Kommandozeile schreiben Java Basics - Anfänger-Themen 4
K Kommandozeile zählen Java Basics - Anfänger-Themen 5
H Text ausdrucken, den ich entweder direkt in die Kommandozeile schreibe, oder über input redirect übe Java Basics - Anfänger-Themen 2
D Java Programm auf Kommandozeile durchführen Java Basics - Anfänger-Themen 12
N Kommandozeile,Anfänge Java Basics - Anfänger-Themen 12
M Swing Klasse auch per Kommandozeile starten? Java Basics - Anfänger-Themen 2
Fab1 Argumente in der Kommandozeile eingeben Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben