Start a Job via PRO API using Java

Prerequisites

  1. Get a Java environment for development, such as IntelliJ IDEA . Here we’ll assume you’re just using the 64-bit version.

  2. Get the latest official JDK from the Oracle website: Download JDK More information about JDK can be found in Oracle’s documentation: JDK Documentation

  3. Get AIMMS PRO API via your AIMMS PRO Portal.

    1. Log into AIMMS PRO

    2. Go to Help > getting started

    3. Download AIMMS PRO API

    4. Move it to a convenient location, and unzip the archive

Note

If you are on the AIMMS Cloud, you may directly use https://your-cloud-name.cloud.aimms.com/api-library/pro-api-complete.zip

Running the Example

  1. First publish the example application.

    You can find the example model in .\pro-api-complete\examples\AimmsModel\PROApiExampleApplication.aimms. Create an aimmspack, say PROApiExampleApplication.aimmspack and publish it on your AIMMS PRO system, for instance using the name PROApiExampleApplication and version 1.

  2. Start the Java example by opening .\pro-api-complete\examples\java\pom.xml using IntelliJ IDEA.

    1. You may note the following message: Project SDK is not defined.

      To repair:

      1. Click on the “Setup SDK” to the right

      2. Select the latest version without subversion, here 11.

      3. click Ok in the dialog. The message Project SDK is not defined. should disappear.

      ../../_images/ProjectSDKIsNotDefinedRepairing.PNG
    2. Adapt application details presented on lines 30 - 39 of Program.java file.

      ../../_images/AdaptingConnectionDetails.png
      • Line 30, DEFAULT_ENDPOINT: this might also be wss://your-cloud-name.cloud.aimms.com

        • when connection is encrypted, start with wss (cloud systems are always encrypted).

        • when connection is not encrypted, start with ws

      • Lines 32-34, DEFAULT_ENVIRONMENT, DEFAULT_USERNAME, and DEFAULT_PASSWORD should have been supplied by your AIMMS PRO administrator.

      • Lines 38-39, DEFAULT_APPLICATION_NAME, DEFAULT_APPLICATION_VERSION, the name and version of the app as it is published.

    3. Now you can start the demo via IDEA menu > Run > Run

Output

In the window 4: Run of IDEA, you’ll get the following log:

 1"C:\Program Files\Java\jdk1.8.0_201\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.1\lib\idea_rt.jar=63713:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_201\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\rt.jar;C:\u\s\How To\develop\Articles\98\downloads\pro-api-complete\examples\java\target\classes;C:\Users\chris\.m2\repository\com\aimms\pro\java-api\2.30.53821.225\java-api-2.30.53821.225.jar;C:\Users\chris\.m2\repository\org\slf4j\slf4j-log4j12\1.7.5\slf4j-log4j12-1.7.5.jar;C:\Users\chris\.m2\repository\org\slf4j\slf4j-api\1.7.5\slf4j-api-1.7.5.jar;C:\Users\chris\.m2\repository\log4j\log4j\1.2.17\log4j-1.2.17.jar;C:\Users\chris\.m2\repository\commons-cli\commons-cli\1.3.1\commons-cli-1.3.1.jar" com.aimms.proapiexample.Program
 2INFO  - main - Engine                     - ARMI 1.6.8.71
 3INFO  - main - ConnectionStore            - initiating connection to 'tcp://localhost:63715'
 4INFO  - Thread-0 - TCPProxyServer             - startWebSocketProxy( '/127.0.0.1:63720', 'wss://aimms-sandbox.cloud.aimms.com/ws-proxy/backend')
 5INFO  - WebSocketClient@2130038760-31 - WebSocketProxy             - onConnectBinary('WebSocketSession[websocket=JettyAnnotatedEventDriver[com.aimms.pro.api.impl.WebSocketProxy@739229c7],behavior=CLIENT,connection=WebSocketClientConnection@e0e48ed{IDLE}{f=Flusher[queueSize=0,aggregateSize=0,failure=null],g=Generator[CLIENT,validating],p=Parser@5e7fe217[ExtensionStack,s=START,c=0,len=0,f=null,p=WebSocketPolicy@1415755[behavior=CLIENT,maxTextMessageSize=65536,maxTextMessageBufferSize=32768,maxBinaryMessageSize=1048576,maxBinaryMessageBufferSize=32768,asyncWriteTimeout=60000,idleTimeout=300000,inputBufferSize=4096]]},remote=WebSocketRemoteEndpoint@4abacde0[batching=true],incoming=JettyAnnotatedEventDriver[com.aimms.pro.api.impl.WebSocketProxy@739229c7],outgoing=ExtensionStack[queueSize=0,extensions=[],incoming=org.eclipse.jetty.websocket.common.WebSocketSession,outgoing=org.eclipse.jetty.websocket.client.io.WebSocketClientConnection]]')
 6INFO  - main - Program                    - Current jobs
 7INFO  - main - Program                    - App=PROApiExampleApplication 2, Description=BasicScheduleJob, Status=QUEUED, Owner=theo@ROOT, Created=Wed Apr 10 14:27:08 CEST 2019, RunTime=0, QueueTime=-59
 8INFO  - main - Program                    - Waiting for job: App=PROApiExampleApplication 2, Description=ScheduleJobAndCheck, Status=QUEUED, Owner=theo@ROOT, Created=Wed Apr 10 14:26:09 CEST 2019, RunTime=0, QueueTime=1
 9INFO  - main - Program                    - Waiting for job: App=PROApiExampleApplication 2, Description=ScheduleJobAndCheck, Status=QUEUED, Owner=theo@ROOT, Created=Wed Apr 10 14:26:09 CEST 2019, RunTime=0, QueueTime=2
10INFO  - main - Program                    - Waiting for job: App=PROApiExampleApplication 2, Description=ScheduleJobAndCheck, Status=QUEUED, Owner=theo@ROOT, Created=Wed Apr 10 14:26:09 CEST 2019, RunTime=0, QueueTime=4
11INFO  - main - Program                    - Waiting for job: App=PROApiExampleApplication 2, Description=ScheduleJobAndCheck, Status=QUEUED, Owner=theo@ROOT, Created=Wed Apr 10 14:26:09 CEST 2019, RunTime=0, QueueTime=5
12INFO  - main - Program                    - Waiting for job: App=PROApiExampleApplication 2, Description=ScheduleJobAndCheck, Status=INITIALIZING, Owner=theo@ROOT, Created=Wed Apr 10 14:26:09 CEST 2019, RunTime=0, QueueTime=6
13INFO  - main - Program                    - Waiting for job: App=PROApiExampleApplication 2, Description=ScheduleJobAndCheck, Status=INITIALIZING, Owner=theo@ROOT, Created=Wed Apr 10 14:26:09 CEST 2019, RunTime=1, QueueTime=6
14INFO  - main - Program                    - Ended: App=PROApiExampleApplication 2, Description=ScheduleJobAndCheck, Status=FINISHED, Owner=theo@ROOT, Created=Wed Apr 10 14:26:09 CEST 2019, RunTime=2, QueueTime=6
15INFO  - main - Program                    - Waiting for events on job
16INFO  - main - Program                    - Waiting for events on job
17INFO  - main - Program                    - Waiting for events on job
18INFO  - main - Program                    - Waiting for events on job
19INFO  - main - Program                    - Waiting for events on job
20INFO  - main - Program                    - Waiting for events on job
21INFO  - main - Program                    - Waiting for events on job
22INFO  - DispatcherThread[13] - JobInteractor              - onHandle: ProcedureCall 'notifyClientWithResults'
23INFO  - main - Program                    - procedureCall: notifyClientWithResults
24INFO  - main - Program                    -  argument[{0}], Parameter:
25INFO  - main - Program                    -   [] : 600.0
26INFO  - main - Program                    -  argument[1], StringParameter:
27INFO  - main - Program                    -   [] : 'ThisIsTheResult'
28INFO  - DispatcherThread[15] - JobInteractor              - Scheduling job finish over 1000 ms
29INFO  - main - Program                    - Waiting for events on job
30INFO  - Thread-21 - JobInteractor              - onFinished
31INFO  - main - Program                    - job Finished
32INFO  - main - Program                    - Waiting for events on job
33INFO  - main - Program                    - TupleValuePair: com.aimms.pro.api.parameter.TupleValuePair@482f8f11
34INFO  - main - Program                    - TupleValuePair: com.aimms.pro.api.parameter.TupleValuePair@1593948d
35INFO  - main - Program                    - TupleValuePair: com.aimms.pro.api.parameter.TupleValuePair@1b604f19
36INFO  - main - Program                    - TupleValuePair: com.aimms.pro.api.parameter.TupleValuePair@7823a2f9
37INFO  - main - Program                    - Waiting for events on job
38INFO  - main - Program                    - Waiting for events on job
39INFO  - main - Program                    - Waiting for events on job
40INFO  - main - Program                    - Waiting for events on job
41INFO  - main - Program                    - Waiting for events on job
42INFO  - main - Program                    - Requesting progress report
43INFO  - main - Program                    - Waiting for events on job
44INFO  - DispatcherThread[13] - JobInteractor              - onHandle: ProcedureCall 'notifyClientWithProgress'
45INFO  - main - Program                    - procedureCall: notifyClientWithProgress
46INFO  - main - Program                    - Percentage completed = 10.0%, not enough, continueing
47INFO  - main - Program                    - Waiting for events on job
48INFO  - main - Program                    - Waiting for events on job
49
50... repetition removed...
51
52INFO  - main - Program                    - Waiting for events on job
53INFO  - main - Program                    - Waiting for events on job
54INFO  - main - Program                    - Requesting progress report
55INFO  - DispatcherThread[14] - JobInteractor              - onHandle: ProcedureCall 'notifyClientWithProgress'
56INFO  - main - Program                    - procedureCall: notifyClientWithProgress
57INFO  - main - Program                    - Percentage completed = 80.0%, enough, so stopping the current tast
58INFO  - DispatcherThread[15] - JobInteractor              - onError: 'while running procedure 'proc_AdvancedInteraction':You have interrupted execution. [error 2014].'
59INFO  - DispatcherThread[15] - JobInteractor              - Scheduling job finish over 1000 ms
60INFO  - main - Program                    - error: while running procedure 'proc_AdvancedInteraction':You have interrupted execution. [error 2014].
61ERROR - main - Program                    - Could not execute program
62java.lang.IllegalStateException: Could not terminate session {"sessionID" : "ba39f084-35f3-4463-b8b9-979cb81f9771", "clientQueueID" : "66b3d082-94a0-49fd-9220-0dce5b1abb96", "workerQueueID" : "44ae81d8-8aa7-48ab-8a13-5660aa17b779"}
63    at com.aimms.pro.api.impl.ServiceProvider.terminateSession(ServiceProvider.java:152)
64    at com.aimms.pro.api.impl.Job.terminate(Job.java:66)
65    at com.aimms.proapiexample.Program.AdvancedInteractLoop(Program.java:327)
66    at com.aimms.proapiexample.Program.AdvancedInteraction(Program.java:289)
67    at com.aimms.proapiexample.Program.main(Program.java:83)
68Caused by: com.aimms.armi.UserException: Session manager error / Cannot terminate session in state 'Finished' [error 1064]
69    at com.aimms.armi.BaseCompletionHandler.userException(BaseCompletionHandler.java:38)
70    at com.aimms.armi.core.RemoteInvocationCompletionHandler.executeCompletion(RemoteInvocationCompletionHandler.java:101)
71    at com.aimms.armi.core.RemoteInvocationRequest.execute(RemoteInvocationRequest.java:44)
72    at com.aimms.pro.armi.api.Api.SessionManagerServiceStub.InterruptSession(SessionManagerServiceStub.java:143)
73    at com.aimms.pro.api.impl.ServiceProvider.terminateSession(ServiceProvider.java:147)
74    ... 4 more
75INFO  - main - Channel                    - close
76INFO  - main - WebSocketProxy             - close( 1000, 'Connection closed' )
77INFO  - main - WebSocketProxy             - onClose( 1001, 'Shutdown')
78Exception in thread "Thread-22" java.lang.NullPointerException
79    at com.aimms.pro.api.impl.ServiceProvider.unsubscribe(ServiceProvider.java:134)
80    at com.aimms.pro.api.impl.JobInteractor.unregisterForMessages(JobInteractor.java:271)
81    at com.aimms.pro.api.impl.JobInteractor$1.run(JobInteractor.java:348)
82    at java.lang.Thread.run(Thread.java:748)
83
84Process finished with exit code 0

Selected remarks about that log:

  • Lines 1-5 are about making the connection.

  • We first execute BasicScheduleJob which starts an AIMMS job after a delay of 60 seconds. Note the absence of tracing statements in this procedure, so there isn’t anything in our log.

  • Lines 6-7 are about ListAllJobs, there is currently one job waiting, the job we’ve just started (because of its initial delay).

  • Lines 8-14 are about BasicScheduleJobAndCheck; we see that the status this jobs moves through the states QUEUED, INITIALIZING, and FINISHED.

  • Lines 15-31 are about ScheduleJobAndCheckResult, the procedure notifyClientWithResults sends two times a result back from AIMMS.

  • Lines 33-36 show that the data for an AIMMS Parameter is prepared/passed to AIMMS.

  • Lines 37-53 shows another procedure proc_AdvancedInteraction that acts on the interaction with AIMMS.

  • Line 55 logs that via notifyClientWithProgress a stopExecution event is sent to AIMMS to stop the execution.

  • Lines 56-84 show how this abnormal termination is handled step by step.

Further Reading

See also the manual on PRO API.