i have problems creating a temporary file with java through lua.
The code works if i start the jav program through the command line but if the program is started by the Lua-plugin it does not create a file.
Cases:
Command Line> java Bot !info
BotAnswer.txt will be created in Temp directory if the file already exist it will be overwritten
The file contains the correct data
Execution through Lua
ERROR: Java programm will start but BotAnswer.txt wont be created ... if file already exists nothing happens
The file is missing or contains the wrong data
If file already existed it sends the old and wrong content to the chat
I guess there are some permission errors or something like that.
It would be a huge help for me if you could tell me how to fix this.
Here are the code snippets:
located in C:\Program Files\TeamSpeak 3 Client\plugins\lua_plugin\testmodule
Lua
if targetMode == 2 then --targetMode is always 2 for this case
os.execute("java Bot " .. message) --Start java program with message as arguments (message = !info)
if message == "!info" then
folderName = os.getenv("TEMP")
fileName = "BotAnswer.txt"
filePath = io.open(folderName .. "/" .. fileName, "r")
answer = filePath:read("*all")
filePath:close()
os.remove(folderName .. "/" .. fileName)
ts3.requestSendChannelTextMsg(serverConnectionHandlerID, answer, fromID) --Send the content of BotAnswer.txt to the teamspeak Chat
end
end
Java
public class Bot {
public static void main(String[] args) {
Bot myBot = new Bot();
String command = myBot.getCommand(args);
String answer = myBot.differentiateCommand(command);
try {
myProcessor.writeAnswerToFile(answer);
} catch (Exception e) {}
}
public String getCommand(String[] args) {
if(args.length == 0) {
System.exit(0);
}
if (args[0].startsWith("!") != true) {
System.exit(0);
}
String message = args[0];
if (message.startsWith("!")) {
String[] msgArray = message.split("!");
message = msgArray[1];
}
return message;
}
public String differentiateCommand(String command) {
String answer = "";
if (command.startsWith("info")) {
answer = "Tis should be the TeamSpeak answer";
}
}
public void writeAnswerToFile(String answer)throws IOException {
String tempDir = System.getenv("TEMP");
File tempFile = new File(tempDir + "/" + "BotAnswer.txt");
tempFile.createNewFile();
FileWriter writer = new FileWriter(tempFile);
writer.write(answer);
writer.flush();
writer.close();
}
}
Related
I'm trying to make a function that reboot the javafx application, On windows 10 works perfectly but on Windows 7 it doesn't, I search for this solution and it was perfect, then I test it on Windows 10 and nothing, the app just turn off. Also I test it watching for an exception inside the log file and it doesn't throw any Exception.
Something specific must be made in order to work also on windows 7? maybe a different approach? Thanks.
this is the code:
//Restart app the current Java application, with parameter you can pass a Runnable to do before restart app, null if not
public static void restartApplication(Runnable runBeforeRestart) throws IOException {
try {
/**
* Sun property pointing the main class and its arguments.
* Might not be defined on non Hotspot VM implementations.
*/
final String SUN_JAVA_COMMAND = "sun.java.command";
// java binary
String java = System.getProperty("java.home") + "/bin/java";
// vm arguments
List<String> vmArguments = ManagementFactory.getRuntimeMXBean().getInputArguments();
StringBuffer vmArgsOneLine = new StringBuffer();
for (String arg : vmArguments) {
// if it's the agent argument : we ignore it otherwise the
// address of the old application and the new one will be in conflict
if (!arg.contains("-agentlib")) {
vmArgsOneLine.append(arg);
vmArgsOneLine.append(" ");
}
}
// init the command to execute, add the vm args
final StringBuffer cmd = new StringBuffer("\"" + java + "\" " + vmArgsOneLine);
// program main and program arguments
String[] mainCommand = System.getProperty(SUN_JAVA_COMMAND).split(" ");
// program main is a jar
if (mainCommand[0].endsWith(".jar")) {
// if it's a jar, add -jar mainJar
cmd.append("-jar " + new File(mainCommand[0]).getPath());
} else {
// else it's a .class, add the classpath and mainClass
cmd.append("-cp \"" + System.getProperty("java.class.path") + "\" " + mainCommand[0]);
}
// finally add program arguments
for (int i = 1; i < mainCommand.length; i++) {
cmd.append(" ");
cmd.append(mainCommand[i]);
}
// execute the command in a shutdown hook, to be sure that all the
// resources have been disposed before restarting the application
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
try {
Runtime.getRuntime().exec(cmd.toString());
} catch (IOException e) {
logToFile.log(e, "info", "The application fail to restart, applying the command");
}
}
});
// execute some custom code before restarting
if (runBeforeRestart!= null) {
runBeforeRestart.run();
}
// Wait for 2 seconds before restart
//TimeUnit.SECONDS.sleep(2);
// exit
System.exit(0);
} catch (Exception e) {
// something went wrong
logToFile.log(e, "info", "The application fail to restart generally");
}
}
Update: Searching for other approach I found out a solution, It's test it on both Windows OS and works
here it's the code:
//Restart app the current Java application, with parameter you can pass a Runnable to do before restart app, null if not
public static void restartApplication(Runnable runBeforeRestart, Integer TimeToWaitToExecuteTask) throws IOException {
try {
// execute some custom code before restarting
if (runBeforeRestart != null) {
// Wait for 2 seconds before restart if null
if (TimeToWaitToExecuteTask != null) {
TimeUnit.SECONDS.sleep(TimeToWaitToExecuteTask);
} else {
TimeUnit.SECONDS.sleep(2);
}
runBeforeRestart.run();
}
final String javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
final File currentJar = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI());
/* is it a jar file? */
if (!currentJar.getName().endsWith(".jar"))
return;
/* Build command: java -jar application.jar */
final ArrayList<String> command = new ArrayList<String>();
command.add(javaBin);
command.add("-jar");
command.add(currentJar.getPath());
final ProcessBuilder builder = new ProcessBuilder(command);
builder.start();
System.exit(0);
} catch (Exception e) {
// something went wrong
logToFile.log(e, "info", "The application fail to restart generally");
}
}
What is the best way of passing a string (arg1 in case of code below) with about 800K characters (yes, that's a huge number) to a java jar. Following is the code I am using to invoke the jar file:
p = Runtime.getRuntime().exec(jrePath+"/bin/java -jar C:/folder/myjar.jar methodName" + arg1);
ALternately, how can I create a jar file to accept one String input and one byte[] input in main{ in void main(String args[])}
Or any other ideas? The requirement is to somehow pass the huge String/byte[] of String to a java jar file that I am creating
As mentioned in this question, there is a maximum argument length set by the operating system. Seeing as this argument is 800K characters, its fairly safe to say that you have exceeded this max value on most computers. To get around this, you can write arg1 to a temp file using the built in API:
final File temp;
try {
temp = File.createTempFile("temp-string", ".tmp");
} catch (final IOException e){
//TODO handle error
return;
}
try (final BufferedWriter writer = new BufferedWriter(new FileWriter(temp))) {
writer.write(arg1);
} catch (final IOException e){
//TODO handle error
return;
}
try {
// run process and wait for completion
final Process process = Runtime.getRuntime().exec(
jrePath + "/bin/java -jar C:/folder/myjar.jar methodName " +
temp.getAbsolutePath());
final int exitCode = process.waitFor();
if (exitCode != 0) {
//TODO handle error
}
} catch (final IOException | InterruptedException e){
//TODO handle error
return;
}
if (!file.delete()) {
//TODO handle error
}
I have a program that I want to run from a detected USB drive (removable storage such as a USB), and this was done by creating two classes: external.java and DetectDrive.java as follows:
external.java
public class external
{
public static void main(String args[]) throws InterruptedException
{
DetectDrive d = new DetectDrive();
String DetectDrive = d.USBDetect();
BufferedWriter fileOut;
String filePath = DetectDrive;
System.out.println(filePath);
try
{
fileOut = new BufferedWriter(new FileWriter("F:\\external.bat"));
fileOut.write("cd "+ filePath +"\n");
fileOut.write("external.exe"+"\n");
fileOut.close(); //close the output stream after all output is done
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("cmd /c start" +DetectDrive+ "\\external.bat");
p.waitFor();
} catch (IOException e){
e.printStackTrace();
}
}
}
DetectDrive.java
import java.io.*;
import java.util.*;
import javax.swing.filechooser.FileSystemView;
public class DetectDrive
{
public String USBDetect()
{
String driveLetter = "";
FileSystemView fsv = FileSystemView.getFileSystemView();
File[] f = File.listRoots();
for (int i = 0; i < f.length; i++)
{
String drive = f[i].getPath();
String displayName = fsv.getSystemDisplayName(f[i]);
String type = fsv.getSystemTypeDescription(f[i]);
boolean isDrive = fsv.isDrive(f[i]);
boolean isFloppy = fsv.isFloppyDrive(f[i]);
boolean canRead = f[i].canRead();
boolean canWrite = f[i].canWrite();
if (canRead && canWrite && !isFloppy && isDrive && (type.toLowerCase().contains("removable") || type.toLowerCase().contains("rimovibile")))
{
//log.info("Detected PEN Drive: " + drive + " - "+ displayName);
driveLetter = drive;
break;
}
}
/*if (driveLetter.equals(""))
{
System.out.println("Not found!");
}
else
{
System.out.println(driveLetter);
}
*/
//System.out.println(driveLetter);
return driveLetter;
}
}
The problem now is that there are no errors when I run the external.java (main). However, the output only shows the detected drive which is F:\ but it doesn’t run the specified program which is external.exe and it also mentioned that the program got terminated. Can someone please help me point out where I went wrong and what the correct codes should be like? I am new to Java.
I got the DetectDrive codes from http://www.snip2code.com/Snippet/506/Detect-USB-removable-drive-in-Java which I believe is now in maintenance.
Is it possible to change the new FileWriter("F:\external.bat") to detect the USB drive directory instead? For example letting the program detect the usb drive and automatically put in the correct directory instead of us typing the F:\ manually. I have no answer for this yet. Please help!
It seems problem is with command :
"cmd /c start" +DetectDrive+ "\\external.bat"
It should have a {space} after start:
"cmd /c start " +DetectDrive+ "\\external.bat"
I am trying to create a directory but it seems to fail every time? I have checked that it is not a permission issue too, I have full permission to write to that directory. Thanks in advance.
Here is the code:
private void writeTextFile(String v){
try{
String yearString = convertInteger(yearInt);
String monthString = convertInteger(month);
String fileName = refernce.getText();
File fileDir = new File("C:\\Program Files\\Sure Important\\Report Cards\\" + yearString + "\\" + monthString);
File filePath = new File(fileDir + "\\"+ fileName + ".txt");
writeDir(fileDir);
// Create file
FileWriter fstream = new FileWriter(filePath);
try (BufferedWriter out = new BufferedWriter(fstream)) {
out.write(v);
}
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
private void writeDir(File f){
try{
if(f.mkdir()) {
System.out.println("Directory Created");
} else {
System.out.println("Directory is not created");
}
} catch(Exception e){
e.printStackTrace();
}
}
public static String convertInteger(int i) {
return Integer.toString(i);
}
Calendar cal = new GregorianCalendar();
public int month = cal.get(Calendar.MONTH);
public int yearInt = cal.get(Calendar.YEAR);
Here is the output:
Directory is not created
Error: C:\Program Files\Sure Important\Report Cards\2012\7\4532.txt (The system cannot find the path specified)
It's possibly because File.mkdir creates the directory only if the parent directory exists.
Try using File.mkdirs which creates all the necessary directories.
Here's the code which worked for me.
private void writeDir(File f){
try{
if(f.mkdirs()) {
System.out.println("Directory Created");
} else {
System.out.println("Directory is not created");
}
} catch(Exception e){
// Demo purposes only. Do NOT do this in real code. EVER.
// It squashes exceptions ...
e.printStackTrace();
}
}
The only change I made was to change f.mkdir() to f.mkdirs() and it worked
I think that #La bla bla has nailed it, but just for completeness, here are all of the things that I can think of that could cause a call to File.mkdir() to fail:
A syntax error in the pathname; e.g. an illegal character in a file name component
The directory to contain the final directory component does not exist.
There is already something with that name.
You don't have permission to create a directory in the parent directory
You don't have permission to do a lookup in some directory on the path
The directory to be created is on a read-only file system.
The file system gave a hardware error or network related error.
(Obviously, some of these possibilities can be quickly eliminated in the context of this question ...)
I think this will work only on an English language Windows installation:
System.getProperty("user.home") + "/Desktop";
How can I make this work for non English Windows?
I use a french version of Windows and with it the instruction:
System.getProperty("user.home") + "/Desktop";
works fine for me.
I think this is the same question... but I'm not sure!:
In java under Windows, how do I find a redirected Desktop folder?
Reading it I would expect that solution to return the user.home, but apparently not, and the link in the answer comments back that up. Haven't tried it myself.
I guess by using JFileChooser the solution will require a non-headless JVM, but you are probably running one of them.
This is for Windows only. Launch REG.EXE and capture its output :
import java.io.*;
public class WindowsUtils {
private static final String REGQUERY_UTIL = "reg query ";
private static final String REGSTR_TOKEN = "REG_SZ";
private static final String DESKTOP_FOLDER_CMD = REGQUERY_UTIL
+ "\"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\"
+ "Explorer\\Shell Folders\" /v DESKTOP";
private WindowsUtils() {}
public static String getCurrentUserDesktopPath() {
try {
Process process = Runtime.getRuntime().exec(DESKTOP_FOLDER_CMD);
StreamReader reader = new StreamReader(process.getInputStream());
reader.start();
process.waitFor();
reader.join();
String result = reader.getResult();
int p = result.indexOf(REGSTR_TOKEN);
if (p == -1) return null;
return result.substring(p + REGSTR_TOKEN.length()).trim();
}
catch (Exception e) {
return null;
}
}
/**
* TEST
*/
public static void main(String[] args) {
System.out.println("Desktop directory : "
+ getCurrentUserDesktopPath());
}
static class StreamReader extends Thread {
private InputStream is;
private StringWriter sw;
StreamReader(InputStream is) {
this.is = is;
sw = new StringWriter();
}
public void run() {
try {
int c;
while ((c = is.read()) != -1)
sw.write(c);
}
catch (IOException e) { ; }
}
String getResult() {
return sw.toString();
}
}
}
or you can use JNA (complete example here)
Shell32.INSTANCE.SHGetFolderPath(null,
ShlObj.CSIDL_DESKTOPDIRECTORY, null, ShlObj.SHGFP_TYPE_CURRENT,
pszPath);
javax.swing.filechooser.FileSystemView.getFileSystemView().getHomeDirectory()
Seems not that easy...
But you could try to find an anwser browsing the code of some open-source projects, e.g. on Koders. I guess all the solutions boil down to checking the HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Desktop path in the Windows registry. And probably are Windows-specific.
If you need a more general solution I would try to find an open-source application you know is working properly on different platforms and puts some icons on the user's Desktop.
You're just missing "C:\\Users\\":
String userDefPath = "C:\\Users\\" + System.getProperty("user.name") + "\\Desktop";
public class Sample {
public static void main(String[] args) {
String desktopPath =System.getProperty("user.home") + "\\"+"Desktop";
String s = "\"" + desktopPath.replace("\\","\\\\") + "\\\\" +"satis" + "\"";
System.out.print(s);
File f = new File(s);
boolean mkdir = f.mkdir();
System.out.println(mkdir);
}
}
there are 2 things.
you are using the wrong slash. for windows it's \ not /.
i'm using RandomAccesFile and File to manage fles and folders, and it requires double slash ( \\ ) to separate the folders name.
Simplest solution is to find out machine name, since this name is only variable changing in path to Desktop folder. So if you can find this, you have found path to Desktop. Following code should do the trick - it did for me :)
String machine_name = InetAddress.getLocalHost().getHostName();
String path_to_desktop = "C:/Documents and Settings/"+machine_name+"/Desktop/";