Call Java from PHP with timeout handler - java

Problem: I am running java files via PHP that a user submits. It is possible for a java file to cause an infinite loop. How can I handle this in the php execution process?
Here is my code:
$proc = proc_open($javaCmd, array(array("pipe", "r"), array("pipe", "w"), array("pipe", "w")), $pipes);
// Check status here logic ?
proc_close($proc);
It currently waits for the process to finish, but I want it to timeout after 30 seconds or a minute. I tried set_time_limit(x), but that does not terminate java.exe.
My question is, is it possible for me to check the status of java.exe process after X seconds, then terminate if it is still running? Or, do I need to use a timeout functionality in java (i.e. have a main class that executes the user's submitted classes on a thread)

Yes, it's possible. I don't think a java process is any different than any other process in this regard. See these links for unix exec with timeout and windows exec with timeout.
I didn't write this code, but here it is copy-pasted in case the original disappears from the Internet:
For unix:
<?php
function PsExecute($command, $timeout = 60, $sleep = 2) {
// First, execute the process, get the process ID
$pid = PsExec($command);
if( $pid === false )
return false;
$cur = 0;
// Second, loop for $timeout seconds checking if process is running
while( $cur < $timeout ) {
sleep($sleep);
$cur += $sleep;
// If process is no longer running, return true;
echo "\n ---- $cur ------ \n";
if( !PsExists($pid) )
return true; // Process must have exited, success!
}
// If process is still running after timeout, kill the process and return false
PsKill($pid);
return false;
}
function PsExec($commandJob) {
$command = $commandJob.' > /dev/null 2>&1 & echo $!';
exec($command ,$op);
$pid = (int)$op[0];
if($pid!="") return $pid;
return false;
}
function PsExists($pid) {
exec("ps ax | grep $pid 2>&1", $output);
while( list(,$row) = each($output) ) {
$row_array = explode(" ", $row);
$check_pid = $row_array[0];
if($pid == $check_pid) {
return true;
}
}
return false;
}
function PsKill($pid) {
exec("kill -9 $pid", $output);
}
For windows:
<?php
// pstools.inc.php
function PsExecute($command, $timeout = 60, $sleep = 2) {
// First, execute the process, get the process ID
$pid = PsExec($command);
if( $pid === false )
return false;
$cur = 0;
// Second, loop for $timeout seconds checking if process is running
while( $cur < $timeout ) {
sleep($sleep);
$cur += $sleep;
// If process is no longer running, return true;
if( !PsExists($pid) )
return true; // Process must have exited, success!
}
// If process is still running after timeout, kill the process and return false
PsKill($pid);
return false;
}
function PsExec($command) {
exec( dirname(__FILE__). "\\psexec.exe -s -d $command 2>&1", $output);
while( list(,$row) = each($output) ) {
$found = stripos($row, 'with process ID ');
if( $found )
return substr($row, $found, strlen($row)-$found-strlen('with process ID ')-1); // chop off last character '.' from line
}
return false;
}
function PsExists($pid) {
exec( dirname(__FILE__). "\\pslist.exe $pid 2>&1", $output);
while( list(,$row) = each($output) ) {
$found = stristr($row, "process $pid was not found");
if( $found !== false )
return false;
}
return true;
}
function PsKill($pid) {
exec( dirname(__FILE__). "\\pskill.exe $pid", $output);
}

Related

Find & Replace inside a compiled .jar file. And then downloading it

So basically what I want: find and replace strings in a .jar file whatever length it is. It works for me fine except I need to have the same length of the replaced variable as the variable. I want that the length doesn't matter. Does anyone know how to help me?
PHP code:
<?php
$search1 = '%%__NONCE__%%';
$replace1 = 'ME_0000000001';
$search2 = '%%__USER__%%';
$replace2 = '000000000001';
$search3 = '%%__RESOURCE__%%';
$replace3 = '1';
function modifyzip($archive, $search, $replace) {
$zip = new ZipArchive();
$status = $zip->open($archive);
// echo $status;
if ($status == true) {
/* Get the count of files BEFORE the loop */
$filecount = $zip->numFiles;
// echo $filecount;
for ($i=0; $i < $filecount; $i++) {
$name = $zip->getNameIndex($i);
$content = $zip->getFromName($name);
$edited = str_replace($search, $replace, $content);
if ($edited != $content) {
// echo $edited;
// echo $edited . "\n\n";
}
$zip->deleteName($name);
$zip->addFromString($name, $edited);
}
}
$zip->close();
}
$templateFilename = 'zips/a.jar';
$inputFilename = 'zips/b.jar';
if (!copy($templateFilename, $inputFilename)) {
die("Could not copy '$templateFilename' to '$inputFilename'");
}
call_user_func('modifyzip', $inputFilename, $search1, $replace1);
call_user_func('modifyzip', $inputFilename, $search2, $replace2);
call_user_func('modifyzip', $inputFilename, $search3, $replace3);
//echo file_get_contents($templateFilename);
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$inputFilename");
header("Content-Type: application/java-archive");
header("Content-Transfer-Encoding: binary");
// read the file from disk
readfile($inputFilename);
unlink($inputFilename);
Java Luyten error:
java.lang.IllegalArgumentException: Argument 'value' must be in the range [1, 18], but value was: 0.
at com.strobel.core.VerifyArgument.inRange(VerifyArgument.java:346)
at com.strobel.assembler.ir.ConstantPool$Tag.fromValue(ConstantPool.java:532)
at com.strobel.assembler.ir.ConstantPool.read(ConstantPool.java:362)
at com.strobel.assembler.metadata.JarTypeLoader.getInternalNameFromClassFile(JarTypeLoader.java:105)
at com.strobel.assembler.metadata.JarTypeLoader.tryLoadType(JarTypeLoader.java:78)
at us.deathmarine.luyten.LuytenTypeLoader.tryLoadType(LuytenTypeLoader.java:25)
at com.strobel.assembler.metadata.MetadataSystem.resolveType(MetadataSystem.java:120)
at com.strobel.assembler.metadata.MetadataSystem.lookupTypeCore(MetadataSystem.java:81)
at com.strobel.assembler.metadata.MetadataResolver.lookupType(MetadataResolver.java:46)
at us.deathmarine.luyten.Model.openEntryByTreePath(Model.java:338)
at us.deathmarine.luyten.Model$TreeListener$1.run(Model.java:266)

org.hidetake.groovy.ssh.session.BadExitStatusException

I have an exception then code tries execute the line "execute 'sudo systemctl stop roc && systemctl start roc' "
Caused by: org.hidetake.groovy.ssh.session.BadExitStatusException: Command returned exit status 1: sudo systemctl stop roc && systemctl start roc
remotes {
webServer {
host = '192.168.0.1'
user = 'vasid'
password = 'XXXX'
}
}
task deploy {
doLast {
ssh.run {
session(remotes.webServer) {
put from: '/work/roc.jar',
into: '/opt/roc'
execute 'sudo systemctl stop roc && systemctl start roc'
}
}
}
}

How to pass two arguments while calling jar file in batch script?

Following is my batch script
#echo off
set /a java_output=43350674
set /a img_id=1
setlocal enableDelayedExpansion
:top
for /f "tokens=1-2 delims= " %%A in ( 'java -jar test.jar %java_output%,%img_id%' ) do (
set /a java_output=%%A
set /a img_id=%%B
)
echo %java_output%
SET /A "err=error"
if "%java_output%" EQU "%err%" (
echo %img_id% > batch_log.txt
echo "End of batch script"
exit /b %ERRORLEVEL%
) else (
if %java_output% LSS 43350681 (
goto top
)
)
endlocal
Getting expected output but I am getting "Missing operand" error each time the for loops runs.
Error in " set /a img_id=%%B "
I have doubt in this line for /f "tokens=1-2 delims= " %%A in ( 'java -jar test.jar %java_output%,%img_id%' ) do (
Is this the correct way to pass 2 batch variables to jar file ?
Following is my java code in jar file.
public class Test {
public static void main(String[] args)
{
System.out.println(args[0]);
int ret = Integer.parseInt(args[0]);
// for error scenarios
String err = "error";
if(ret == 43350677)
{
System.out.println(err+" "+ret);
}
else
{
System.out.println(ret+1+" "+ret);
}
}
}
Following is my output :
C:>test.bat
Missing operand.
43350675
Missing operand.
43350676
Missing operand.
43350677
Missing operand.
0
"End of batch script"
If you want to start a jar file together with parameters out of a Windows script use the following syntax:
call java -jar my-jar-file.jar parm1 parm2 ...
The call is essential, otherwise the parameters are ignored.

Swift/Objective-C background Task

I am developing an Swift app. I'm using sockets for the background connection. But know I get this error, when I try to use it:
libsystem_kernel.dylib`__pthread_kill:
0x11329edd0 <+0>: movl $0x2000148, %eax ; imm = 0x2000148
0x11329edd5 <+5>: movq %rcx, %r10
0x11329edd8 <+8>: syscall -> 0x11329edda <+10>: jae 0x11329ede4 ; <+20>
0x11329eddc <+12>: movq %rax, %rdi
0x11329eddf <+15>: jmp 0x113297d6f ; cerror_nocancel
0x11329ede4 <+20>: retq
0x11329ede5 <+21>: nop
0x11329ede6 <+22>: nop
0x11329ede7 <+23>: nop
It also shows "Thread: Signal Sigabrt"
.Here I call the method:
let x:ComObwareAlifstoPostConnection = ComObwareAlifstoPostConnection()
DispatchQueue.global(qos: .background).async {
x.connect()
let y = x.getPostsWith("username", with: "password", with: "15000000000000", with: "down", with: "0")
DispatchQueue.main.async {
}
}
And here is my Objective-C class (It's Java converted by J2Objc)
- (IOSObjectArray *)getPostsWithNSString:(NSString *)username
withNSString:(NSString *)password
withNSString:(NSString *)time
withNSString:(NSString *)direction
withNSString:(NSString *)minTime {
IOSObjectArray *returnArray = nil;
#try {
[self connect];
if (ComObwareAlifstoPostConnection_socket == nil) {
return nil;
}
JavaIoDataOutputStream *os = new_JavaIoDataOutputStream_initWithJavaIoOutputStream_([ComObwareAlifstoPostConnection_socket getOutputStream]);
[os writeUTFWithNSString:JreStrcat("C$$$$$$$$$$", '2', ComObwareAlifstoPostConnection_SPLITTED, username, ComObwareAlifstoPostConnection_SPLITTED, password, ComObwareAlifstoPostConnection_SPLITTED, time, ComObwareAlifstoPostConnection_SPLITTED, direction, ComObwareAlifstoPostConnection_SPLITTED, minTime)];
[os flush];
JavaIoObjectInputStream *in = new_JavaIoObjectInputStream_initWithJavaIoInputStream_([((JavaNetSocket *) nil_chk(ComObwareAlifstoPostConnection_socket)) getInputStream]);
while ((returnArray = (IOSObjectArray *) cast_check([in readObject], IOSClass_arrayType(ComObwareAlifstoPostPost_class_(), 1))) != nil) {
return returnArray;
}
}
#catch (JavaNetUnknownHostException *e) {
}
#catch (JavaIoIOException *e) {
if (!hastried_) {
hastried_ = true;
return [self getPostsWithNSString:username withNSString:password withNSString:time withNSString:direction withNSString:minTime];
}
[((JavaIoIOException *) nil_chk(e)) printStackTrace];
}
#catch (JavaLangClassNotFoundException *e) {
}
return nil;
}
So, where could be the error? With some other method it works.
Build with debugging enabled, either in Xcode or, if using the command-line, include the C compiler (clang) "-g" flag. Then run it in Xcode's debugger (or from the command-line using lldb). When your app aborts, it should break at the pkill code you listed, but you can move up the stack frame ("up" command) to see which statement

RMI Client invokes Graceful shutdown. Server Stops. Manually started again. But somehow gets autokilled. Why?

Everthing on Java.
Environment: RedHat Linux 12.3
Lets get into details of the communication flow:
fig1.
NOTE: 1. Old model: There was NO A.java
"script.sh" starts/stops B.java as process
2. New model: There IS A.java
"script.sh" never uses A
"script.sh" starts B.java as process.
"myGraceful.sh" stops process Gracefully
"script.sh" is NEVER used for stopping
Server(B.java in server.jar):
Java Process triggered as: ./script.sh {start|stop}
Its a legacy class existing for 10 yrs or more
has RemoteB Interface
has
graceFul(){ ..handles all DB ,user states,connection...etc
..works perfectly from Admin
..invoked as RMI from JSP
..never invoked by script till now
}
initServer(){...}
getUsers(){...}
Requirement & My Effort:
Everyone knows how the code RMI Looks or .sh to invoke java. Hence I dont think pasting a proprietary code should be expected here.
Graceful needs to be done from shell script on same Server node. On Server everything runniing by Spring. I will die if I try to Inject a Bean as there is going to be 100x1000 dependencies coming in queue. Hence I created
RMI Client(com/common/task/A.java in same server.jar):
A can be triggered by: ./myGraceful.sh stop (eg. java -cp... com.A 2>&1)
in same server.jar - hence inevitaby loaded (note not running) on same Server node.
having p s v main(String args[])
Forks Thread ..thread calls RMI shutdown on B ...and thread expected
to die on own.
Problem:
Server shutting down perfectly. Then If I isssue following command AGAIN and AGAIN:
./script.sh start
Server starts up. But within a minute it stops automatically. I dont have any clue what and which is stopping the Server. I Observed
Prior to any of my new modifications:
"./script.sh stop" [used to work flawlessly calling kill -9 $pid ]
"ps - aefwww | grep java" used to show:
pid ppid.. /usr/java/jdk/bin/java ........java -D.... -Djava.timeout=.. -D....
pid ppid.. .../abc/ ....java...
pid ppid.. .../xyz/ .................java...
But now
"./myGraceful.sh stop" triggers modified server.jar(which now has A.java):
"ps - aefwww | grep java" shows:
pid ppid.. .../abc/ ....java...
pid ppid.. .../xyz/ .................java...
Here goes some code:
myGraceful.sh:
----------------
#!/bin/bash
CLASSPATH=$COMMON_CLASS_PATH:$LIB_INHOUSE/server.jar
rmiIp=x.y.zz.www [hidden]
rmiPort=xxxx [hidden]
peerId=1
period=5
function kill_server(){
echo -n "Shutting down Server ($pid): "
echo "executing Arnab"
echo "arg0 : $0 pid : $pid"
java -Djava.rmi.server.hostname=localhost \
com.common.task.GracefulRunner $rmiIp $rmiPort $peerId $period 2>&1
echo Done
}
case "$1" in
start)
get_pids "CustomBootstrap" $2
if [ "$pid" != "" ] ; then
get_processname "CustomBootstrap" $2
if [ "$server" != "" ] ; then
echo "Server already running. pid = $pid"
exit 1
fi
if [ "$ctserver" != "" ] ; then
echo "Shutting down CT Server($pid): "
kill -SIGQUIT $pid
kill -9 $pid
echo Done
fi
fi
$0 run $2 1>&2 &
sleep 2
$0 status $2
# $0 err
;;
stop)
$0 kill $2
;;
kill)
get_pids "CustomBootstrap" $2
if [ "$pid" != "" ] ; then
kill_server
echo "Server ended at `date`"
else
get_pids "Launcher" $2
if [ "$pid" != "" ] ; then
kill_server
else
echo "Server is not running !"
fi
fi
;;
esac
A.java
public class A {
class GracefulStopperThread implements Runnable{
private String serverRMIIp = null;
private int serverRmiPort =0;
private String serverPeerId =null;
private int shutDownPeriod =0;
public GracefulStopperThread(String rmiIp,String rmiPort,String peerId,String period){
serverRMIIp = rmiIp;
serverRmiPort = Integer.parseInt(rmiPort);
serverPeerId = peerId;
shutDownPeriod =Integer.parseInt(period);
}
public void run() {
System.out.println("***************************************** GracefulStopper is running *******************************************");
System.out.println("serverPeerId :="+serverPeerId+" , shutDownPeriod :="+shutDownPeriod);
try {
IRemoteServer serverRef = null;
String rmiUrl = getURL(serverRMIIp,serverRmiPort,serverPeerId);
System.out.println("THE RMI URL : "+rmiUrl);
serverRef = (IRemoteServer) Naming.lookup(rmiUrl );
com.server.ds.IRemoteServer pcServerRef = (com.server.ds.IRemoteServer) serverRef;
pcServerRef.graceful(SHUTDOWN_TYPE_SERVER_NOTSYSTEM,"Gracefully Shutting down withing 10 mins", shutDownPeriod);
System.out.println("GracefulStopperThread completed ");
} catch (Exception e) {
e.printStackTrace();
}
}
private String getURL(String rmiIp,int rmiPort,String peerId) {
return new StringBuffer(32).append("rmi://").append(serverRMIIp).append(':').append(serverRmiPort)
.append('/').append(serverPeerId).toString();
}
}
public static void main(String args[]) throws InterruptedException {
A agent = new A();
Runnable stopper = agent.new GracefulStopperThread(args[0],args[1],args[2],args[3]);
Thread t = new Thread(stopper);
t.start();
t.join();
System.out.println("MainThread completed ");
}
}
From catalina and tomcat logs it became clear - there was a wrong missing JMX entry in the jmx config file which has nothing to do with all above. This caused Tomcat to stop after 85 % of its start. Hence it actually never started. Question can be closed and marked solved.

Categories

Resources