…thoughts on ServiceNow and digital transformation

Post

Building a .jar file to run on the ServiceNow MID Server


John Andersen has a great video on running a jar file from the ServiceNow MID server. The below are my notes from following John’s video to do this myself. It includes steps for setting up the Java development environment.

  1. Install the Java SDK
  2. Create an environment variable called JAVA_HOME and point it to the java executable
  3. In VS Code install Extension Pack for Java
  4. Install Maven by downloading the zip file, extracting (to Program Files) and then adding the bin directory to the Path environment variable
  5. In VS Code Command Palette, do Java: Create Java Project
  6. Select Maven
  7. Select maven-archetype-quickstart
  8. Select the latest version
  9. For the group Id make it com.somethingunique here (your domain name for example)
  10. For the artifact Id, type the name of the project
  11. Choose a folder where the app will be scaffolded
  12. The scaffolding progress will be shown in the terminal
  13. When it asks for a version, type 1

14. Confirm the properties by pressing Enter

15. You should see Build Success if all goes well

16. Open the folder you created the app in in VS Code.

  • The App.java file under src\main\java\com\incidentdo (or whatever your group Id is) contains the code for the app.
  • The pom.xml contains the configuration for the build.

17. If you use libraries outside the standard java libraries, add them to dependencies block of the pom.xml file. For example, the pdfbox library is added below.

    <dependency>
     <groupId>org.apache.pdfbox</groupId>
     <artifactId>pdfbox</artifactId>
     <version>2.0.24</version>
    </dependency>

18. If you use other libraries, the jar file should contain all the dependencies. To build a jar file with dependencies, add the maven-assembly-plugin as below to the plugins block of the pom.xml.

        <plugin>
          <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
              <archive>
                <manifest>
                  <mainClass>com.nuaxis.MergePDFs</mainClass>
                </manifest>
              </archive>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
            </configuration>
            <executions>
              <execution>
                <id>make-assembly</id> <!-- this is used for inheritance merges -->
                <phase>package</phase> <!-- bind to the packaging phase -->
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
        </plugin>

19. In the pom.xml file, edit the maven.compiler.source and maven.compiler.target properties to match the version of java in your development environment. You can find the version of java by running the below in a command prompt


java -version

In the pom.xml file

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>22</maven.compiler.source>
    <maven.compiler.target>22</maven.compiler.target>
  </properties>

19. Compile the application using the below command. Note that you have to be in the same directory as the pom.xml

mvn clean compile assembly:single

20. Then package the app

mvn package

a .jar file should be created in the “target” directory with all dependencies.

21. On the instance, go to the JAR files module and add a new record. The name doesn’t matter. Upload the jar file into the record. The file will sync to the extlib folder of the MID server. Note that it can take a minute or two to sync.

22. In a background script, run the below to create a new record in the ecc_queue table. Note this script calls the .jar file from a command prompt. You should be able to call the new java class directly, however I was unable to get this working. See the section at the end of this article for more details.

    var ecc = new GlideRecord("ecc_queue");
    ecc.initialize();
    ecc.agent = 'mid.server.michael_test'; //mid server name
    ecc.topic = "Command";
    var value = 'java -cp .\\extlib\\demo-1-jar-with-dependencies.jar com.incidentdo.App'; //name of jar file and name of class
    ecc.payload = '<?xml version="1.0" encoding="UTF-8"?><parameters><parameter name="name" value="' + value + '"/><parameter name="skip_sensor" value="true"/></parameters>';
    ecc.queue = "output";
    ecc.state = "ready";
    ecc.name = "jar file test";
    ecc.insert();

This creates a record in the ecc_queue table like the below

23. After a few seconds, the response will come back from the MID Server with a payload like the below. The stdout node should show “Hello World!”

<?xml version="1.0" encoding="UTF-8"?><results probe_time="2368"><result command="java -cp .\extlib\demo-1-jar-with-dependencies.jar com.incidentdo.App"><stdout>Hello World!</stdout><stderr/></result><parameters><parameter name="agent" value="mid.server.michael_test"/><parameter name="signature" value=""/><parameter name="response_to" value=""/><parameter name="from_sys_id" value=""/><parameter name="source" value=""/><parameter name="priority" value="2"/><parameter name="agent_correlator" value=""/><parameter name="skip_sensor" value="true"/><parameter name="processed" value=""/><parameter name="error_string" value=""/><parameter name="sys_id" value="10d2b0941bbe5250ce0a6205604bcb21"/><parameter name="sequence" value="19403aaea2d0000001"/><parameter name="from_host" value=""/><parameter name="sys_created_on" value="2024-12-26 15:52:00"/><parameter name="sys_domain" value="global"/><parameter name="name" value="java -cp .\extlib\demo-1-jar-with-dependencies.jar com.incidentdo.App"/><parameter name="topic" value="Command"/><parameter name="state" value="ready"/><parameter name="queue" value="output"/><parameter name="ecc_queue" value="10d2b0941bbe5250ce0a6205604bcb21"/></parameters></results>

Calling the java class directly instead of running from a command prompt

Both this John Andersen video and some posts in the community demonstrate how the class inside the jar file can be called directly instead of calling it from the command prompt. However, I was not able to get this working. Below are the steps I took with the results.

Run the below in a background script

var probe = new JavascriptProbe("michael_test");
probe.setName("jarfile test");
probe.setJavascript("var test = new Packages.com.incidentdo.App(); test.main();");
probe.create();

This produces a record in the ecc_queue table:

However, this produces the error

Evaluation error: Caused by error in JavaScript probe 'jarfile test' at line 1

==&gt;   1: var test = new Packages.com.incidentdo.App(); test.main();

Helpful Community posts:

https://www.servicenow.com/community/now-platform-forum/mid-server-script-include-expect-custom-java-package-call/m-p/1202885

https://www.servicenow.com/community/developer-forum/how-to-use-custom-jar-mid-server-packages/m-p/1393636/page/3