{"id":18026,"date":"2026-04-24T15:22:09","date_gmt":"2026-04-24T13:22:09","guid":{"rendered":"https:\/\/www.mjr.gmbh\/?p=18026"},"modified":"2026-04-29T14:02:41","modified_gmt":"2026-04-29T12:02:41","slug":"ibm-i-and-xa-license-check","status":"publish","type":"post","link":"https:\/\/www.mjr.gmbh\/en\/infor-erp-xa\/infor-erp-xa-technology\/ibm-i-and-xa-license-check\/","title":{"rendered":"IBM i and XA license check"},"content":{"rendered":"<h2>The challenge<\/h2>\n<p>You want to check how many users are using a license of your IBM I product and especially Infor XA? And see also the users? This is how it works with a short and simple Java program.<\/p>\n<p>The key to achieve that, is to use the IBM i API QLZARTV which delivers all needed information.<\/p>\n<p>Please note: this is just a example and comes without any warranty<\/p>\n<h2>Result of the check<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-18029\" src=\"https:\/\/www.mjr.gmbh\/wp-content\/uploads\/mjr_ibmi_license_check.png\" alt=\"mjr_ibmi_license_check \" width=\"409\" height=\"277\" srcset=\"https:\/\/www.mjr.gmbh\/wp-content\/uploads\/mjr_ibmi_license_check.png 409w, https:\/\/www.mjr.gmbh\/wp-content\/uploads\/mjr_ibmi_license_check-300x203.png 300w, https:\/\/www.mjr.gmbh\/wp-content\/uploads\/mjr_ibmi_license_check-97x66.png 97w\" sizes=\"auto, (max-width: 409px) 100vw, 409px\" \/><\/p>\n<p>Here is the Java code.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">\/\/ LicenseCheck.java by MJR GmbH, Knittlingen, Germany\r\n\/\/ \r\n\/\/Sample code to read license usage of IBM i\r\n\/\/\r\n\/\/ by Demian Welker and Michael Raber (kindly supported by ChatGPT ;-)\r\n\/\/ \r\n\/\/ copy this file as LicenseCheck.java in your IFS folder and call the compile-and-start.sh script locally on IBM i from the same folder\r\n\r\nimport com.ibm.as400.access.*;\r\nimport java.nio.ByteBuffer;\r\nimport java.nio.charset.Charset;\r\nimport java.util.Arrays;\r\n\r\npublic class LicenseUsers {\r\n    static final Charset EBCDIC = Charset.forName(\"Cp037\");\r\n\r\n    public static void main(String[] args) throws Exception {\r\n        System.out.println(\"Starting LicenseUsers...\");\r\n\r\n        if (args.length &lt; 1) {\r\n            System.out.println(\"Usage: java LicenseUsers &lt;productId7&gt; [release6|*ONLY] [feature4]\");\r\n            System.out.println(\"Example: java LicenseUsers 5U33M7X V3R1M0 5001 for XA R11\");\r\n            return;\r\n        }\r\n\r\n        String productId = pad(args[0], 7);\r\n        String release   = pad(args.length &gt; 1 ? args[1] : \"*ONLY\", 6);\r\n        String feature   = pad(args.length &gt; 2 ? args[2] : \"5001\", 4);\r\n\r\n        AS400 as400 = new AS400(\"localhost\");\r\n\r\n        byte[] receiver = callQLZARTV(as400, 8192, productId, release, feature);\r\n        int bytesAvail = bin4(receiver, 4);\r\n\r\n        if (bytesAvail &gt; receiver.length) {\r\n            receiver = callQLZARTV(as400, bytesAvail, productId, release, feature);\r\n        }\r\n\r\n        printResult(receiver);\r\n        as400.disconnectAllServices();\r\n    }\r\n\r\n    static byte[] callQLZARTV(AS400 as400, int receiverLength,\r\n                              String productId, String release, String feature) throws Exception {\r\n\r\n        ProgramCall pc = new ProgramCall(as400);\r\n        pc.setProgram(\"\/QSYS.LIB\/QLZARTV.PGM\");\r\n\r\n        byte[] receiver = new byte[receiverLength];\r\n\r\n        byte[] productIdent = ebcdic(productId + release + feature); \/\/ LICP0100 = 17 bytes\r\n\r\n        byte[] errorCode = new byte[272];\r\n        putBin4(errorCode, 0, errorCode.length); \/\/ bytes provided\r\n        putBin4(errorCode, 4, 0);                \/\/ bytes available\r\n\r\n        ProgramParameter[] parms = new ProgramParameter[] {\r\n            new ProgramParameter(receiverLength),          \/\/ receiver variable\r\n            new ProgramParameter(bin4(receiverLength)),    \/\/ receiver length\r\n            new ProgramParameter(ebcdic(pad(\"LICR0300\", 8))),\r\n            new ProgramParameter(productIdent),\r\n            new ProgramParameter(ebcdic(pad(\"LICP0100\", 8))),\r\n            new ProgramParameter(errorCode, errorCode.length)\r\n        };\r\n\r\n        pc.setParameterList(parms);\r\n\r\n        if (!pc.run()) {\r\n            for (AS400Message m : pc.getMessageList()) {\r\n                System.err.println(m.getID() + \" \" + m.getText());\r\n            }\r\n            throw new RuntimeException(\"QLZARTV failed\");\r\n        }\r\n\r\n        byte[] errOut = parms[5].getOutputData();\r\n        int errAvail = bin4(errOut, 4);\r\n        if (errAvail &gt; 0) {\r\n            String msgId = text(errOut, 8, 7);\r\n            throw new RuntimeException(\"QLZARTV API error: \" + msgId);\r\n        }\r\n\r\n        return parms[0].getOutputData();\r\n    }\r\n\r\n    static void printResult(byte[] r) {\r\n        int bytesReturned = bin4(r, 0);\r\n        int bytesAvailable = bin4(r, 4);\r\n        int usageLimit = bin4(r, 8);\r\n        int usageCount = bin4(r, 12);\r\n        String usageType = text(r, 16, 2);\r\n        String complianceType = text(r, 18, 2);\r\n        String licenseTerm = text(r, 20, 6);\r\n        String releaseLevel = text(r, 26, 6);\r\n        int peakUsage = bin4(r, 52);\r\n\r\n        int userOffset = bin4(r, 96);\r\n        int userCount = bin4(r, 100);\r\n        int userRecordLength = bin4(r, 104);\r\n        int licenseUserLength = bin4(r, 108);\r\n\r\n        System.out.println(\"Release level : \" + releaseLevel);\r\n        System.out.println(\"License term  : \" + licenseTerm);\r\n        System.out.println(\"Usage limit   : \" + usageLimit);\r\n        System.out.println(\"Usage count   : \" + usageCount);\r\n        System.out.println(\"Peak usage    : \" + peakUsage);\r\n        System.out.println(\"Usage type    : \" + usageType);\r\n        System.out.println(\"Compliance    : \" + complianceType);\r\n        System.out.println(\"Users         : \" + userCount);\r\n        System.out.println();\r\n\r\n        if (userOffset == 0 || userCount == 0) {\r\n            System.out.println(\"No current license users found.\");\r\n            return;\r\n        }\r\n\r\n        System.out.printf(\"%-6s %s%n\", \"Uses\", \"License user\");\r\n        System.out.println(\"------------------------------\");\r\n\r\n        for (int i = 0; i &lt; userCount; i++) {\r\n            int pos = userOffset + (i * userRecordLength);\r\n            if (pos + 4 &gt; bytesReturned) break;\r\n\r\n            int usesHeld = bin4(r, pos);\r\n            String licenseUser = text(r, pos + 4, licenseUserLength);\r\n\r\n            System.out.printf(\"%-6d %s%n\", usesHeld, licenseUser);\r\n        }\r\n\r\n        if (bytesAvailable &gt; bytesReturned) {\r\n            System.out.println();\r\n            System.out.println(\"Warning: receiver was too small; not all data returned.\");\r\n        }\r\n    }\r\n\r\n    static byte[] ebcdic(String s) {\r\n        return s.getBytes(EBCDIC);\r\n    }\r\n\r\n    static String text(byte[] b, int off, int len) {\r\n        return new String(Arrays.copyOfRange(b, off, off + len), EBCDIC).trim();\r\n    }\r\n\r\n    static String pad(String s, int len) {\r\n        if (s.length() &gt; len) return s.substring(0, len);\r\n        return String.format(\"%-\" + len + \"s\", s);\r\n    }\r\n\r\n    static byte[] bin4(int value) {\r\n        return ByteBuffer.allocate(4).putInt(value).array();\r\n    }\r\n\r\n    static void putBin4(byte[] b, int off, int value) {\r\n        byte[] x = bin4(value);\r\n        System.arraycopy(x, 0, b, off, 4);\r\n    }\r\n\r\n    static int bin4(byte[] b, int off) {\r\n        return ByteBuffer.wrap(b, off, 4).getInt();\r\n    }\r\n}<\/pre>\n<p>and the script to compile and start:<\/p>\n<p>First line is calling the Java compiler and then in the second line the compiled program. This is a generic description to allow simply to copy and run on the IBM I without deep skills in Java on i. Of course you can use any IDE like IntelliJ, VSCode, Eclipse or whatever to build and run.<\/p>\n<p>The parameters are<\/p>\n<ul>\n<li>5U33M7X as the product code of Infor XA. This can be different, depending on your license.<\/li>\n<li>V3R1M0 stands for Release 11. If you are running XAR10 please use V3R0M0 or V2R9M0 for XAR9<\/li>\n<li>5001 is the feature code of XA (main application)<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\"># compile and call the Java program\r\n# put this script in the folder where the java source code is located\r\n# replace the parameters of the second line as needed for your XA version\r\n\r\njavac -cp \/QIBM\/ProdData\/HTTP\/Public\/jt400\/lib\/jt400.jar LicenseUsers.java\r\njava -cp .:\/QIBM\/ProdData\/HTTP\/Public\/jt400\/lib\/jt400.jar LicenseUsers 5U33M7X V3R1M0 5001\r\n<\/pre>\n<div class=\"wpb_text_column\"><div class=\"wpb_wrapper\"><div class=\"w-iconbox us_custom_9a361e25 iconpos_top style_default color_primary align_center\"><div class=\"w-iconbox-icon\" style=\"font-size:2rem;\"><i class=\"fas fa-lightbulb\"><\/i><\/div><div class=\"w-iconbox-meta\"><h4 class=\"w-iconbox-title\">You have any questions?<\/h4><div class=\"w-iconbox-text\"><p><span style=\"font-size: 18pt;\">Just contact us!<\/span><\/p>\n<div class=\"w-btn-wrapper align_center\"><a class=\"w-btn us-btn-style_1 us_custom_3e336cc9 icon_atleft\" title=\"Kontakt\" href=\"https:\/\/mjr.gmbh\/en\/contact\/\/\"><i class=\"fas fa-bullhorn\"><\/i><span class=\"w-btn-label\">We can talk about your ideas and solutions!<\/span><\/a><\/div>\n<\/div><\/div><\/div>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>The challenge You want to check how many users are using a license of your IBM I product and especially Infor XA? And see also the users? This is how it works with a short and simple Java program. The key to achieve that, is to use the IBM i API QLZARTV which delivers all&#8230;<\/p>\n","protected":false},"author":18,"featured_media":18042,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[38],"tags":[],"tutorial_kategorie":[],"class_list":["post-18026","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-infor-erp-xa-technology"],"acf":[],"views":5743,"_links":{"self":[{"href":"https:\/\/www.mjr.gmbh\/en\/wp-json\/wp\/v2\/posts\/18026","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mjr.gmbh\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mjr.gmbh\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mjr.gmbh\/en\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mjr.gmbh\/en\/wp-json\/wp\/v2\/comments?post=18026"}],"version-history":[{"count":0,"href":"https:\/\/www.mjr.gmbh\/en\/wp-json\/wp\/v2\/posts\/18026\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mjr.gmbh\/en\/wp-json\/wp\/v2\/media\/18042"}],"wp:attachment":[{"href":"https:\/\/www.mjr.gmbh\/en\/wp-json\/wp\/v2\/media?parent=18026"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mjr.gmbh\/en\/wp-json\/wp\/v2\/categories?post=18026"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mjr.gmbh\/en\/wp-json\/wp\/v2\/tags?post=18026"},{"taxonomy":"tutorial_kategorie","embeddable":true,"href":"https:\/\/www.mjr.gmbh\/en\/wp-json\/wp\/v2\/tutorial_kategorie?post=18026"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}