Есть ли библиотека Java для преобразования командного файла в параметры основного метода - PullRequest
0 голосов
/ 07 июля 2010

Я работаю над (Codehaus) Maven 2 Mojo. К сожалению, вызванная логика имеет несовместимую лицензию, и мне приходится разбирать отдельный процесс (как это делается для плагина Cobertura maven).

Форкировать себя легко, используя org.codehaus.plexus.util.cli.Commandline и друзей. Разветвитель должен иметь возможность устанавливать тысячи аргументов для основного метода вызываемого процесса (который является сторонним кодом, который будет использоваться). В Windows Commandline может быть только 8 КБ. Использование прямого форка (Runtime.getRuntime().exec) поддерживает только общий размер аргумента до 32 тыс., Что по-прежнему недостаточно.

Так что мне нужна оболочка для стороннего инструмента, который читает строки из текстового файла (командный файл) и вызывает целевой класс вместе с ними. Это легко закодировать, и я мог бы сделать это сам , но у меня есть еще один из моих классов, вызывающий сторонний код, который не может быть в самой кодовой базе Mojo из-за проблем с лицензией (как указано выше ). Лучше всего будет библиотека, которую я могу использовать в качестве зависимости, которая сделает это для меня.

Знаете ли вы, какую библиотеку / класс я мог бы использовать (без настройки другого проекта, который должен быть выпущен, бла-бла-бла).

1 Ответ

0 голосов
/ 07 сентября 2010

Очевидно (как никто не ответил) нет такой вещи, чтобы использовать из коробки. Поэтому я должен был придумать один сам.

  • Для создания файла командной строки я скопировал net.sourceforge.cobertura.util.CommandLineBuilder ( source ), который имеет методы addArg(), saveArgs() и getCommandLineFile().
  • Для выполнения командной строки с этим файлом я использовал org.codehaus.plexus.util.cli.Commandline, как это обычно используется в MOJO.

    Commandline cl = new Commandline();
    cl.setExecutable( COMMAND_CLASS );
    cl.createArg().setValue( TASK_CLASS );
    
    CommandLineBuilder builder = new CommandLineBuilder( "macker" );
    for ( Iterator/*<String>*/it = options.iterator(); it.hasNext(); ) {
       builder.addArg( (String) it.next() );
    }
    builder.saveArgs();
    String commandsFile =  builder.getCommandLineFile();
    cl.createArg().setValue( commandsFile );
    
    StringStreamConsumer stdout = new StringStreamConsumer();
    StringStreamConsumer stderr = new StringStreamConsumer();
    int exitCode = CommandLineUtils.executeCommandLine( cl, stdout, stderr );
    
  • «Другая» сторона должна распаковать аргументы. Для этого я написал небольшой класс CommandLineFile ( source ).

    String className = args[0];
    Class clazz = Class.forName( className );
    Method main = clazz.getMethod( "main", new Class[] { String[].class } );
    
    List/*<String>*/lines = new ArrayList/*<String>*/();
    Reader in = new InputStreamReader( new FileInputStream( args[1] ), "UTF-8" );
    try {
        lines = IOUtils.readLines( in );
    } finally {
        in.close();
    }
    
    main.invoke( null, new Object[] { lines.toArray( new String[lines.size()] ) } );
    
  • Единственная проблема, которая осталась, это необходимость в CommandLineFile быть на пути к классам. Но это другая история ...

Все используемые классы являются общими и с открытым исходным кодом. Таким образом, они могут быть использованы для любой проблемы разветвления.

...