Выполнение JAVA-приложения в отдельном процессе

При этом используется lapply для применения функции к каждому элементу вашего вектора, затем связывается результат с исходным фреймом данных и добавляются имена столбцов.

# Given example
set.seed(1)
(tib <- tibble(num1 = sample(12), num2 = sample(12)))
addup <- function(x, y, z){x + y + z}
vec <- c(3,6,4)

# Add columns and bind to original data frame
foo <- cbind(tib, lapply(vec, function(x)addup(tib$num1, tib$num2, x)))

# Correct column names
colnames(foo)[(ncol(tib)+1):ncol(foo)] <- vec

# Print result
print(foo)

#    num1 num2  3  6  4
# 1     4    9 16 19 17
# 2     5    5 13 16 14
# 3     6    8 17 20 18
# 4     9   11 23 26 24
# 5     2    6 11 14 12
# 6     7    7 17 20 18
# 7    10    3 16 19 17
# 8    12    4 19 22 20
# 9     3   12 18 21 19
# 10    1    1  5  8  6
# 11   11    2 16 19 17
# 12    8   10 21 24 22
43
задан tshepang 14 April 2014 в 11:54
поделиться

8 ответов

Две подсказки:

System.getProperty("java.home") + "/bin/java" дает Вам путь к исполняемому файлу Java.

((URLClassLoader) Thread.currentThread().getContextClassLoader()).getURL() помогает Вам восстановить путь к классу текущего приложения.

Тогда Ваш EXECUTE.application, просто (псевдокодируйте):

Process.exec(javaExecutable, "-classpath", urls.join(":"), CLASS_TO_BE_EXECUTED)

42
ответ дан RamenChef 26 November 2019 в 22:30
поделиться

Необходимо ли действительно запустить их исходно? Вы могли просто назвать их "основные" методы непосредственно? Единственная специальная вещь об основном состоит в том, что средство запуска VM называет его, ничто не мешает Вам назвать основным самим.

3
ответ дан TofuBeer 26 November 2019 в 22:30
поделиться

Это - синтез некоторых из других ответов, которые были предоставлены. Системные свойства Java предоставляют достаточно информации для предложения пути к команде Java и пути к классу в том, что, я думаю, независимый от платформы путь.

public final class JavaProcess {

    private JavaProcess() {}        

    public static int exec(Class klass) throws IOException,
                                               InterruptedException {
        String javaHome = System.getProperty("java.home");
        String javaBin = javaHome +
                File.separator + "bin" +
                File.separator + "java";
        String classpath = System.getProperty("java.class.path");
        String className = klass.getName();

        ProcessBuilder builder = new ProcessBuilder(
                javaBin, "-cp", classpath, className);

        Process process = builder.inheritIO().start();
        process.waitFor();
        return process.exitValue();
    }

}

Вы выполнили бы этот метод как так:

int status = JavaProcess.exec(MyClass.class);

Я думал, что имело смысл передавать в фактическом классе, а не Строковом представлении имени, так как класс должен быть в пути к классу так или иначе, чтобы это работало.

67
ответ дан hallidave 26 November 2019 в 22:30
поделиться

Вы проверяли ProcessBuilder API? Это доступно с тех пор 1.5

http://java.sun.com/javase/6/docs/api/java/lang/ProcessBuilder.html

3
ответ дан lothar 26 November 2019 в 22:30
поделиться
public abstract class EXECUTE {

    private EXECUTE() { /* Procedural Abstract */ }

    public static Process application( final String CLASS_TO_BE_EXECUTED ) {

        final String EXEC_ARGUMENT 
        = new StringBuilder().
              append( java.lang.System.getProperty( "java.home" ) ).
              append( java.io.File.separator ).
              append( "bin" ).
              append( java.io.File.separator ).
              append( "java" ).
              append( " " ).
              append( new java.io.File( "." ).getAbsolutePath() ).
              append( java.io.File.separator ).
              append( CLASS_TO_BE_EXECUTED ).
              toString();

        try {       

            return Runtime.getRuntime().exec( EXEC_ARGUMENT );

        } catch ( final Exception EXCEPTION ) {     

            System.err.println( EXCEPTION.getStackTrace() );
        }

        return null;
    }
}
3
ответ дан 3 revs 26 November 2019 в 22:30
поделиться

Следование, что должен был заявить TofuBeer: действительно ли Вы уверены, что действительно необходимо разветвиться от другой JVM? JVM имеет действительно хорошую поддержку параллелизма в эти дни, таким образом, можно получить большую функциональность для относительно дешевого, просто отделив новый поток или два (который может или не может потребовать вызова в Foo#main (Строка [])). Проверьте java.util.concurrent для большего количества информации.

Если Вы решаете разветвиться, Вы собираетесь некоторое время сложности, связанной с нахождением необходимых ресурсов. Таким образом, если Ваше приложение изменится часто и будет зависеть от набора файлов банки, то необходимо будет отслеживать их всех так, чтобы они могли быть розданы к аргументу пути к классу. Кроме того, такой подход требует к вывести обоих местоположение (в настоящее время выполняющийся) JVM (который не может быть точным), и местоположение текущего пути к классу (который, еще менее вероятно, будет точен, в зависимости от способа, которым родительский поток был вызван - банка, jnlp, взорван .classes dir, некоторый контейнер, и т.д.).

С другой стороны, соединение в статические #main методы имеет свои ловушки также. статические модификаторы имеют противную тенденцию утечки в другой код и обычно осуждаются настроенными на дизайн людьми.

2
ответ дан jasonnerothin 26 November 2019 в 22:30
поделиться

Взгляните на GMP . Я нашел это в этой записи в потрясающе полезном блоге Kohsuke (одного из программистов Sun).

4
ответ дан StaxMan 26 November 2019 в 22:30
поделиться

Проблема, возникающая при запуске этого из графического пользовательского интерфейса Java, заключается в том, что он работает в фоновом режиме. Таким образом, вы вообще не можете видеть командную строку.

Чтобы обойти это, вы должны запустить java.exe через «cmd.exe» И «start». Я не знаю почему, но если вы поставите «cmd / c start» перед ним, он покажет командную строку при запуске.

Однако проблема с «start» состоит в том, что если в пути к приложению есть пробел (который обычно имеет путь к java exe, как и в C: \ Program Files \ Java \ jre6 \ bin \ java.exe или аналогичный), тогда запуск просто завершается неудачей с "не удается найти c: \ Program"

Поэтому вам нужно заключить в кавычки C: \ Program Files \ Java \ jre6 \ bin \ java.exe Теперь start жалуется на параметры, которые вы передаете в java.exe: «Система не может найти файл -cp.»

Экранирование пробела в «Program Files» с помощью обратной косой черты также не работает. Итак, идея состоит в том, чтобы не использовать пространство. Создайте временный файл с расширением bat, а затем поместите туда свою команду с пробелами и запустить биту. Однако запуск летучей мыши через start не завершается, когда завершается, поэтому вы должны поставить «exit» в конец командного файла.

Это все еще кажется неприятным.

Итак, ища альтернативы, я обнаружил, что использование кавычки в пространстве «Program Files» на самом деле работает с запуском.

В приведенном выше классе EXECUTE построитель строк добавляет в:

append( "cmd /C start \"Some title\" " ).
append( java.lang.System.getProperty( "java.home" ).replaceAll(" ", "\" \"") ).
append( java.io.File.separator ).
append( "bin" ).
append( java.io.File.separator ).
append( "java" ).
append( " " ).
append( new java.io.File( "." ).getAbsolutePath() ).
append( java.io.File.separator ).
append( CLASS_TO_BE_EXECUTED ).
1
ответ дан 26 November 2019 в 22:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: