Bir Java programında başka bir jar çalıştırma


115

A.jar, B.jar olarak adlandırılan birkaç basit java uygulaması yazmıştım.

Şimdi bir GUI java programı yazmak istiyorum, böylece kullanıcı A.jar'ı çalıştırmak için A düğmesine ve B.jar'ı çalıştırmak için B düğmesine basabilir.

Ayrıca GUI programımda çalışma zamanı işlem detayını çıkarmak istiyorum.

Herhangi bir öneri?


31
Bunun neden reddedildiğinden emin değilim. Ona varsayımlarının neden yanlış olabileceğini açıklayın, ancak soruyu olumsuz oylamayın.
William Brendel

-1 temel Java terminolojisi doğru kullanılmıyor ve soru çok belirsiz ve ikinci tahmin için çok şey bırakıyor. Sorunuzu daha fazla ayrıntıyla yeniden ifade etmeyi düşünün veya önce Java sınıf yolu ve diğer temel bilgileri okuyun.
topchef

21
@Grigory: Gördün mü, hemen oy kullanmak yerine ilk etapta sorman gereken buydu. Daha fazla bilgi istemeden olumsuz oy kullanmanın bir faydası yok ...
William Brendel

4
@William, düğmeye senden birkaç saniye sonra bastığım için özür dilerim. Sonraki yorumla red oylama hakkımı saklı tutuyorum. Temel hazırlık yapılmadan sorulan soruları görmek ve / veya sorunu anlamak ya da sunmak için çaba sarf etmek sinir bozucu. Oy vermek benim için bir restoranda bahşiş gibi: Hizmet kalitesine bağlı olarak standart% 12'den fazla veya az veriyorsun. Öyleyse burada aynı fikirde olmayalım.
topchef

1
@topchef Buna 11 yıl geç kaldım ama siz "Temel hazırlık yapılmadan sorulan soruları görmek sinir bozucu ..." diyorsunuz. O zaman düzeltmeye yardım et. Neden olumsuz oy verdiğinizi açıklayın . Aksi takdirde soruna hiç yardımcı olmazsınız.
tylerr147

Yanıtlar:


63

Doğru anladıysam, kavanozları java GUI uygulamanızın içinden ayrı bir işlemde çalıştırmak istiyorsunuz.

Bunu yapmak için şunları kullanabilirsiniz:

// Run a java app in a separate system process
Process proc = Runtime.getRuntime().exec("java -jar A.jar");
// Then retreive the process output
InputStream in = proc.getInputStream();
InputStream err = proc.getErrorStream();

Sürecin çıktısını tamponlamak her zaman iyi bir uygulamadır.


21
Bu çözüm taşınabilir mi?
Pacerier

3
Teşekkürler. "Dir" parametresi dahil olmak üzere 3 parametre ile exec () func denedim ve çalışmıyor. Sadece bir tane ile, sadece 3 dosya .jar'ı aynı yere koymamız gerekiyor
Duc Tran

RuntimeO java uygulamasının nesnesini nasıl elde edeceğinizi biliyor musunuz ?
stommestack

ProcessBuilder kullanarak daha taşınabilir bir sürüm kullanabilir miyiz?
Anand Rockzz

"Java" programı çalıştırılamıyor: CreateProcess error = 2, Sistem belirtilen dosyayı bulamıyor. Bu hatayı alıyorum.
Gentleman

27

.jar çalıştırılabilir değildir. Sınıfları örnekleyin veya herhangi bir statik yöntemi çağırın.

DÜZENLE: Bir JAR oluştururken Ana Sınıf girişi ekleyin.

> p.mf (p.mf içeriği)

Ana Sınıf: pk.Test

>Test.java

package pk;
public class Test{
  public static void main(String []args){
    System.out.println("Hello from Test");
  }
}

Process sınıfını ve yöntemlerini kullanın,

public class Exec
{
   public static void main(String []args) throws Exception
    {
        Process ps=Runtime.getRuntime().exec(new String[]{"java","-jar","A.jar"});
        ps.waitFor();
        java.io.InputStream is=ps.getInputStream();
        byte b[]=new byte[is.available()];
        is.read(b,0,b.length);
        System.out.println(new String(b));
    }
}

1
Bence fikir, bir jar'e erişim verildiğinde, sınıfları buradan yüklemek için sınıf yoluna nasıl eklersiniz?
Jherico

1
Not: Yalnızca
YOLUNUZDA

@AVD: A.jar dosyası nerede tutulmalı?
logan

1
@logan - Bir programı yüklediğiniz bir dizinde.
adatapost

Bu yaklaşım yeni bir JVM süreci mi yaratacak yoksa mevcut olanı mı kullanacak?
RahulDeep Attri

17

Bu yardımcı olur umarım:

public class JarExecutor {

private BufferedReader error;
private BufferedReader op;
private int exitVal;

public void executeJar(String jarFilePath, List<String> args) throws JarExecutorException {
    // Create run arguments for the

    final List<String> actualArgs = new ArrayList<String>();
    actualArgs.add(0, "java");
    actualArgs.add(1, "-jar");
    actualArgs.add(2, jarFilePath);
    actualArgs.addAll(args);
    try {
        final Runtime re = Runtime.getRuntime();
        //final Process command = re.exec(cmdString, args.toArray(new String[0]));
        final Process command = re.exec(actualArgs.toArray(new String[0]));
        this.error = new BufferedReader(new InputStreamReader(command.getErrorStream()));
        this.op = new BufferedReader(new InputStreamReader(command.getInputStream()));
        // Wait for the application to Finish
        command.waitFor();
        this.exitVal = command.exitValue();
        if (this.exitVal != 0) {
            throw new IOException("Failed to execure jar, " + this.getExecutionLog());
        }

    } catch (final IOException | InterruptedException e) {
        throw new JarExecutorException(e);
    }
}

public String getExecutionLog() {
    String error = "";
    String line;
    try {
        while((line = this.error.readLine()) != null) {
            error = error + "\n" + line;
        }
    } catch (final IOException e) {
    }
    String output = "";
    try {
        while((line = this.op.readLine()) != null) {
            output = output + "\n" + line;
        }
    } catch (final IOException e) {
    }
    try {
        this.error.close();
        this.op.close();
    } catch (final IOException e) {
    }
    return "exitVal: " + this.exitVal + ", error: " + error + ", output: " + output;
}
}

0

Kavanoz sınıf yolunuzdaysa ve Ana sınıfını biliyorsanız, sadece ana sınıfı çağırabilirsiniz. Örnek olarak DITA-OT kullanarak:

import org.dita.dost.invoker.CommandLineInvoker;
....
CommandLineInvoker.main('-f', 'html5', '-i', 'samples/sequence.ditamap', '-o', 'test')

Bunun, alt kavanozun bellek alanını ve kavanozunuzla bir sınıf yolunu paylaşmasına neden olabilecek tüm parazit potansiyeline sahip olacağını unutmayın. Bu maddelerin kirlenmesini istemiyorsanız, yukarıda belirtildiği gibi başka seçenekleriniz de vardır - yani:

  • içindeki kavanoz ile yeni bir ClassLoader oluşturun. Bu daha güvenlidir; Uzaylı kavanozlardan yararlanacağınız bilgisiyle bir şeyler tasarlarsanız, en azından yeni kavanozun bilgisini temel bir sınıf yükleyiciye ayırabilirsiniz. Eklenti sistemimiz için mağazamda yaptığımız şey bu; ana uygulama bir ClassLoader fabrikası, API'nin bir kopyası ve gerçek uygulamanın bir ClassLoader oluşturması gereken ilk eklenti olduğu bilgisine sahip küçük bir kabuktur. Eklentiler, birbirine sıkıştırılmış bir çift kavanozdur - arayüz ve uygulama -. ClassLoader'lar tüm arabirimleri paylaşırken, her ClassLoader yalnızca kendi uygulamasına ilişkin bilgiye sahiptir. Yığın biraz karmaşık, ancak tüm testleri geçiyor ve harika çalışıyor.
  • kullanım Runtime.getRuntime.exec(...)(kavanozu tamamen izole eder, ancak normal "uygulamayı bulma", "dizelerinizden doğru şekilde kaçma", "platforma özgü WTF" ve "OMG Sistem Konuları" çalışan sistem komutlarının tuzaklarına sahiptir.

0

Aşağıdakiler, programın bağımsız olarak çalışması durumunda, jar dosyasını bir toplu iş dosyasıyla başlatarak çalışır:

public static void startExtJarProgram(){
        String extJar = Paths.get("C:\\absolute\\path\\to\\batchfile.bat").toString();
        ProcessBuilder processBuilder = new ProcessBuilder(extJar);
        processBuilder.redirectError(new File(Paths.get("C:\\path\\to\\JavaProcessOutput\\extJar_out_put.txt").toString()));
        processBuilder.redirectInput();
        try {
           final Process process = processBuilder.start();
            try {
                final int exitStatus = process.waitFor();
                if(exitStatus==0){
                    System.out.println("External Jar Started Successfully.");
                    System.exit(0); //or whatever suits 
                }else{
                    System.out.println("There was an error starting external Jar. Perhaps path issues. Use exit code "+exitStatus+" for details.");
                    System.out.println("Check also C:\\path\\to\\JavaProcessOutput\\extJar_out_put.txt file for additional details.");
                    System.exit(1);//whatever
                }
            } catch (InterruptedException ex) {
                System.out.println("InterruptedException: "+ex.getMessage());
            }
        } catch (IOException ex) {
            System.out.println("IOException. Faild to start process. Reason: "+ex.getMessage());
        }
        System.out.println("Process Terminated.");
        System.exit(0);
    }

Batchfile.bat dosyasında şunu söyleyebiliriz:

@echo off
start /min C:\path\to\jarprogram.jar

-3

Java 1.6 iseniz, aşağıdakiler de yapılabilir:

import javax.tools.JavaCompiler; 
import javax.tools.ToolProvider; 

public class CompilerExample {

    public static void main(String[] args) {
        String fileToCompile = "/Users/rupas/VolatileExample.java";

        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

        int compilationResult = compiler.run(null, null, null, fileToCompile);

        if (compilationResult == 0) {
            System.out.println("Compilation is successful");
        } else {
            System.out.println("Compilation Failed");
        }
    }
}

4
Bunun OP'nin sorusunu yanıtladığını sanmıyorum
Sri Harsha Chilakapati
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.