Starting a Java application at startup - java

I have a Java application.
The application has a setting that decides whether or not the application starts at startup.
Currently, I have it this by placing/removing a shortcut in the StartUp items folder.
However, I am wondering if there is a better way to handle this behaviour.
EDIT
Yes, it's Windows. Sorry for not clearing that before.
The application has an UI where the user may trigger actions, also the application runs a few tasks in the background periodically while running.
#Peter, how could I change the registry with code from within the application? Is that approach compatible with all versions of Windows?

Below is a small example snippet of how it can be done from inside your application
static final String REG_ADD_CMD = "cmd /c reg add \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\" /v \"{0}\" /d \"{1}\" /t REG_EXPAND_SZ";
private void exec(String[] args) throws Exception
{
if (args.length != 2)
throw new IllegalArgumentException("\n\nUsage: java SetEnv {key} {value}\n\n");
String key = args[0];
String value = args[1];
String cmdLine = MessageFormat.format(REG_ADD_CMD, new Object[] { key, value });
Runtime.getRuntime().exec(cmdLine);
}
I'm pretty sure this will work with all versions of Windows since they all use the same Startup\Run registry entry.
Hope that helps! :)
Credit

On Windows I have used open source Java Service Wrapper to make our application as window service which you can setup automatic at startup.
What you need to do is to download latest wrapper.exe and create wrapper.config file put all the configuration like Main class any VM arument other parameters in defined standards and create a window service by this exe

Use the Registry to start your program at the startup and then it will be shown in the list provided by msconfig commnd through Run.
Use this registry path
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

Related

Why doesn't cd command work using Java JSch?

I'm just learning Java and Jsch, and I can get it to run other commands but not cd. The error code returned by the SSHManager sendCommand function is not null, but some unreadable string that is different every time (maybe that means it is null not that familiar with inner workings of Java).
Any idea why not? Similar question here JSch - Why doesn't CD work? but unanswered.
I won't copy and paste the whole SSHManager class here - useful answer with complete code here that I'm trying to follow. Run a command over SSH with JSch
Sample code below:
import SSH.SSHManager;
public class src
{
int ERROR = 0;
public static void main(String[] args)
{
String username = "debian";
String password = "temppwd";
String ipadd = "192.168.7.2";
SSHManager ssh = new SSHManager(username, password, ipadd, "");
ssh.connect();
String out = "";
//this doesn't work, printing output as bytes to show how weird it is
out = ssh.sendCommand("cd Desktop");
System.out.println(out.getBytes());
//some other test commands
out = ssh.sendCommand("mkdir test");
System.out.println(out);
out = ssh.sendCommand("ls");
System.out.println(out);
ssh.sendCommand("logout");
}
}
Output from the Eclipse Console (bin and Desktop are already there in root directory):
[B#b065c63
bin
Desktop
test
Each command executed over SSH "exec" channel (what is behind SSHManager.sendCommand) is executed in its own shell. So the commands have no effect on each other.
To execute multiple commands in the same shell, just use an appropriate syntax of your server shell. Most *nix shells use semicolon or double-ampersand (with a different semantics).
In your case, the double-ampersand would be more appropriate.
cd Desktop && mkdir test && ls
See also Multiple commands using JSch.
Though, if your want to read commands output, you will have problem distinguishing, where output of one commands ends and output of the following commands starts. Let alone if you wanted to check command exit code.
Then it's better to execute each command in its own "exec" channel in a way that does not require a context. In your case that means using full paths:
mkdir Desktop/test
ls Desktop
See also How to perform multiple operations with JSch.
Also as you were going to use file manipulation only, you actually should not execute shell commands at all. Use the standard SSH API for file manipulation, the SFTP.
The question has kind of an answer, in the comments. Every command in sendCommand uses it's own 'pipe', so it disconnects and starts over in each one.
A quick solution would be to send multiple commands in one one sendCommand, such as:
out = ssh.sendCommand("cd Desktop; mkdir test; ls; logout");
But the correct way is to use a session, such as https://stackoverflow.com/a/9269234/290036
I answered a similar question Using java jcabi SSH client (or other) to execute several commands in shell
My open-source API Maverick Synergy has a high-level API to execute multiple commands within a shell. Its currently designed for and works well with bash-type shells.

How can I check if my application can create a symbolic link?

From my Java application I want to create a symbolic link. However my application can run in different circumstances, not all of those permit the creation of symbolic links. I have the following situations:
Linux - can always make a symlink
Windows - can make a symlink if you are running the application as an administrator.
To create the symlink I use Files.createSymbolicLink(). This throws an IOException under Windows when it doesn't have permission. To be precise the exception is:
java.nio.file.FileSystemException: test\link: A required privilege is not held by the client.
I want to be able to tell if I have this permission from the application (Java 7 or newer) before trying to make the symlink. How can I do this?
This code bellow will work only for Windows and comes with Java.
public static boolean AdminAuth() {
String groups[] = (new com.sun.security.auth.module.NTSystem()).getGroupIDs();
for (String group : groups) {
if (group.equals("S-1-5-32-544"))
return true;
}
return false;
}
The SID S-1-5-32-544 is the id of the Administrator group in the Windows operating system.
You can also take a look at this documentation regarding Application Manifest for Windows.

java, execute exe from WAR in java code

In my war, I have file exe in WEB-INF\classes\
How can I execute this file in Java code (How can I specify path to this file) ?
command = " ? ";
Process x = p.exec(command);
Te following approach could work:
1) Prepare full path of your executable:
ServletContext context = getContext();
String fullPath = context.getRealPath("/WEB-INF/classes/executable");
2) Execute like you would normally do it:
String[] cmd = { fullPath /*[...] arguments */};
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
This is a simplified example; you may also want to read more about ProcessBuilder.
This is bad idea. Imagine simply fact that your .war packege should run on almost any server (".war is platform independend") and your .exe file is compiled just for one architecture.
Better should be execute your .exe as external program just for separate platform independent and platform dependent part. Then in java you can test operating system and on this basis run desired externel programm.
Read this link with similar question.
The best way to do find a file's real location inside a web app is to use the ServletContext.getRealPath (see http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html#getRealPath(java.lang.String))
You can access that object from the session...

Java Command Process Chain Generator

I have build a Java command line application which consists of several moduls. So when you start the application via the command line, you have to pass one parameter and its options like this for example:
cmd-> java -jar application -startModul1 option1 folderPath
OR
cmd-> java -jar application -startModul5 500 folderPath 1222
Currently I have to start each modul by starting the application and passing the requested parameter+options. For now thats finde but later, when I have lets say 20 modules, I want to generate a proccess chain with several moduls started one after the other.
For example at the end I could start both modules from the example above with just one command.
cmd-> java -jar application -startAllModules option1 500 folderPath 1222
Is there a framework, where I can generate such a proccess chain with existing command line modules? This should not be NOTHING programatically because I want to have some sort of xml-file or whatever, where I just configure a process chain and where I can select the modules and its parameters that should be run with one command.
Have you thought of turning your program into an interpreter?
I think that parsing your command line, understanding what simple commands it must execute (from the xml you want to use) and launching them is enough.
How to launch them?
Process p = Runtime.exec(String[] cmdarray)
where cmdarray will have each of the words of the command:
{"java", "-jar", "application", "-startModul1", "option1", "folderPath"}
and
p.waitFor();
if you want this thread to wait until launched command ends.
Update: non concurrent
The later was in case you want to run several independent processes in parallel. One for command you need.
In case you only need to execute them one after the another there's a more simply way. When the main realizes it must execute multi modules, it calls itself with the appropiate arguments.
public static void main(String[] args) throws Exception {
// parse params
if (it's a multi module command line) {
for (each module you have to execute) {
main(new String[] {"-startModule1", ..., ...}); // call myself with different args
}
}
else {
// execute what you've been asked for
}
}

Start Windows Service with Java

I am trying to start a windows service in java using this
public static void main(String[] args) throws IOException {
String startCom = "net start";
String startProc = "\"C:/Program Files/Common Files/Apple/Mobile Device Support/bin/AppleMobileDeviceService.exe\"";
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(startCom + startProc);
System.out.println("Starting It");
}
It runs with no exceptions but does not start the service. What Am I doing wrong?
Try to figure out what the registered service name is, and use that instead of the full executable. For example:
net start "Adobe Acrobat Update Service"
You can find out the service name by by running net start on a command window (which prints a list of all registered services) or by finding the service in the Services control panel by clicking the Start button, typing services.msc, and pressing Enter. If the service name is cryptic, you can right-click the service in the Services control panel and click Properties to confirm the executable for that service.
You probably need to execute the command with escalated privileges. You can either do this by disabling UAC (not recommended), by launching javaw.exe with elevated privileges when you start your program, or by using a utility like Elevate.exe to execute any privileged commands.
If you're having trouble getting Runtime.exec to do your bidding, try using ProcessBuilder instead.
Lastly, it's a good idea to always read the contents of STDOUT and STDERR (from Process.getOutputStream() and Process.getErrorStream()). They might contain diagnostic information; but even more importantly, if the buffers fill up while the Process is still outputting to them, the Process will hang.
Try this code:
public static void main(String[] args) throws IOException {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("cmd start /c C:/Program Files/Common Files/Apple/Mobile Device Support/bin/AppleMobileDeviceService.exe");
System.out.println("Starting It");
It looks like your main() exits, so your service will die. In this case, you need to install the service using
sc create "servicename" binpath="path",
and then start it with
sc start "servicename.
That is, a service .exe still needs to be installed as a Windows service.

Categories

Resources