How can I pass Java command line options in a separate file?
Asked Answered
B

4

7

Is there any way of launching Oracle's Java.exe and have it take its command line options from a text file on Windows?

What I'd like to be able to do is something like this:

java.exe -optionsFile=myOptionsFile.txt MyClass

where 'myOptionsFile.txt' contains a list of standard Java VM options such as "-classpath="my very long classpath" and "-Dthis=that" etc.

All of the options must be present when Java.exe is run as it is the target of a memory debugging tool called VMMap. VMMap allows you to launch a .exe and attach to it in order to debug native heap issues. In this case, I cannot generate the command line args at runtime or have another process launch java.exe for me.

Bobbette answered 29/8, 2017 at 15:16 Comment(15)
No but you can write a script that launches java for you, including your long options, which amounts to the same thing in most practical cases.Aluminium
Why can't you read the file first, and write the options when calling java?Fredette
All the Java args have to be there when it's launched in this case. I'm trying to launch the application inside a tool called VMMap, which can only launch applications with a 260 character command line. My application has a command line that's over 5,500 characters (which doesn't fit). I've updated the original post to include this information.Bobbette
Your question is an X/Y Problem. Tell us what problem you are trying to solve instead of asking for help with the solution, which does not appear to be the correct approach.Em
(1) If you mean VMMap from former-sysinternals-now-part-of-MS, it can handle a pre-existing process just fine, at least as of the 2014 version I have (2) If -classpath alone is (much of) the problem, use envvar CLASSPATH instead, or wildcards, or fat jar(s) (3) Otherwise, it may work to use envvar _JAVA_OPTIONS and/or JAVA_TOOL_OPTIONSSwagerty
@Swagerty Yes, it's the VMMap from SysInternals. There are effectively two ways you can debug a process with it. You can either directly attach to a running process, and it will show all the memory allocated to the process and let you look at string values held in the heap etc. The second method is to get VMMap to launch the process directly. In this mode, VMMap hooks the APIs for memory allocation and can show you memory leaks including callstacks. It's a much more detailed view of the process :) Good idea about using _JAVA_OPTIONS and/or CLASSPATH environment vars - will try those.Bobbette
@JarrodRoberson Thanks for the feedback, but this is not an X/Y Problem. My actual problem is that I can't debug my application with VMMap (one of many tools in my arsenal that I use regularly to debug native applications). As my application contains Java, C++ and C# code, it is a very useful tool. I know how VMMap works and what I can use it for. In this case, I need to use it to find a memory leak. But I don't need help finding the memory leak as I'm quite proficient at doing that on my own. What I don't know is how to launch Java.exe and provide command line parameters in a file.Bobbette
Did you try the solution I provided?Ithyphallic
@Ithyphallic Hi, yes I did try your suggestion and have left a comment with your answer.Bobbette
@MarkDouglas - the variations of solutions that are not what you are asking for and honestly better solutions points to the X/Y conclusion. You do not need to load from a text file you need to feed the same requirements to VMMap which does not predicate loading command line options from a text file as the solutions in the comments and answers prove out. You should edit your question to reword it without the request to do something that is impossible.Em
@JarrodRoberson The requirement is simple. I need to pass a very long list of command args to my application for it to run. This is over 5,500 characters in length. VMMap only allows you to specify 260 characters. One solution would have been to specify the command arguments in a file and have Java.exe read that file, but it sounds like this is not possible with the Oracle JVM. In this case the answer to my original question is 'it is not possible', which is an acceptable answer if true. I just needed to explore if it was possible and could have helped others who have similar requirements.Bobbette
@JarrodRoberson I'm not sure how you can call the other suggestions 'better solutions' as none of them allow me to pass command line arguments in a file to the JVM. You are trying to get me change my question into something that people (including myself) can already answer. My question is NOT 'how do I pass a very long list of arguments to Java.exe'.Bobbette
@MarkDouglas - the point is you do not have to pass command line args from a file into the JVM, you need to provide the same args to both programs. That is your actual problem. How to pass the same args to two programs when one of them do not allow you to read them from a file.?* The point is you do not have to make java read from a file, because that is not going to happen. If you do not edit your question do not expect any better answers that you have now. Just trying to help and provide some guidance on how to succeed on the site.Em
@JarrodRoberson This is getting silly. I know how to pass arguments on the command line. I am NOT attempting to pass the same arguments to 'both programs', only to Java.exe from VMMap. But even that is almost irrelevant. All I wanted to know is how (if possible) I can pass arguments in a file. The original question says exactly that, but you are assuming I'm trying to solve a different issue, which I am not. How would you suggest I reword my question if all I want to know is how, if possible, can I pass command line args in a file to Java.exe?Bobbette
@JarrodRoberson I know you are trying to help, and it is appreciated, but please understand that my original question is all that I want an answer to - nothing more, nothing less.Bobbette
A
3

Since Java 11 (maybe before), it's possible to pass an argument file

$ java @my-args.txt -jar the.jar

my-args.txt

-Xms1G
-Xmx30G
Avalon answered 12/6, 2023 at 14:29 Comment(0)
P
1

You could use xargs.

Given a file, arguments.in, with the following contents:

~/dev/code$ more arguments.in
-version

Invoked like so:

~/dev/code$ cat arguments.in | xargs $JAVA_HOME/bin/java

Produces this output (i.e. the same output as if you invoked java -version):

java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)

Note: this assumes you are either on a *nix OS or are using Cygwin (or a simulator emulator such as GOW).

Paramagnetism answered 29/8, 2017 at 15:24 Comment(4)
Sorry, I forgot to mention that this is on Windows. I've updated the original post.Bobbette
Cygwin and GOW are Windows compatible and can provide the xargs tool.Paramagnetism
Thanks glitch, but it sounds like xargs would be launching Java.exe which wouldn't work in VMMap. VMMap takes the path of the .exe to launch and attach to, and then allows you to monitor native memory allocations in that process only. If xargs then launched Java.exe, VMMap would be unable to monitor it.Bobbette
@MarkDouglas yes, agreed. Although xargs is a valid way of bridging arguments->process, your updated question makes clear that it won't meet your 'within VMMap' needs. Perhaps the question title could be updated to make clear the need to tweak the behaviour of a java process spawned by VMMap? Otherwise, you might get passers-by offering opinions on launching your own java process (which is a much simpler proposition).Paramagnetism
I
0

Simple way:-

yourclassName=JavaClassName
java `cat myOptionsFile.txt` $yourclassName

In windows, this should work fine.

set /p VAR=<myOptionsFile.txt
java.exe %VAR% yourclassName
Ithyphallic answered 29/8, 2017 at 15:36 Comment(1)
I don't think this can work because it's the command prompt (shell) that performs the expansion of environment variables into their actual values. When you run 'java.exe %VAR% yourClass' from a command prompt, the substitution of %VAR% is performed before java.exe is invoked. When trying this from within VMMap, the substitution will not take place because it's simply passing the raw text '%VAR%' to the process being invoked.Bobbette
M
0

Building on top of @nagendra547's answer,

java $( grep -vE '^[#;]' "$PWD/jvm.parameters" ) -jar whatever.jar

will also allow you to include comments in your parameters file.

Meave answered 9/10, 2023 at 17:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.