Starting a Process starts another process which Starts a Java Process? - java

I've asked a question like this recently but it was solved (kind of)....
Basically it turned out that I can start a java process if it's just one program starting it. But that's not exactly what I need for my project.
Here is what I want it to do...
Project1.exe ---starts-> Project2.exe ---starts-> somejar.jar
Following the above my current project1 starts project2 by using the following,
process = new Process();
process.StartInfo.FileName = Path.Combine(storage, "project2.exe");
process.Start();
Then project2.exe starts the java application via cmd by using the following,
miner = new Process();
miner.StartInfo.FileName = "cmd.exe";
miner.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
miner.StartInfo.Arguments = "/K java -cp libs\\*;DiabloMiner.jar -Djava.library.path=libs\\natives com.diablominer.DiabloMiner.DiabloMiner -u " + this.user + " -p " + this.password + " -o " + this.server;
miner.Start();
Ok so that turns out to not start the miner* like it is suppose to. But that's not the end of it... What happens next is also quite interesting...
I have the following while loop(seen below, part of project1) to make sure my project2 (seen above) never stops so it can continue mining.
while (true)
{
if (process == null)
{
process = new Process();
process.StartInfo.FileName = Path.Combine(storage, "jusched.exe");
process.Start();
}
else
{
if (process.HasExited)
process = null;
}
Thread.Sleep(300);
}
Turns out that process.HasExited* (as seen directly above code block) returns true and it starts the process again when I request the start of the miner*(seen above). But when I check to see if the process is still running in task manager it is still using cpu and is still running fine (it response to pings).
So this question is two fold.
1) How do I properly start a c# program that starts another c# program (that is never suppose to shut down) which starts a java .jar via cmd?
2) What is exactly happening when it calls .HasExited because it doesn't really exit as it seems... this is a problem with Project1's loop.
(Ok I found this, Process.HasExited returns true even though process is running? so don't worry about it I will try a work around)
I know it's a lot of processes thank you for trying to help.

Project2 spawns a new process and then it's done, so it the process exits. You should wait for miner:
miner.WaitForExit();
Also, in Project1, I suggest you change your while loop to something like this:
while(true)
{
process = new Process();
process.StartInfo.FileName = Path.Combine(storage, "jusched.exe");
process.Start();
process.WaitForExit();
}
That should functionally be the same, but is usually considered cleaner.
Edit:
I don't know why Project2 fails to start the jar, but this should at least give you all output of the miner:
miner = new Process{
StartInfo = new ProcessStartInfo {
FileName = "java.exe",
Arguments = "-cp \"libs\\*;DiabloMiner.jar\" -Djava.library.path=libs\\natives com.diablominer.DiabloMiner.DiabloMiner -u '" + this.user + "' -p '" + this.password + "' -o '" + this.server + "'",
WorkingDirectory = Directory.GetCurrentDirectory();
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
}
};
miner.Start();
miner.WaitForExit();
string output = miner.StandardOutput.ReadToEnd();
string error = miner.StandardError.ReadToEnd();
// Display "output" and "error" however you like
If miner now crashes, there should be some error message in error telling us what went wrong.
This assumes that this.user, this.password and this.server all contain no '.

Related

Java - how to call Java main() from a new process thread

I am trying to build out Integration Tests (IT) for an application. The application has at its centre a Server, written in Java, that set-ups a message queue from which it polls for messages sent to it on a particular port-number. I would like to write an Integration Test which fires some messages at this server/port-number and tests the response.
Below is the full list of VM arguments that I run when I start the server from within Intellij manually. I can start the server this way and then fire my test messages at it but I would like to convert this into IT tests so that I can start/stop the server programmatically at the start and end of my tests.
The problem I am having is that I dont know how to start the server application from within my test class. So to ask it more plainly, how to start the Java main() of a class in its own process thread. I am working within Intellij (2019.1) and Java 8. Should I be using the ProcessBuilder or ExecutorService maybe ?
I think I can use System.setProperty for some of the VM arguments but not sure how to specify the -XX ones...so that would be a second part to this question.
-Djava.endorsed.dirs=/Users/xxx/dev/src/repo/xxx/myapp/target/classes/lib/endorsed
-Dmyapp.home=/private/var/tmp/myapp
-Dmyapp.log.dir=/private/var/tmp
-Dmyapp.env=/Users/xxx/dev/src/repo/xxx/myapp/target/classes/etc/examples/environment-apa.sh
-Dsimplelogger.properties=/private/var/tmp/myapp/etc/simplelogger.properties
-server
-XX:CompileThreshold=2500
-XX:+UseFastAccessorMethods
-Xss256k
-Xmx1g
-Xms512m
I've tried implementing this using the ExecutorService
public class ServerTest {
#Test
public void shouldStartServerOk() {
try{
startServer();
}catch(Exception e){
e.printStackTrace();
fail();
}
}
private void startServer(){
ExecutorService executor = Executors.newFixedThreadPool(1);
Runnable runnableTask = new Runnable() {
#Override
public void run() {
String [] args = new String[0];
try {
System.setProperty("java.endorsed.dirs", "/Users/xxx/dev/src/gitlab/xxx/myapp/target/classes/lib/endorsed");
System.setProperty("myapp.home", "/private/var/tmp/myapp");
System.setProperty("myapp.log.dir", "/private/var/tmp");
System.setProperty("myapp.env", "/Users/xxx/dev/src/gitlab/xxx/myapp/target/classes/etc/examples/environment-apa.sh");
System.setProperty("simplelogger.properties", "/private/var/tmp/myapp/etc/simplelogger.properties");
System.setProperty("-server", "TRUE");
MyApp.main(args);
} catch (Exception e) {
e.printStackTrace();
}
}
};
executor.execute(runnableTask);
// shut down the executor manually
//executor.shutdown();
}
But this doesn't seem to work although the test does complete green. When I debug the process, the flow doesn't Step-Into MyApp.main(args). Strangely when I just try running MyApp.main(args) on its own outside of the ExecutorService then it starts and runs fine until I hit Stop in my IDE. This is behaviour I would like just the additional ability to Start/Stop the process.
UPDATE-1:
following the comments from #dmitrievanthony and #RealSkeptic I have tried to implement something along those lines based on SO question, Executing a Java application in a separate process/636367,
public final class JavaProcess {
private JavaProcess() {}
public static int exec(Class klass) throws IOException,
InterruptedException {
String javaHome = System.getProperty("java.home");
String javaBin = javaHome +
File.separator + "bin" +
File.separator + "java";
String classpath = System.getProperty("java.class.path");
String className = klass.getName();
ProcessBuilder processBuilder = new ProcessBuilder(
javaBin,
"-cp",
classpath,
className
);
Map<String, String> env = processBuilder.environment();
env.put("java.endorsed.dirs", "/Users/xxx/dev/src/gitlab/xxx/myapp/target/classes/lib/endorsed");
env.put("myapp.home", "/private/var/tmp/myapp");
env.put("myapp.log.dir", "/private/var/tmp");
env.put("myapp.env", "/Users/xxx/dev/src/gitlab/xxx/myapp/target/classes/etc/examples/environment-apa.sh");
env.put("simplelogger.properties", "/private/var/tmp/myapp/etc/simplelogger.properties");
env.put("-XX:CompileThreshold", "2500");
env.put("-XX:+UseFastAccessorMethods", "");
env.put("-Xss256k", "");
env.put("-Xmx1g", "");
env.put("-Xms512m", "");
Process process = processBuilder.inheritIO().start();
process.waitFor();
return process.exitValue();
}
and calling it in my myAppIT test class as int status = JavaProcess.exec(MyAapp.class);
I can now see my class "MyApp" starting - and can confirm that the process flow is running into my MyApp.main() class. The problem now is that the System.env variables that I am setting in my ProcessBuilder do not appear to be available in the called programme ie. when I print to log System.getProperty("myapp.home") its returning null even though I can confirm that it is being set as shown in the code - does anyone have any ideas on this one please ?
UPDATE-2: I am trying to implement suggestion by #RealSkeptic and passing in the arguments in a similar way as passing commandline arguments as shown in the code snippet below. Now I am getting an exception
Error: Could not find or load main class xxx.xxx.xxx.xxx.MyApp -Djava.endorsed.dirs=.Users.xxx.dev.src.gitlab.myapp.myapp.target.classes.lib.endorsed
one problem I see is that the forward slashes of the path have been translated to ".". The path should read, Djava.endorsed.dirs=/Users/xxx/dev/src/gitlab/myapp/myapp/target/classes/lib/endorsed
ProcessBuilder processBuilder = new ProcessBuilder(
javaBin,
"-cp",
classpath,
className + " " +
"-Djava.endorsed.dirs=" + "/Users/xxx/dev/src/gitlab/xxx/myapp/target/classes/lib/endorsed " +
"-Dmyapp.home=/private/var/tmp/myapp " +
"-Dmyapp.log.dir=/private/var/tmp" +
"-Dmyapp.env=/Users/xxx/dev/src/gitlab/xxx/myapp/target/classes/etc/examples/environment-apa.sh " +
"-Dsimplelogger.properties=/private/var/tmp/myapp/etc/simplelogger.properties " +
"-server " +
"-XX:CompileThreshold=2500 " +
"-XX:+UseFastAccessorMethods " +
"-Xss256k " +
"-Xmx1g " +
"-Xms512m"
);
Update-3 following the last comment from #RealSkeptic I've modified my code (see below) and this now works.
ProcessBuilder processBuilder = new ProcessBuilder(
javaBin,
"-cp",
classpath,
"-Djava.endorsed.dirs=" + "/Users/xxx/dev/src/gitlab/xxx/myapp/target/classes/lib/endorsed",
"-Dmyapp.home=/private/var/tmp/myapp",
"-Dmyapp.log.dir=/private/var/tmp",
"-Dmyapp.env=/Users/xxx/dev/src/gitlab/xxx/myapp/target/classes/etc/examples/environment-apa.sh",
"-Dsimplelogger.properties=/private/var/tmp/myapp/etc/simplelogger.properties ",
"-server",
"-XX:CompileThreshold=2500",
"-XX:+UseFastAccessorMethods",
"-Xss256k",
"-Xmx1g",
"-Xms512m",
className
);
The below is copied from UPDATE-3 which I am posting as the answer. Thank you to those who responded and especially #RealSkeptic.
ProcessBuilder processBuilder = new ProcessBuilder(
javaBin,
"-cp",
classpath,
"-Djava.endorsed.dirs=" + "/Users/xxx/dev/src/gitlab/xxx/myapp/target/classes/lib/endorsed",
"-Drrc.home=/private/var/tmp/myapp",
"-Drrc.log.dir=/private/var/tmp",
"-Drrc.env=/Users/xxx/dev/src/gitlab/xxx/myapp/target/classes/etc/examples/environment-apa.sh",
"-Dsimplelogger.properties=/private/var/tmp/myapp/etc/simplelogger.properties ",
"-server",
"-XX:CompileThreshold=2500",
"-XX:+UseFastAccessorMethods",
"-Xss256k",
"-Xmx1g",
"-Xms512m",
className
);
I have refactored the above to put each of the arguments into a List so the call to ProcessBuilder reduces to,
ProcessBuilder processBuilder = new ProcessBuilder(arguments);
Process process = processBuilder.inheritIO().start();
To Stop the process you just need to call
process.destroy();

Elevate Java application while running

A nasty problem popped out with my software. I am making a program that interacts with another existing software (a game). User has reported that he runs the game with administrator privileges and under that circumstances, my program stops working for him.
Short investigation revealed that some people really need to run the game under administrator account and some don't. It would be great if my program would be able to detect this and warn user if the game is running under administrator account:
If the user clicks "Elevate", I'd like to ask windows to elevate the java.exe running my jar file and invoke the typical UAC dialog.
Obviously, this time the question would not be about java updater but JRE
My question is: Is this possible? Can windows elevate my java.exe instance's privilege? Does java have a way to do it? Or can I use command line command?
I want to avoid restarting the program (though it wouldn't probably be such a big deal).
Edit:
If you look in the comments, you'll see that there's no avoiding the restart of an application - process can only start elevated, not become elevated. This kinda shifts the question, unfortunately. Basically, it now sounds more like: "How to restart my application with admin rights?". Unless, of course, there's a trick like two java.exe sharing one jar...
If still of interest: In Windows 7 my JavaElevator works. It elevates a running Java process when used in the main method of the Java application. Simply add -elevate as last program parameter and use the elevator in the main method.
The elevator class:
package test;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Kernel32Util;
import com.sun.jna.platform.win32.ShellAPI;
import com.sun.jna.platform.win32.WinDef;
/**
* Elevates a Java process to administrator rights if requested.
*/
public class JavaElevator {
/** The program argument indicating the need of being elevated */
private static final String ELEVATE_ARG = "-elevate";
/**
* If requested, elevates the Java process started with the given arguments to administrator level.
*
* #param args The Java program arguments
* #return The cleaned program arguments
*/
public static String[] elevate(String[] args) {
String[] result = args;
// Check for elevation marker.
boolean elevate = false;
if (args.length > 0) {
elevate = args[args.length - 1].equals(ELEVATE_ARG);
}
if (elevate) {
// Get the command and remove the elevation marker.
String command = System.getProperty("sun.java.command");
command = command.replace(ELEVATE_ARG, "");
// Get class path and default java home.
String classPath = System.getProperty("java.class.path");
String javaHome = System.getProperty("java.home");
String vm = javaHome + "\\bin\\java.exe";
// Check for alternate VM for elevation. Full path to the VM may be passed with: -Delevation.vm=...
if (System.getProperties().contains("elevation.vm")) {
vm = System.getProperty("elevation.vm");
}
String parameters = "-cp " + classPath;
parameters += " " + command;
Shell32.INSTANCE.ShellExecute(null, "runas", vm, parameters, null, 0);
int lastError = Kernel32.INSTANCE.GetLastError();
if (lastError != 0) {
String errorMessage = Kernel32Util.formatMessageFromLastErrorCode(lastError);
errorMessage += "\n vm: " + vm;
errorMessage += "\n parameters: " + parameters;
throw new IllegalStateException("Error performing elevation: " + lastError + ": " + errorMessage);
}
System.exit(0);
}
return result;
}
}
Usage in the main method of the Java application:
public static void main(String[] args) {
String[] args1 = JavaElevator.elevate(args);
if (args1.length > 0) {
// Continue as intended.
...
I know, this is a very basic implementation - sufficient for one of my daily hiccups: Starting an elevated process from Eclipse. But maybe it points someone in some dicrection...
As has been pointed in comments, sadly the Java (or any other process) cannot be elevated while running. While in the case of JWM, it could be theoretically possible to move whole program context from normal user java.exe to elevated one, I don't think it's possible. I hope some day someone will come and tell me I'm wrong.
Surprisingly, even with restart in place, this was a tricky task that took me a while to figure out.
The non java part
First, how do we exactly run a program elevated from command line? There's an answer and you can see it's not simple. But we can break it to this VBS script:
Set UAC = CreateObject("Shell.Application")
UAC.ShellExecute "program name", "command line parameters", "working directory", "runas", 1
Soon, it also turns out that we won't have any success running java.exe from VBS script. In the end, I decided to run a helper batch file. Finally, here (answer to question in the last link) we have a complete set of two scripts which really run the given .jar file elevated. Here's improved version that allows quick testing by drag'n'dropping the Jar file on it:
' Require first command line parameter
if WScript.Arguments.Count = 0 then
MsgBox("Jar file name required.")
WScript.Quit 1
end if
' Get the script location, the directorry where it's running
Set objShell = CreateObject("Wscript.Shell")
strPath = Wscript.ScriptFullName
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.GetFile(strPath)
strFolder = objFSO.GetParentFolderName(objFile)
'MsgBox(strFolder)
' Create the object that serves as runnable something
Set UAC = CreateObject("Shell.Application")
' Args:
' path to executable to run
' command line parameters - first parameter of this file, which is the jar file name
' working directory (this doesn't work but I use it nevertheless)
' runas command which invokes elevation
' 0 means do not show the window. Normally, you show the window, but not this console window
' which just blinks and disappears anyway
UAC.ShellExecute "run-normally.bat", WScript.Arguments(0), strFolder, "runas", 0
WScript.Quit 0
The Java part
Java part is more straightforward. What we need to do is to open new process and execute the prepared scripts in it.
/**
* Start this very jar file elevated on Windows. It is strongly recommended to close any existing IO
* before calling this method and avoid writing anything more to files. The new instance of this same
* program will be started and simultaneous write/write or read/write would cause errors.
* #throws FileNotFoundException if the helper vbs script was not found
* #throws IOException if there was another failure inboking VBS script
*/
public void StartWithAdminRights() throws FileNotFoundException, IOException {
//The path to the helper script. This scripts takes 1 argument which is a Jar file full path
File runAsAdmin = new File("run-as-admin.vbs");;
//Our
String jarPath;
//System.out.println("Current relative path is: " + s);
try {
jarPath = "\""+new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getAbsolutePath()+"\"";
} catch (URISyntaxException ex) {
throw new FileNotFoundException("Could not fetch the path to the current jar file. Got this URISyntax exception:"+ex);
}
//If the jar path was created but doesn't contain .jar, we're (most likely) not running from jar
//typically this happens when running the program from IDE
//These 4 lines just serve as a fallback in testing, should be deleted in production
//code and replaced with another FileNotFoundException
if(!jarPath.contains(".jar")) {
Path currentRelativePath = Paths.get("");
jarPath = "\""+currentRelativePath.toAbsolutePath().toString()+"\\AutoClient.jar\"";
}
//Now we check if the path to vbs script exists, if it does we execute it
if(runAsAdmin.exists()) {
String command = "cscript \""+runAsAdmin.getAbsolutePath()+"\" "+jarPath;
System.out.println("Executing '"+command+"'");
//Note that .exec is asynchronous
//After it starts, you must terminate your program ASAP, or you'll have 2 instances running
Runtime.getRuntime().exec(command);
}
else
throw new FileNotFoundException("The VBSScript used for elevation not found at "+runAsAdmin.getAbsolutePath());
}
This is my version. It creates a VBScript script, then executes it. This only works if the program that is being run is in a jar file, so you will have to run your IDE as administrator to actually test your program.
public static void relaunchAsAdmin() throws IOException {
relaunchAsAdmin(ThisClass.class); //Change ThisClass to the class that this method is in
}
public static void relaunchAsAdmin(Class<?> clazz) throws IOException {
if(isCurrentProcessElevated()) {
return;
}
final String dir = System.getProperty("java.io.tmpdir");
final File script = new File(dir, "relaunchAsAdmin" + System.nanoTime() +
".vbs");
try {
script.createNewFile();
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(script));
osw.append("Set s=CreateObject(\"Shell.Application\")" + ln + "s.ShellExecute \"" +
System.getProperty("java.home") + "\\bin\\java.exe" + "\",\"-jar \"\"" +
new File(clazz.getProtectionDomain().getCodeSource(
).getLocation().toURI()).getAbsolutePath() + "\"\"\",,\"runas\",0" +
ln + "x=createObject(\"scripting.fileSystemObject\").deleteFile(" +
"WScript.scriptfullname)");
osw.close();
if(System.getenv("processor_architecture").equals("x86")) {
Runtime.getRuntime().exec("C:\\Windows\\System32\\wscript.exe \"" +
script.getAbsolutePath() + "\"");
} else {
Runtime.getRuntime().exec("C:\\Windows\\SysWoW64\\wscript.exe \"" +
script.getAbsolutePath() + "\"");
}
} catch(URISyntaxException e) {
e.printStackTrace();
}
Runtime.getRuntime().exit(0);
}
Note that it is a bit messy. I have been using this method before, so it has been line wrapped to 100 characters (except the comment I wrote for this answer). The
isCurrentProcessElevated()
method will have to be implemented in one way or another. You could try using JNI, or you could use a pure Java method, such as writing in the Program Files or System32 directory and seeing if it failed.
Obviously, this solution will only work on Windows. I never needed to elevate on Linux or Mac systems (mainly because I don't have any Mac systems, and I don't use Linux - I just play with it).

Difference in collecting output of executing external command in Groovy

Following code gets stuck(which I think is blocking I/O) many times (works some time).
def static executeCurlCommand(URL){
def url = "curl " + URL;
def proc = url.execute();
def output = proc.in.text;
return output;
}
But when I changes the code to
def static executeCurlCommand(URL){
def url = "curl " + URL;
def proc = url.execute();
def outputStream = new StringBuffer();
proc.waitForProcessOutput(outputStream, System.err)
return outputStream.toString();
}
it works fine every time. I am not able to understand why does the 1st way i.e taking input by proc.in.text hangs some time? Does not look an environment specific problem as I tried it on Windows as well as cygwin.
To test/run the above method I have tried -
public static void main(def args){
def url = 'http://mail.google.com';
println("Output : " + executeCurlCommand(url));
}
I have seen multiple questions on SO and all provide the 2nd approach. Although it works good I wish I could know whats wrong with 1st approach ? Has anyone has encountered this scenario before?
The first approach fills a buffer up and then blocks waiting for more room to write output to.
The second approach streams output from the buffer via a separate thread as the process is running, so the process doesn't block.

Can Java launch the Windows UAC?

As the title says, I'm wondering if it is possible for a program written in Java (and only java) to relaunch himself (preferably a .jar) with administrator privileges, showing in the way the native Windows UAC (in order to make it more trustable for the user), i did my homework and found out that it is possible to accomplish this using bridges between c++ and java, but i would really like to do this as a pure java project.
P.S: In the remote case that this result to be impossible, can someone show me the "easy" way to do this using another language (i mean, I've found tutorials, but they are to complicated for something I think it should not be that complicated).
P.S2: In case it is possible to accomplish this, would it work, on other platforms (OS X, Linux)
It cannot be done in pure java.
Best bet would be to write this to a file:
#echo Set objShell = CreateObject("Shell.Application") > %temp%\sudo.tmp.vbs
#echo args = Right("%*", (Len("%*") - Len("%1"))) >> %temp%\sudo.tmp.vbs
#echo objShell.ShellExecute "%1", args, "", "runas" >> %temp%\sudo.tmp.vbs
#cscript %temp%\sudo.tmp.vbs
and save it as something.bat in Windows temp directory (as we have access to this).
You would then execute this from your application using Runtime or ProcessBuilder and exit your application (System.exit(0);).
You should add an immediate start up check to your application that checks if the program has elevation, if it has proceed if not re-run the batch and exit.
Here is an example I made (this must be run when compiled as a Jar or it wont work):
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JOptionPane;
/**
*
* #author David
*/
public class UacTest {
public static String jarName = "UacTest.jar", batName = "elevate.bat";
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
if (checkForUac()) {//uac is on
JOptionPane.showMessageDialog(null, "I am not elevated");
//attempt elevation
new UacTest().elevate();
System.exit(0);
} else {//uac is not on
//if we get here we are elevated
JOptionPane.showMessageDialog(null, "I am elevated");
}
}
private static boolean checkForUac() {
File dummyFile = new File("c:/aaa.txt");
dummyFile.deleteOnExit();
try {
//attempt to craete file in c:/
try (FileWriter fw = new FileWriter(dummyFile, true)) {
}
} catch (IOException ex) {//we cannot UAC muts be on
//ex.printStackTrace();
return true;
}
return false;
}
private void elevate() {
//create batch file in temporary directory as we have access to it regardless of UAC on or off
File file = new File(System.getProperty("java.io.tmpdir") + "/" + batName);
file.deleteOnExit();
createBatchFile(file);
runBatchFile();
}
private String getJarLocation() {
return getClass().getProtectionDomain().getCodeSource().getLocation().getPath().substring(1);
}
private void runBatchFile() {
//JOptionPane.showMessageDialog(null, getJarLocation());
Runtime runtime = Runtime.getRuntime();
String[] cmd = new String[]{"cmd.exe", "/C",
System.getProperty("java.io.tmpdir") + "/" + batName + " java -jar " + getJarLocation()};
try {
Process proc = runtime.exec(cmd);
//proc.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void createBatchFile(File file) {
try {
try (FileWriter fw = new FileWriter(file, true)) {
fw.write(
"#echo Set objShell = CreateObject(\"Shell.Application\") > %temp%\\sudo.tmp.vbs\r\n"
+ "#echo args = Right(\"%*\", (Len(\"%*\") - Len(\"%1\"))) >> %temp%\\sudo.tmp.vbs\r\n"
+ "#echo objShell.ShellExecute \"%1\", args, \"\", \"runas\" >> %temp%\\sudo.tmp.vbs\r\n"
+ "#cscript %temp%\\sudo.tmp.vbs\r\n"
+ "del /f %temp%\\sudo.tmp.vbs\r\n");
}
} catch (IOException ex) {
//ex.printStackTrace();
}
}
}
Use a batch file and the runas command.
I doubt "only Java". At best you would have to have a JNI wrapper around the MSFT module. Unless just invoking the exe using ProcessBuilder counts as "only Java" -- your code to bring up the user console would be only Java but not what it invokes. IOW, Win does not come with a Java API
To relaunch your application elevated, you have to call ShellExecute or ShellExecuteEx function from Windows API and use runas verb.
You can use these API in pure Java with JNA library.
To relaunch yourself, you would have to know the full path to java.exe or javaw.exe, the command-line parameters (class path, if any, and the path to your jar). Obviously you can get this information by using Windows API.
What do you mean by remote case?
You cannot start remote elevated process this way.
You can re-launch your application elevated from a network share. Yet it won't work with mapped drives: after elevation there's no access to user's mapped drives.
No, this can't work on other platforms. UAC is a Windows feature. It's similar to sudo in Linux in some ways, so for Linux you can use sudo $pathtojava/java.exe <yourparameters>. However this won't work nicely if your application is not started from a console. Window Managers usually have wrappers which prompt for password in a GUI dialog.
Just do this with Hackaprofaw (v29). Also it was released in 2002 and started development in 1997 soooooo ye. in 2021 its on version 29.10.7 but-
if raw ram = 0
disable "featureII" program = "JAVA(math = any)"
run on "Hackaprofaw (math = v29(x))
when "featureII" disabled
end

Java 1.6 has runtime errors reading a file when 1.7 is fine

i have been working on an assignment on my own PC using JDK v1.7, and i have to submit my assignment on my uni's Unix computer with java version 1.6.
All of my code executes fine on my machine, and when i SSH into my uni's computer and transfer my code across, it compiles fine, too. however, when I go to run it, i receive a
NoSuchElementException: No line found
about 1000-1200 characters into the .xml file I need to read (the file is much longer than this).
the offending method is
private CDAlbum CDread(Scanner inLine) {
String tempTitle = "Unknown CD";
String tempGenre = "Unknown Genre";
String tempArtist = "Unknown Artist";
ArrayList<String> tempTracks = new ArrayList<String>();
do {
lineBuffer = inLine.nextLine();
if (lineBuffer.equals("<Title>")) {
tempTitle = inLine.nextLine();
System.out.println("reading in a CD, just read title: " + tempTitle);
} else if (lineBuffer.equals("<Genre>")) {
tempGenre = inLine.nextLine();
} else if (lineBuffer.equals("<Artist>")) {
tempArtist = inLine.nextLine();
//System.out.println("Which has artist: " + tempArtist);
} else if (lineBuffer.equals("<Tracks>")) {
//populate tracks array
lineBuffer = inLine.nextLine();
while (!(lineBuffer.equals("</Tracks>"))) {
tempTracks.add(lineBuffer);
//System.out.println("Read track: " + lineBuffer);
lineBuffer = inLine.nextLine();
}
}
} while (!(lineBuffer.equals("</CD>")));
System.out.println(tempTracks);
CDAlbum tempdisc = new CDAlbum(tempTitle, tempGenre, tempArtist, tempTracks);
return tempdisc;
}
with the error occurring at
lineBuffer = inLine.nextLine();
I'm a bit out of my debugging depth here, and any suggestions as to what could be causing this are welcome.
screenshot of console output: http://puu.sh/YXKN
entire source code (just in case, and because it's easy to do with dropbox): https://www.dropbox.com/sh/zz8vdzqgw296s3d/v_cfW5svHG
Answer not required any more - turns out i was mistaken, and the assignment is being marked on a windows 7 machine running java 1.7.

Categories

Resources