I have already can execute *.java or *.jar on PHP at my xampp, with this code
exec('java -cp stanford-parser.jar edu.stanford.nlp.parser.lexparser.LexicalizedParser stanford-parser-2012-03-09-models\edu\stanford\nlp\models\lexparser\englishPCFG.ser.gz text.txt > result.txt');
it's localhost in my computer.
And now I want to hosting my coding into website internet. I'm afraid the java don't want to execute and run the exec line. What should I do to make exec *.java or *.jar can run on website?
I hear that I must install tomcat or javabridge. But I don't understand. can you help me? thanks very much.
You don't need tomcat to run the above command, you should be able to run it just like you do on your own machine as long as java is installed on the server you're running on. Of course, you'll want to make sure your paths are set correctly, and even then this is not a good idea, especially if you expect it to be hit by a lot of traffic or if it takes a significant amount of time to complete (> 5 seconds).
The easiest way to do this the 'right' way is to kick off a long running process (outside of the Apache/php request and set some type of flag or indicator when it is complete. You can have the browser refresh if you want them to be immediately notified when it is completed. A simple way to do this is to run the command above as a background process (append & to the end of the command as shown below). Of course, this leave out a lot of error handling that may need to be done.
exec('java -cp stanford-parser.jar edu.stanford.nlp.parser.lexparser.LexicalizedParser stanford-parser-2012-03-09-models\edu\stanford\nlp\models\lexparser\englishPCFG.ser.gz text.txt &> result.txt');
Related
I should preface this by saying I'm a novice who got in way too deep trying to make a Swing app an exe. After reading the docs I've sort of gleaned what the meanings of all the parameters are, but I'm still confused. What I'm trying to achieve is an application that can be double clicked and launch the GUI, without creating a JRE (if it is not necessary) No jfx so it is non modular.
I tried to use these following commands:
jpackage --type app-image -i "C:\Users\User\quadAdventGame\out\artifacts\quadAdventGame_jar" -n quadGameTest --main-class Main --main-jar quadAdventGame.jar
Then using that app image:
jpackage -n name --app-image "C:\Users\User\quadGameTest"
This resulted in two things: The installer ran, Norton Antivirus flagged it, saying it stopped the process, and then I told Norton to let it go. Then the installer failed to run, saying it had no access to "main.msi" in my Local disk. I also tried direct msi installing,
jpackage --type msi -i "C:\Users\User\quadAdventGame\out\artifacts\quadAdventGame_jar" -n quadGameTest --main-class Main --main-jar quadAdventGame.jar
which simply doesn't run when double clicked.
BTW, here's what the generated folder looks like, which seems like it may be wrong.
My questions would be:
Is Norton some how involved in the stoppage of my app from running? I'm not sure what Main.msi is in my temp folder.
Are my commands wrong? It seems like they are not correct for what I want to achieve, which is just a simple runnable application. The code is baby stuff, this is literally just me trying to prove I can do this. Does the main class input need to have the .java prefix? It honestly might be me just naming stuff wrong, but the generated folders have a jar that runs fine.
If so, how can these commands be remedied?
I am on the Oracle JDK 14.
I have a java program (text-based no GUI) that I have written and compiled and uploaded to a server.
I run it with java -cp myjar.jar mypackage.MyClass which starts it running processing a datafile with 20,000,000+ entries in it and printing output to System.out. I have calculated that it will take a very long time to process the data and I didn't want to have my laptop open for the 10 days of number crunching...
When I log out of my shell however, the process stops.
How can I execute the command and log out without it stopping? What is that even called?
I am using an Amazon Ubuntu EC2 server. I log in using a certificate from Mac OSX with terminal. The server seems to be using a bash shell.
Hope someone can help me out!
Jason.
Consider using screen instead of nohup. It allows you to create a virtual terminal that persists even after you logout/disconnect. When you reconnect to the server, you can immediately jump into the screen session you last had open.
Typical workflow on the server:
type screen (you may need to press space to leave intro page)
type in your command that you want to leave long-running (your java program, or an OS upgrade)
press ctrl a+d to leave screen (make sure to hold ctrl down)
To re-enter screen just use screen -r, and you will see the previous terminal and any running programs as you left it.
You can use nohup
nohup java -cp myjar.jar mypackage.MyClass > yourLogFile.log &
-----> http://ss64.com/bash/nohup.html
The exec command doesn't work on my server, it does not do anything, I've had safe_mode off, and verified that all the console commands are working, I've tried with absolute paths. I've checked the permissions on the applications and all the applications I need have execution permissions. I don't know what else to do, here are the rundown of the codes I've tried.
echo exec('/usr/bin/whoami');
echo exec('whoami');
exec('whoami 2>&1',$output,$return_val);
if($return_val !== 0) {
echo 'Error<br>';
print_r($output);
}
exec('/usr/bin/whoami 2>&1',$output,$return_val);
if($return_val !== 0) {
echo 'Error<br>';
print_r($output);
}
The last two codes display:
Error
Array ( )
I've contacted the server service and they can't help me, they don't know why the exec command isn't working.
have a look at /etc/php.ini , there under:
; This directive allows you to disable certain functions for security reasons.
; It receives a comma-delimited list of function names. This directive is
; *NOT* affected by whether Safe Mode is turned On or Off.
; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.disable-functions
disable_functions =
make sure that exec is not listed like this:
disable_functions=exec
If so, remove it and restart the apache.
For easy debugging I usually like to execute the php file manually (Can request more errors without setting it in the main ini). to do so add the header:
#!/usr/bin/php
ini_set("display_errors", 1);
ini_set("track_errors", 1);
ini_set("html_errors", 1);
error_reporting(E_ALL);
to the beginning of the file, give it permissions using chmod +x myscript.php and execute it ./myscript.php. It's very heedful especially on a busy server that write a lot to the log file.
EDIT
Sounds like a permissions issue. Create a bash script that does something simple as echo "helo world" and try to run it. Make sure you have permissions for the file and for the folder containing the file. you chould just do chmod 755 just for testing.
A few more notes
For debugging always wrap your exec/shell_exec function in var_dump().
error_reporting(-1); should be on, as should be display_errors, as last resort even set_error_handler("var_dump"); - if only to see if PHP itself didn't invoke execvp or else.
Use 2>&1 (merge the shells STDERR to STDOUT stream) to see why an invocation fails.
For some cases you may need to wrap your command in an additional shell invocation:
// capture STDERR stream via standard shell
echo shell_exec("/bin/sh -c 'ffmpeg -opts 2>&1' ");
Else the log file redirect as advised by #Mike is the most recommendable approach.
Alternate between the various exec functions to uncover error messages otherwise. While they mostly do the same thing, the output return paths vary:
exec() → either returns the output as function result, or through the optional $output paramater.
Also provides a $return_var parameter, which contains the errno / exit code of the run application or shell. You might get:
ENOENT (2) - No such file
EIO (127) - IO error: file not found
// run command, conjoined stderr, output + error number
var_dump(exec("ffmpeg -h 2>&1", $output, $errno), $output, $errno));
shell_exec() → is what you want to run mostly for shell-style expressions.
Be sure to assign/print the return value with e.g. var_dump(shell_exec("..."));
`` inline backticks → are identical to shell_exec.
system() → is similar to exec, but always returns the output as function result (print it out!). Additionally allows to capture the result code.
passthru() → is another exec alternative, but always sends any STDOUT results to PHPs output buffer. Which oftentimes makes it the most fitting exec wrapper.
popen() or better proc_open() → allow to individually capture STDOUT and STDERR.
Most shell errors wind up in PHPs or Apaches error.log when not redirected. Check your syslog or Apache log if nothing yields useful error messages.
Most common issues
As mentioned by #Kuf: for outdated webhosting plans, you could still find safe_mode or disable_functions enabled. None of the PHP exec functions will work. (Best to find a better provider, else investigate "CGI" - but do not install your own PHP interpreter while unversed.)
Likewise can AppArmor / SELinux / Firejail sometimes be in place. Those limit each applications ability to spawn new processes.
The intended binary does not exist. Pretty much no webhost does have tools like ffmpeg preinstalled. You can't just run arbitrary shell commands without preparation. Some things need to be installed!
// Check if `ffmpeg` is actually there:
var_dump(shell_exec("which ffmpeg"));
The PATH is off. If you installed custom tools, you will need to ensure they're reachable. Using var_dump(shell_exec("ffmpeg -opts")) will search all common paths - or as Apache has been told/constrained (often just /bin:/usr/bin).
Check with print_r($_SERVER); what your PATH contains and if that covers the tool you wanted to run. Else you may need to adapt the server settings (/etc/apache2/envvars), or use full paths:
// run with absolute paths to binary
var_dump(shell_exec("/bin/sh -c '/usr/local/bin/ffmpeg -opts 2>&1'"));
This is somewhat subverting the shell concept. Personally I don't think this preferrable. It does make sense for security purposes though; moreover for utilizing a custom installation of course.
Permissions
In order to run a binary on BSD/Linux system, it needs to be made "executable". This is what chmod a+x ffmpeg does.
Furthermode the path to such custom binaries needs to be readable by the Apache user, which your PHP scripts run under.
More contemporary setups use PHPs builtin FPM mode (suexec+FastCGI), where your webhosting account equals what PHP runs with.
Test with SSH. It should go without saying, but before running commands through PHP, testing it in a real shell would be highly sensible. Probe with e.g. ldd ffmpeg if all lib dependencies are there, and if it works otherwise.
Use namei -m /Usr/local/bin/ffmpeg to probe the whole path, if unsure where any access permission issues might arise from.
Input values (GET, POST, FILE names, user data) that get passed as command arguments in exec strings need to be escaped with escapeshellarg().
$q = "escapeshellarg";
var_dump(shell_exec("echo {$q($_GET['text'])} | wc"));
Otherwise you'll get shell syntax errors easily; and probably exploit code installed later on...
Take care not to combine backticks with any of the *exec() functions:
$null = shell_exec(`wc file.txt`);
↑ ↑
Backticks would run the command, and leave shell_exec with the output of the already ran command. Use normal quotes for wrapping the command parameter.
Also check in a shell session how the intended program works with a different account:
sudo -u www-data gpg -k
Notably for PHP-FPM setups test with the according user id. www-data/apache are mostly just used by olden mod_php setups.
Many cmdline tools depend on some per-user configuration. This test will often reveal what's missing.
You cannot get output for background-run processes started with … & or nohup …. In such cases you definitely need to use a log file redirect exec("cmd > log.txt 2>&1 &");
On Windows
CMD invocations will not play nice with STDERR streams often.
Definitely try a Powershell script to run any CLI apps else, or use a command line like:
system("powershell -Command 'pandoc 2>&1'");
Use full paths, and prefer forward slashes always ("C:/Program Files/Whatevs/run.exe" with additional quotes if paths contain spaces).
Forward slashes work on Windows too, ever since they were introduced in MS-DOS 2.0
Figure out which service and SAM account IIS/Apache and PHP runs as. Verify it has execute permissions.
You can't run GUI apps usually. (Typical workaround is the taskscheduler or WMI invocations.)
PHP → Python, Perl
If you're invoking another scripting interpreter from PHP, then utilize any available debugging means in case of failures:
passthru("PYTHONDEBUG=2 python -vvv script.py 2>&1");
passthru("perl -w script.pl 2>&1");
passthru("ruby -wT1 script.rb 2>&1");
Or perhaps even run with any syntax -c check option first.
Since you are dropping out of the PHP context into the native shell, you are going to have a lot of issues debugging.
The best and most foolproof I have used in the past is writing the output of the script to a log file and tailing it during PHP execution.
<?php
shell_exec("filename > ~/debug.log 2>&1");
Then in a separate shell:
tail -200f ~/debug.log
When you execute your PHP script, your errors and output from your shell call will display in your debug.log file.
You can retreive the outputs and return code of the exec commands, thoses might contains informations that would explain the problem...
exec('my command', $output, $return);
I am trying to run a simple JAVA program once per day on a Windows 7 machine.
My code runs fine inside NetBeans. If I do a clean and build it suggests this:
C:\Program Files\Java\jdk1.7.0/bin/java -jar "C:\Users\User1\Documents\NetBeansProjects\Facebook\dist\Facebook.jar"
This does not work from the DOS prompt of course because of the space between program and files so I do this:
C:\Program Files\Java\jdk1.7.0/bin/java -jar "C:\Users\User1\Documents\NetBeansProjects\Facebook\dist\Facebook.jar" -jar "C:\Users\User1\Documents\NetBeansProjects\Facebook\dist\Facebook.jar"
This works from the DOS prompt.
I now create a task in Windows Scheduler to run:
C:\Program Files\Java\jdk1.7.0/bin/java
with arguments:
-jar "C:\Users\User1\Documents\NetBeansProjects\Facebook\dist\Facebook.jar"
When I then run it, all I see is a DOS box flashing up for a second. I expect the code to take about 30 secs to run. The code should persist data to a database and no updates happen.
The code also uses java.util.logging so I should see log entries and I don't.
I strongly suspect that I am not running the JAVA command properly or that there's a bad classpath issue that it present when running via Scheduler that isn't there when running from the DOS prompt.
Help would be appreciated. If you've seen this before and can sort it that would be great. If you can tell me how to get a meaningful error trace from Scheduler than that would also be really helpful.
Thanks!
I Think that you could create a simple batch script that will launch your program in this way :
#echo off
REM Eventually change directory to the program directory
cd C:\Users\User1\Documents\NetBeansProjects\Facebook\dist\
REM run the program
"C:\Program Files\Java\jdk1.7.0\bin\java.exe" -jar "C:\Users\User1\Documents\NetBeansProjects\Facebook\dist\Facebook.jar"
Copy it into the notepad and save as java_script.cmd and then schedule this script instead of the program directly.
I solved it after changing all fonts' references to "SansSerif"
I was using Jasper Reports inside Java to create a PDF file. It was working fine when I double click the batch file or Scheduler with Windows Server 2003 but not working with the Scheduler of 2008.
I tried many different things nothing worked so I though Could it be that Windows Server 2008 is blocking the access?.
Now is working perfect. So, if you are having problems check the references to anything you are using.
The scheduler will run under a different user unless you specify what user to run as. If it isn't running as your user then it won't be able to write to your directories.
The real problem to the original question is a java installation issue on Microsoft systems. Java jre installs into Program Files\java. The executable (java.exe) is only installed in that java\bin directory. Running from the command line, the os looks in the proper location for the java.exe. Running from other MS tools (such as VBA Excel or in this case TaskScheduler), it does not!
You can see that TaskScheduler is looking in the wrong place by viewing the tasks history in the TaskScheduler tool. Double click on some of the history events and one will list the action and return code. The action will show that the TaskScheduler is trying to run
"C:\Windows\system32\java.EXE"
So, copy java.exe from the java\bin directory into the place where the scheduler is looking, and now it will work.
Or update your task and provide the full path to java.exe.
You can also update the environment system path to look for java in the java\bin directory, but that has to apply to all users and sometimes this is faulty as well.
In an application I am writing, I am launching another application (a runnable JAR) using Runtime.exec(...). Everything launches successfully in Windows, but Linux (specifically certain installations of CentOS - works in Ubuntu) has been giving me some problems. For some reason, the only way the secondary application will successfully launch is if I execute the first through a terminal. All behavior works as expected. However, if I launch the first application by double-clicking its icon (without a terminal open), the button to launch the second application seems to do nothing. I get no exceptions or error output - just a flash of my progress bar saying that it is launching, and then nothing. I can confirm through jconsole that the second application's process is never launched.
I have seen the commonly linked article on the pitfalls of the exec method ( http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html ), but have not been able to solve this problem with anything I have found there. I am in fact reading the output and error streams of the second process, as I see all output when it successfully runs (after launching the first application through a terminal command). Not knowing a lot about deeper workings of Linux, I think this sounds like it may be a permissions issue with the output stream or something, but I am not sure.
In case it helps to diagnose the problem, I am using the command:
rt.exec(new String[]{"\bin\bash", "-c", "java -jar myjarfile.jar myArg1 myArg2 ..."}); Since this works (depending on how the application is launched), I'm not too concerned that anything is wrong with this piece of code...
Anyone have any suggestions? Thanks in advance!
EDIT: The solution was to fix the directory to the JAR I was attempting to run. When launched via the GUI, user.dir was pointing to the parent directory of the folder containing my application. Since I'm using Eclipse RCP, my solution was to use
String currDirPath = Platform.getInstallLocation().getURL().toString(); instead. Thanks for the help everyone!
Since you're just using the jar file name - myjarfile.jar - and not the full path to it, depending on the current working directory, the jar may or may not be found. Try changing your exec command to use the full path to the jar instead. You can debug this by using rt.exec() to write the output of 'pwd' to a text file.
instead of
rt.exec(new String[]{"\bin\bash", "-c", "java -jar myjarfile.jar myArg1 myArg2 ..."});
use
rt.exec(new String[]{"\bin\bash", "-c", "/***path to java***/java -jar myjarfile.jar myArg1 myArg2 ..."});