How to write from Java to the Windows Event Log? - java

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.

Related

how to execute a command with it's native gui using process builder

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

How to Write Syslog on linux using java

I want to write Syslog using in java program on linux system. I don't want to use any library.
Assuming that "no libraries" means no 3rd-party libraries.
One approach would be to code your own implementation of the Syslog Protocol; see RFC 5424. You could do this in pure Java.
CORRECTION - Actually, not pure Java. The syslog protocol (typically) uses UNIX Domain sockets, and there is no built-in Java library functionality for this. You would need to resort to native code, or a 3rd-party library; see UNIX Domain Socket in Java
A second approach would be to write a JNI wrapper for the syslog(3) C library methods. Under the hood, this library opens a datagram socket on a local port and (presumably) implements the Syslog Protocol. So you don't achieve much by doing it this way.
(Note that the C libraries are part of (at least) any GNU/Linux system, so this doesn't count as using a 3rd-party library. At least, not in my books ...)
I used the system logger with a Runtime like this:
public static void log(String TextToLog){
Runtime r = Runtime.getRuntime();
try{
r.exec("logger \"Applicationname " + TextToLog + "\"");
}
catch(IOException e){e.printStackTrace();}
}
If the distribution uses systemd, you can use the following.
String logMessage = "some message";
String logIdentifier = "java-app";
String command = "echo " + logMessage + " | systemd-cat -t " + logIdentifier;
new ProcessBuilder(new String[] {"bash","-c","eval " + command}).start();
To watch in GNU/Linux's terminal, watch for your logIdentifier:
watch -n0.5 sudo journalctl -t "java-app"

How can I override java -Xmx option in application?

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.

runtime.getruntime().exec("wscript.exe macro.vbs") doesn't work on windows server 2008

I have a web application on a server deployed in tomcat 7 on windows server 2008.
This web application is running these lines of code:
String path = req.getServletContext().getRealPath("/") + "WEB-INF/vbs/macro.vbs";
int range = 1;
int range1 = 1;
int status = Runtime.getRuntime().exec("wscript.exe" + path + "" + range + "" + range1 + "" + temp.getAbsolutePath() + "" + temp1.getAbsolutePath()).waitFor();
On the local computer, the execution succeeds perfectly. Deployed to the server, instead, the application stops on the exec runtime and the browser waits for a response.
What could be the cause?
I know this is a very old question but still worth replying in case that someone with a similar problem.
Executing external programs using Runtime.getRuntime().exec() is perfectly fine but in this case there were no spaces in between the parameters, meaning that the command to be executed was wscript.exe/WEB-INF/vbs/macro.vbs11... instead of wscript.exe /WEB-INF/vbs/macro.vbs 1 1 ....
The Runtime.getRuntime().exec(String) method automatically splits the string by spaces so another potential problem is that arguments in the command string might need to be wrapped in quotes to prevent them from being parsed incorrectly by the application.
The correct code would have been:
int status = Runtime.getRuntime().exec(
"wscript.exe \"" + path + "\" " + range + " " + range1 + "\" " +
temp.getAbsolutePath() + "\" " + temp1.getAbsolutePath() + "\"")
.waitFor();
The fact that it worked in some servers but not in others could very well be related to the paths where these files were deployed having or not having spaces in them (e.g. "C:\Program Files").

Issue starting cmd.exe twice in a row

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

Categories