public static JobInstance run(com.enioka.jqm.model.JobInstance job)
    {
        if (job == null)
        {
            throw new IllegalArgumentException("Argument job cannot be null");
        }
        jqmlogger.info("Starting single runner for payload " + job.getId());

        // Set thread name - used in audits
        Thread.currentThread().setName("JQM single runner;;" + job.getId());

        // JNDI first - the engine itself uses JNDI to fetch its connections!
        Helpers.registerJndiIfNeeded();

        // Get a copy of the instance, to be sure to get a non detached item.
        DbConn cnx = Helpers.getNewDbSession();
        job = com.enioka.jqm.model.JobInstance.select_id(cnx, job.getId());
        job.loadPrmCache(cnx);

        // Parameters
        final int poll = Integer.parseInt(GlobalParameter.getParameter(cnx, "internalPollingPeriodMs", "10000"));
        final int jobId = job.getId();

        // Security
        if (System.getSecurityManager() == null)
        {
            System.setSecurityManager(new SecurityManagerPayload());
        }

        // Create run container
        final RunningJobInstance l = new RunningJobInstance(job, new JavaRunner(cnx));

        // Kill signal handler
        final Thread mainT = Thread.currentThread();
        Thread shutHook = new Thread()
        {
            @Override
            public void run()
            {
                Thread.currentThread().setName("JQM single runner;stophook;" + jobId);
                jqmlogger.info("Shutting down the single runner before its normal end (kill order)");

                // The stop order may come from SIGTERM or SIGINT - in which case, the payload is not aware it should stop.
                try
                {
                    JqmClientFactory.getClient().killJob(jobId);
                }
                catch (JqmInvalidRequestException e)
                {
                    // Ignore - the job has already finished.
                }

                // To speed up payload learning its coming demise
                mainT.interrupt();

                // Give one second for graceful payload stop
                try
                {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e)
                {
                    // Nothing to do
                }

                // Shut down the process if needed
                if (!l.isDone())
                {
                    // Timeout! Violently halt the JVM.
                    jqmlogger.info("Job has not finished gracefully and will be stopped abruptly");
                    l.endOfRun(com.enioka.jqm.model.State.CRASHED);
                    Runtime.getRuntime().halt(0);
                }
                else
                {
                    jqmlogger.debug("Stop order was handled gracefully");
                }
            }
        };
        Runtime.getRuntime().addShutdownHook(shutHook);

        // Kill order (from database) handler
        Thread stopper = new Thread()
        {
            @Override
            public void run()
            {
                Thread.currentThread().setName("JQM single runner;killerloop;" + jobId);
                DbConn cnx = null;

                while (!Thread.interrupted())
                {
                    cnx = Helpers.getNewDbSession();
                    com.enioka.jqm.model.JobInstance job = com.enioka.jqm.model.JobInstance.select_id(cnx, jobId);
                    cnx.close();

                    if (job != null && job.getInstruction().equals(com.enioka.jqm.model.Instruction.KILL))
                    {
                        jqmlogger.debug(
                                "Job " + jobId + " has received a kill order. It's JVM will be killed after a grace shutdown period");
                        System.exit(1); // Launch the exit hook.
                        break;
                    }

                    try
                    {
                        Thread.sleep(poll);
                    }
                    catch (InterruptedException e)
                    {
                        break;
                    }
                }
            }
        };
        stopper.start();

        // Go.
        l.run();

        // Free resources
        Runtime.getRuntime().removeShutdownHook(shutHook);
        cnx.close();
        stopper.interrupt();

        // Get result
        return JqmClientFactory.getClient().getJob(job.getId());
    }
public static JobInstance run ( com . enioka . jqm . model . JobInstance job ) { if ( job == null ) { throw new IllegalArgumentException ( "Argument job cannot be null" ) ; } jqmlogger . info ( "Starting single runner for payload " + job . getId ( ) ) ; Thread . currentThread ( ) . setName ( "JQM single runner;;" + job . getId ( ) ) ; Helpers . registerJndiIfNeeded ( ) ; DbConn cnx = Helpers . getNewDbSession ( ) ; job = com . enioka . jqm . model . JobInstance . select_id ( cnx , job . getId ( ) ) ; job . loadPrmCache ( cnx ) ; final int poll = Integer . parseInt ( GlobalParameter . getParameter ( cnx , "internalPollingPeriodMs" , "10000" ) ) ; final int jobId = job . getId ( ) ; if ( System . getSecurityManager ( ) == null ) { System . setSecurityManager ( new SecurityManagerPayload ( ) ) ; } final RunningJobInstance l = new RunningJobInstance ( job , new JavaRunner ( cnx ) ) ; final Thread mainT = Thread . currentThread ( ) ; Thread shutHook = new Thread ( ) { @ Override public void run ( ) { Thread . currentThread ( ) . setName ( "JQM single runner;stophook;" + jobId ) ; jqmlogger . info ( "Shutting down the single runner before its normal end (kill order)" ) ; try { JqmClientFactory . getClient ( ) . killJob ( jobId ) ; } catch ( JqmInvalidRequestException e ) { } mainT . interrupt ( ) ; try { Thread . sleep ( 1000 ) ; } catch ( InterruptedException e ) { } if ( ! l . isDone ( ) ) { jqmlogger . info ( "Job has not finished gracefully and will be stopped abruptly" ) ; l . endOfRun ( com . enioka . jqm . model . State . CRASHED ) ; Runtime . getRuntime ( ) . halt ( 0 ) ; } else { jqmlogger . debug ( "Stop order was handled gracefully" ) ; } } } ; Runtime . getRuntime ( ) . addShutdownHook ( shutHook ) ; Thread stopper = new Thread ( ) { @ Override public void run ( ) { Thread . currentThread ( ) . setName ( "JQM single runner;killerloop;" + jobId ) ; DbConn cnx = null ; while ( ! Thread . interrupted ( ) ) { cnx = Helpers . getNewDbSession ( ) ; com . enioka . jqm . model . JobInstance job = com . enioka . jqm . model . JobInstance . select_id ( cnx , jobId ) ; cnx . close ( ) ; if ( job != null && job . getInstruction ( ) . equals ( com . enioka . jqm . model . Instruction . KILL ) ) { jqmlogger . debug ( "Job " + jobId + " has received a kill order. It's JVM will be killed after a grace shutdown period" ) ; System . exit ( 1 ) ; break ; } try { Thread . sleep ( poll ) ; } catch ( InterruptedException e ) { break ; } } } } ; stopper . start ( ) ; l . run ( ) ; Runtime . getRuntime ( ) . removeShutdownHook ( shutHook ) ; cnx . close ( ) ; stopper . interrupt ( ) ; return JqmClientFactory . getClient ( ) . getJob ( job . getId ( ) ) ; }
Runs an existing JobInstance.

@param job
@param logFile
the file to which output the run log. if null, only stdout will be used.
@return the result of the run