Вызов java из командного файла - как разделить параметры JVM и основного метода?

1

У меня есть пакетный файл Windows для запуска моего приложения Java, поэтому это выглядит так:

RunJavaPgm.bat

java -classpath lib\* com.blah.MyClass %*

Таким образом, это работает отлично, я могу передать любое количество параметров моему основному методу, делая что-то вроде

RunJavaPgm Param1 Param2

Теперь проблема, с которой я столкнулся, заключается в том, что мне нужно определить некоторые системные свойства, но если я попытаюсь сделать что-то вроде

RunJavaPgm Param1 Param2 -DMyProperty=MyValue

то это не сработает - передача этого значения -D в мой основной метод. Помещение "вокруг" не имеет значения. Причина в том, что если вы просто наберете "java" в командной строке, он скажет вам, каков должен быть синтаксис:

java [-options] class [args]

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

Большое спасибо!

Связанный - командный файл для запуска файла jar с параметрами

  • 1
    извините, но я не понимаю вашей проблемы. Почему вы не указали параметры JVM перед параметром основного класса?
  • 1
    Потому что он запускается из командного файла. Я не знаю, когда пишу командный файл, какие параметры JVM может захотеть указать конечный пользователь, выполняющий это. Для пакетного файла, что обозначение% * означает только все передаваемые в него параметры, он не знает разницы между параметрами JVM и основного метода.
Показать ещё 2 комментария
Теги:
batch-file
parameter-passing

2 ответа

1
Лучший ответ

попробуй это:

@echo off

setlocal EnableDelayedExpansion

set "jvm_args="
set "main_args="
set flag=0

for %%a in (%*) do (

    set arg=%%~a


    if !flag! EQU 0 if "!arg:~0,1!" NEQ "-" (
        set "main_args= !main_args! %%a"
        set flag=2
    )

    if "!arg:~0,1!" EQU "-" (
        set "jvm_args=!jvm_args! !arg!"
        set flag=1
    )

    if !flag! EQU 1 if "!arg:~0,1!" NEQ "-"  (
        set "jvm_args=!jvm_args!=!arg!"
        set flag=0
    )

)

::remove echo to run the java
echo java %jvm_args% com.blah.MyClass %main_args%

Он проверяет, я аргумент начинается с - и помещает его (и следующие один, как = является разделитель для партии), чтобы Jvm аргументов, а остальные аргументы Java. Это не идеальное решение (и не тяжело протестировано), но может сделать то, что вы хотите.

EDIT: попытка обработки котируемых параметров jvm:

@echo off

setlocal EnableDelayedExpansion

set "jvm_args="
set "main_args="
set flag=0

for %%a in (%*) do (

    set "arg=%%~a"

    echo #!arg:~0,1!#

    if !flag! EQU 0 if "!arg:~0,1!" NEQ "-" (
        set "main_args= !main_args! %%a"
        set flag=2
    )

    if "!arg:~0,1!" EQU "-" (
        set "jvm_args=!jvm_args! !arg!"
        set flag=1
        echo !arg!|find "=" >nul 2>&1 && set flag=0

    )

    if !flag! EQU 1 if "!arg:~0,1!" NEQ "-"  (
        set "jvm_args=!jvm_args!=!arg!"
        set flag=0
    )

)

::remove echo to run the java
echo java %jvm_args% com.blah.MyClass %main_args%
  • 0
    Это невероятно, спасибо большое! Как вы говорите, обработка = это проблема. Поскольку ваш код RunJavaPgm -Dx=y Param1 он будет обрабатывать RunJavaPgm -Dx=y Param1 но не RunJavaPgm "-Dx=y" Param1 поскольку флаг затем считает Param1 значением после параметра JVM. Кажется невозможным обрабатывать и -Dx = y, и "-Dx = y" одновременно, поскольку first = исчезает до того, как пакетный файл сможет его увидеть. Поэтому я просто скажу пользователям, что они должны помещать -D параметры в двойные кавычки, это не проблема, и делает скрипт немного проще, так как в нем нет значений флага, о которых нужно беспокоиться. Итак, большое спасибо!
  • 0
    @nigelg Я думаю, что можно обрабатывать приведенный случай с немного большими усилиями. Если мне удастся, я добавлю его в ответ ...
Показать ещё 1 комментарий
1

... может ли кто-нибудь подумать о каких-нибудь умных альтернативах?

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

Но я бы подумал, что пользователь, который может понять -D, также может быть обучен помещать их в нужное место.


(Вы можете подумать о том, чтобы получить main метод поиска "неулокальных" -D параметров и добавления соответствующих свойств системы. Однако во многих случаях это произойдет слишком поздно. Некоторые свойства будут использоваться до того, как ваш main метод будет выполняться Это не решение, в общем.)

  • 0
    Да, я думал об этом ... это приложение Spring, поэтому в первых нескольких строках, прежде чем он запустит контекст Spring, основной метод может проанализировать все аргументы, чтобы увидеть, начинаются ли они с -D и использовать System. setProperty, чтобы установить их, но это просто неприятный способ сделать это :(
  • 0
    И да, пользователи знают о том, как правильно использовать опцию -D, и знают, где ее разместить, но я пытаюсь избавить их от необходимости печатать "java -classpath lib / * -DSomeProperty = SomeValue com. very.long.package.name.VeryLongClassName Param1 Param2 ", поэтому вместо этого они могут просто набрать" RunJavaPgm -DSomeProperty = SomeValue Param1 Param2 "
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню