I am running a script in PowerShell, that calls a java application, but this application fails due to Out.of.memory.error: Heap Size. I created environment variable, but it didn't work. From the dump txt file I found out, that the java_command_line contains -Xmx512m option:
IBM_JAVA_COMMAND_LINE=C:\Program Files\ (x86)\IBM\Java70\jre\bin\java.exe -Xmx512m -classpath C:\Users\IBM_ADMIN\Desktop\Nessus_Scripts\nessusconverter.exe;...
From what I learned, this overrides my created environment variable and lowers the max heap size for this application. I guess it is coded in the called application. My problem is, that I don't know the author of the application and need it for my work. I am also time-limited, so some deep debugging or improving of this app is off limits.
Is there a way to override the option set in the application (without interfering in the app)?
I have Windows 7 and IBM SDK Java version 7.0.
Script calling the java app:
Function CallNessusConverter ( [Array]$input_files
[String]$output_filename, [String]$exceptions_filename,
[String]$hosts_filename, [String]$output_directory ) {
[String]$output_XML_file = $output_directory + "\" + $output_filename + ".xml"
[String]$output_Issue_file = $output_directory + "\" + $output_filename + "-Issues.csv"
[String]$output_Missed_file = $output_directory + "\" + $output_filename + "-NotScanned.csv"
[String]$input_XML_files = ""
foreach ($file in $input_files){
$input_XML_files += " " + $file
}
Write-Host "**** Calling nessusconverter ****"
[string]$CLI_nessusconverter = ".\nessusconverter -inputXMLfiles $input_files -exceptions $exceptions_filename -hosts $hosts_filename -outputXML $output_XML_file -outputIssue $output_Issue_file -rmunknown -outputMissed $output_Missed_file"
iex $CLI_nessusconverter
...
CallNessusConverter $input_files $output_filename $exceptions_filename $hosts_filename $output_directory`
As some kind of workaround, if there no other solution, you could try to replace the java.exe with a file that calls the real java with the desired parameters... Of course this is not a good idea if other applications use this java.exe as well.
Related
if(os.contains("windows"))
{
File bat = new File(System.getenv("APPDATA") + "/SelfCommandPrompt", appId + "-run.bat");
bat.getParentFile().mkdirs();
List<String> list = new ArrayList(1);
list.add("#echo off");
list.add("start" + " \"" + appName + "\" " + command);
IOUtils.saveFileLines(list, bat, true);
ProcessBuilder pb = new ProcessBuilder(bat.getAbsolutePath());
//inherit IO and main directory
pb.directory(getProgramDir());
//fire the batch file
pb.start();
System.exit(0);
}
So I dynamically create a .bat file and I want to run the process but, NOT IN THE BACKGROUND. Java forces the process to happen in the background how do I make it so it's not in the background? I am not looking to get the output stream from the .bat file I only want to execute it with the native gui it's intended to use on double click. Everywhere I look on these forums it only tells me how to do it in the background and get the outputstream? Why isn't there a boolean for this in the process builder? For my program specifically right now I want to reboot my java program with command prompt terminal on double click. I have the command generation working I tested the .bat file but, java again forces it to happen in the background.
Another use for doing a process not in the background. A java launcher for a game which executes a program with the gui not in the background which I may also need in the future.
Also the bat files output which is dynamically generated based off of the enviorment
java -Dfile.encoding=Cp1252 -cp C:\Users\jredfox\Documents\MDK\md5-spreadsheet\filededuper\bin;C:\Users\jredfox\Documents\MDK\md5-spreadsheet\filededuper\libs\apache-codecs.jar jredfox.selfcmd.SelfCommandPrompt true jredfox.filededuper.Main
edit I figured out a command for windows but, only windows. I need commands for mac
Runtime.getRuntime().exec("cmd /c start" + " \"" + appName + "\" " + command);
Figured it out.
basically get the terminal string on linux you need to make an api for it
save any shell scripts you need in the appdata
make an api to get the app data folder
create your custom command
return if conditions are not met like the System.console != null for my thing yours will be different.
execute command in new terminal window therefore the new native terminal using os commands.
All the code is found here.
https://github.com/jredfox/OpenTerminal
motivation:
I have a test that needs to write a short temp file (must be < 107 characters).
Currently the test is using
Files.createTempFile(null,".sock");
issue
which when running
I'm trying to figure out the java.io.tmp value when running java test using bazel. The different options I have is:
Setting $TEST_TMPDIR (or without)
Using "local"=True (or without)
Here is the result:
# local=True + TEST_TMPDIR=/btmp:
/btmp/_bazel_ors/719f891d5db9fd5e73ade25b0c847fd1/execroot/__main__/_tmp/8be6e61521c57d3cfc8585efa880e1ac/1638063256753562848.sock
# local=False + TEST_TMPDIR=/btmp:
/btmp/_bazel_ors/719f891d5db9fd5e73ade25b0c847fd1/bazel-sandbox/5561433121200492142/execroot/__main__/_tmp/8be6e61521c57d3cfc8585efa880e1ac/4867903879018296623.sock
# local=True , no TEST_TMPDIR:
/private/var/tmp/_bazel_ors/719f891d5db9fd5e73ade25b0c847fd1/execroot/__main__/_tmp/8be6e61521c57d3cfc8585efa880e1ac/984443110479498941.sock
# local=False , no TEST_TMPDIR:
/private/var/tmp/_bazel_ors/719f891d5db9fd5e73ade25b0c847fd1/bazel-sandbox/6199384508952843116/execroot/__main__/_tmp/8be6e61521c57d3cfc8585efa880e1ac/4588114364301475150.sock
Seems like the shortest temp prefix I can get is:
/private/var/tmp/_bazel_ors/719f891d5db9fd5e73ade25b0c847fd1/execroot/__main__/_tmp/
which is 85 char long (way too long for my needs).
How can I safely play with this configuration and make it a lot shorter?
note:
My env is mac osx sierra and I'm running bazel 0.5.1
Solvable by adding this to the jvm_flags of the test target:
"jvm_flags" = ["-Djava.io.tmpdir=/tmp"],
But note that it would make the test less hermetic
You can also tell bazel where it should store its outputs --output_base=/tmp/foo.
I am trying to automate some processes that were build in ancient times, for the sake of avoiding repetitive actions. It is required that the processes are started with one batch and stopped with another (this can not be changed btw).
So i made a commandline tool to do this (and many other repetitive stuff) and I have modelled a command that starts the 'startbatch' and a command that start the 'stopbatch'. Both commands work fine separatly (as I tested them separatly) but there seems to be a problem when i want execute them one after another (in the correct order ofcourse). I get the following error in new cmd.exe window:
The process cannot access the file because it is being used by another process.
the code that i am using to start the batches looks like this:
public void startBatchInDev(String company){
String startBatchFolder = locations.getLocationFor("startbatch");
try{
Runtime runtime = Runtime.getRuntime();
runtime.exec("cmd.exe /C cd \"" + startBatchFolder + "\" & start cmd.exe /k \"" + BATCHSTART + company.toLowerCase()+ "-dev" + BATCH_SUFFIX + "\"");
}
catch(IOException ioe){
ioe.printStackTrace();
}
}
public void stopBatchInDev(String company){
String startBatchFolder = locations.getLocationFor("startbatch");
try{
Runtime runtime = Runtime.getRuntime();
runtime.exec("cmd.exe /C cd \"" + startBatchFolder + "\" & start cmd.exe /k \"" + BATCHSTOP + company.toLowerCase()+ "-dev" + BATCH_SUFFIX + "\"");
}
catch(IOException ioe){
ioe.printStackTrace();
}
}
The names of the batchfiles are concatenated, but they are OK once the application is running.
The error message is quite clear, some file is locked and I can't access it because of it. Some googling confirms my suspicion, but I can't seem to find a solution for this. The hits in google are all about obvious uses of files, like an obvious shared resource. But in my case, i am not working on the same batch file. The stop and start batch are two different files. So I am actually starting to think that it might be the cmd.exe file that is being locked by windows...
So this question is actually two questions:
- what is the exact cause of the described problem?
- how do i programmatically fix this (if possible)?
thanks in advance!
So, basically, bat is not so great :-(
I was able to repro this from java, but I also found that this script:
#echo off
echo STOP
echo STOP >> E:\tmp\java\logfile.txt
C:\cygwin\bin\sleep.exe 1
echo STOP1 >> E:\tmp\java\logfile.txt
C:\cygwin\bin\sleep.exe 1
echo STOP2 >> E:\tmp\java\logfile.txt
When run twice like this:
start test.bat && start test.bat
Will fail with one or more messages like:
The process cannot access the file because it is being used by another process.
The reason is that " >> " redirection opens the file for Read/Write access but only FILE_SHARE_READ sharing. If two different programs attempt to open the file this way, one of them fails.
So, you cannot have two different batch files running at the same time and logging to the same file
I have this piece of code that compiles a class called tspClassName, when I compile using this code:
Process compileProc = null;
try {
compileProc = Runtime.getRuntime().exec("javac -classpath ."
+ File.separator + "src" + File.separator
+ File.separator + "generated." + tspClassName + ".java -d ." + File.separator + "bin");
// catch exception
if (compileProc.exitValue() != 0)
{
System.out.println("Compile exit status: "
+ compileProc.exitValue());
System.err.println("Compile error:" +
compileProc.getErrorStream());
it outputs this:
"Compile exit status: 2
Compile error:java.io.FileInputStream#17182c1"
The class tspClassName.java compiles without errors otherwise, so I am guessing it has to do with the path,and in my eclipse project, the tspClassName.java resides in package homework4.generated inside src, is there something wrong with the path that I use in the code?
thanks
Your Java code runs a command that looks something like this:
javac -classpath ./src//generated.ClassName.java -d ./bin
I don't think that's what you want. I think you need to change your Java code so it maybe generates something like:
javac -classpath . src/generated/ClassName.java -d ./bin
^
Note the space after the classpath (".").
You can use the javax.tools.JavaCompiler or JCI that wrap this functionality.
I recommend doing something like this:
String command = String.format(
"javac -classpath . src%1$sgenerated%1$s%2$s.java -d .%1$sbin",
File.separator,
tspClassName
);
LOG("Executing " + command);
//... exec(command) etc
... where LOG is whatever your logging framework uses to log the command to be executed. This will help debugging immensely, since it was pointed out that the command you built is ill-constructed.
Alternately you can also build the string using replace
String command =
"javac -classpath . src/generated/ClassName.java -d ./bin"
.replace("/", File.separator)
.replace("ClassName", tspClassName);
This is perhaps more readable.
On draining Process streams
OP's comment suggests that waitFor() never returns. This is likely caused by compilation errors/warnings in javac process.
From the API:
Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.
You need to continuously drain the Process.getOutputStream() et.al.
See also
Java Puzzlers, Puzzle 82: Beer Blast
Related questions
Draining standard error in Java
I think the proper way to do this kind of work is programatically using the javax.tools API, not an external process:
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler()
Reference:
ToolProvider.getSystemJavaCompiler()
The problem could be with the file location instead of using single value parameter for exec()
try 3 parameter method which has the command, environment and location as parameters which helps us to move to the specified location and execute the command
check 6 and 8 methods for reference
http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html
Process compile = Runtime.getRuntime().exec("javac "+fname,null,new File(dir));
firstly you should use apache exec library if you want to use processes like that. Apache exec library makes things very easy.
Secondly you should print your std output and std error streams of your process which you are executing. Without them its no way to know whats being executed and what's it doing.
Thirdly, try to print the full cmd line which the process is executing. Copy that cmd line and try to run it manually. Most of the time you would find your issues this way.
And finally if your aim is just to compile a class / generate or modify a class file at runtime give this a good read and try. It has examples too. You could also try code generation / class manipulation libraries like BCEL, JavaAssist etc.
Best of luck.
How can I write from Java to the Windows Event Log?
Log4J is a Java-based logging utility. The class NTEventLogAppender can be used to "append to the NT event log system". See the documentation here:
http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/nt/NTEventLogAppender.html
Edit: There is a newer version, Log4j 2 "that provides significant improvements over its predecessor."
You can use JNA to write to the Event Log directly without the need of any native DLLs. See Advapi32 and Advapi32Util classes for various event log methods (ships since JNA 3.2.8).
If you're using Log4j, consider Log4jna instead of NTEventLogAppender.
You can also use the eventcreate command on Windows XP Pro and above.
String command = "eventcreate "
+ " /l APPLICATION"
+ " /so \"" + applicationObjectName + "\""
+ " /t " + lvl
+ " /id " + id
+ " /d \"" + description + "\"";
Runtime.getRuntime().exec(command);
For XP home and lower, you could create a vbs application that writes using the wscript.shell.eventcreate method. However you sacrifice the ability to specify source.
Example:
http://www.ozzu.com/mswindows-forum/posting-event-log-with-batch-files-t76791.html
Back in 2001 JavaWorld published an article on how to write messages to the Windows NT Event Log. Or, you can take a look at the Log4j NTEventLogAppender class.