L'exécution d'une application Java dans un processus séparé
Pouvez une application Java à être chargé dans un processus séparé à l'aide de son nom, par opposition à son emplacement, de manière indépendante de la plateforme?
Je sais que vous pouvez exécuter un programme via ...
Process process = Runtime.getRuntime().exec( COMMAND );
... le problème principal de cette méthode est que ces appels sont ensuite plate-forme spécifique.
Idéalement, j'aimerais envelopper d'une méthode dans quelque chose d'aussi simple que...
EXECUTE.application( CLASS_TO_BE_EXECUTED );
... et passe dans le nom complet d'une classe d'application comme CLASS_TO_BE_EXECUTED
.
- Donc, si je reçois de vous droit, vous avez plusieurs classes avec main() méthodes et vous souhaitez vous lancer dans des processus distincts?
- Que diriez-vous si vous exec("java.exe", CLASS_TO_BE_EXECUTED.classe.getName()) ?
- comment prendre une entrée d'un utilisateur de la classe java exécute comme un processus qui a commencé par un programme java, en utilisant quelque chose comme fr.readLine()
- Je suis avec l'OP, ce serait bien si on pouvait contourner l'ensemble de l'interface CLI. Quelqu'un devrait vraiment venir avec une classe wrapper pour faire cela, alors que les développeurs peuvent se concentrer sur la logique métier.
Vous devez vous connecter pour publier un commentaire.
Deux conseils:
System.getProperty("java.home") + "/bin/java"
vous donne un chemin d'accès à l'exécutable java.((URLClassLoader) Thread.currentThread().getContextClassLoader()).getURL()
vous aide à reconstruire le classpath de l'application en cours.Alors votre
EXECUTE.application
est juste (pseudo-code):Process.exec(javaExecutable, "-classpath", urls.join(":"), CLASS_TO_BE_EXECUTED)
C'est une synthèse de quelques autres réponses qui ont été fournies. Les propriétés système Java fournir suffisamment d'informations à venir avec le chemin d'accès à la commande java et le chemin de classe dans ce qui, je pense, est une plate-forme indépendante.
Vous devez exécuter cette méthode comme suit:
J'ai pensé qu'il était logique de passer à la classe réelle plutôt que la représentation de Chaîne de nom depuis la classe doit être dans le classpath de toute façon pour que cela fonctionne.
redirectOutput(...)
etredirectError(...)
sur le processus générateur (avantstart()
) si vous voulez commencer une sorte de serveur, sinon il risque de se bloquer et vous risquez de ne pas être en mesure de communiquer avec elle. Je ne sais pas pourquoi mais...String className = klass.getName();
au lieu deString className = klass.getCanonicalName();
de traiter correctement les classes imbriquées.Expansion sur @stepancheg réponse le code ressemblerait donc (sous la forme d'un test).
Cela peut-être trop pour vous, mais Projet Akuma fait ce que vous voulez et plus encore.
Je l'ai trouvé via cette entrée à kohsuke nous (un de Soleil de la roche commencer programmeurs) fabuleusement blog utiles.
Avez-vous découvrez la ProcessBuilder API? Il est disponible depuis 1.5
http://java.sun.com/javase/6/docs/api/java/lang/ProcessBuilder.html
Avez-vous vraiment besoin de les lancer en mode natif? Pourriez-vous appeler leur "principal" des méthodes directement? La seule chose de spécial au sujet principal, c'est que la VM lanceur appelle, rien ne vous empêche de l'appel principal de vous-même.
Que TofuBeer avait à dire: Êtes-vous sûr que vous avez vraiment besoin de la fourche à la fourchette dans un autre JVM? La JVM a vraiment un bon support pour la simultanéité de ces jours, de sorte que vous pouvez obtenir beaucoup de fonctionnalités pour relativement pas cher par tourner un nouveau Thread ou deux (qui peut ou ne peut pas exiger d'appeler Foo#main(String[])). Découvrez java.util.concurrente pour plus d'infos.
Si vous décidez de fourche, vous définissez vous-même pour un peu de complexité lié à la découverte de ressources nécessaires. C'est, si votre application est en train de changer fréquemment et dépend d'un tas de fichiers jar, vous aurez besoin de garder une trace de tous afin qu'ils puissent être transmis à la variable classpath arg. En outre, une telle approche nécessite de déduire à la fois l'emplacement de la (actuellement en cours d'exécution) de la JVM (qui peut ne pas être exacte) et l'emplacement de l'actuel chemin de classe (ce qui est encore moins susceptible d'être précis, selon le moyen, que le frai Thread a été invoquée - jar, jnlp, a explosé .les classes dir, certains conteneurs, etc.).
D'autre part, un lien statique #principales méthodes a ses pièges. statique des modificateurs ont une fâcheuse tendance à s'infiltrer dans le code des autres et sont généralement mal vu par la conception de l'esprit des gens.
Un problème qui se produit lorsque vous exécutez à partir d'un IHM java est qu'il fonctionne dans le fond.
Si vous ne pouvez pas voir l'invite de commande à tous.
Pour contourner ce problème, vous devez exécuter le java.exe à travers "cmd.exe" ET "démarrer".
Je ne sais pas pourquoi, mais si vous mettez "cmd /c start" en face il montre l'invite de commande en tant qu'il s'exécute.
Cependant, le problème avec "start", c'est que si il y a un espace dans le chemin d'accès de l'application
(dont le chemin d'accès à la java exe ont généralement que c'est dans
C:\Program Files\Java\jre6\bin\java.exe ou similaire),
puis commencer à juste échoue avec "impossible de trouver c:\Program"
Si vous avez de mettre des guillemets autour de C:\Program Files\Java\jre6\bin\java.exe
Maintenant commencer à se plaint de paramètres que vous passez à java.exe:
"Le système ne peut pas trouver le fichier -cp."
Échapper à l'espace dans "Program Files" avec une barre oblique inverse ne fonctionne pas.
L'idée est donc de ne pas utiliser l'espace.
Générer un fichier temporaire avec l'extension bat puis placez votre commande avec les espaces dans les il y
et exécuter la chauve-souris.
Toutefois, l'exécution d'une chauve-souris par le biais de démarrer, ne quittez pas quand c'est fait,
donc vous devez mettre "exit" à la fin du fichier de commandes.
Cela semble encore dégoûtant.
Donc, à la recherche de solutions, j'ai trouvé que l'utilisation de la citation de l'espace citation dans l'espace de "Program Files" fonctionne réellement avec start.
Dans l'EXÉCUTION de la classe au-dessus de changer le générateur de chaîne ajoute: