1) About JMX Subsystem of WildFly (configuration) https://docs.jboss.org/author/display/WFLY10/JMX+subsystem+configuration Remember service url from "jmx.service.url" 2) About Zabbix Java Gateway Java Gateway documentation: https://www.zabbix.com/documentation/3.0/manual/concepts/java Download section is 5.1.1. We should download latest stable version. For example, 3.0.4. We should use archive without postfix. For example, zabbix-3.0.4.tar.gz 3) Extract files from archive and go to this folder. Find JMX Discovery class: zabbix_java\src\com\zabbix\gateway\JMXItemChecker.java Open this file for edit. 4) Add support of setting JMX Servicy type by property file: [1] Replace line "url = new JMXServiceURL....." in the constructor by: String formattedJmxURL = String.format(getJMXServiceType(), conn, port); try{ url = new JMXServiceURL(formattedJmxURL); }catch(MalformedURLException exception){ throw new ZabbixException("Bad URL:'" + formattedJmxURL + "'",exception); } [2] Add method for getting property from file: /** [2] Get Properties from property file */ public static String getJMXServiceType(){ Properties prop = new Properties(); InputStream inputStream = JMXItemChecker.class.getResourceAsStream("/conf.properties"); if (inputStream != null) { try{ prop.load(inputStream); }catch(IOException e){ e.printStackTrace(); } } return prop.getProperty("format"); } Add property file "zabbix_java\src\conf.properties" with property "format": Standart format: service:jmx:rmi:///jndi/rmi://[%s]:%s/jmxrmi JBOSS/WILDFLY format: service:jmx:http-remoting-jmx://%s:%s (old version) or put it from official WildFly documentation (from Paragraph 1 of this tutorial). [3] Add Import statements: // [3] Add import statements import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.util.Properties; 5) Add support of key filter in jmx.discovery mode: ---> Đ•dit "getStringValue" method in "else if (item.getKeyId().equals("jmx.discovery"))" branch: [4] Edit throw exception declaration: //if (0 != item.getArgumentCount()) // throw new ZabbixException("required key format: jmx.discovery"); // [4] Replace argument check if (item.getArgumentCount() > 1) { throw new ZabbixException("required key format: jmx.discovery or jmx.discovery[]"); } // [5] Add if statement before "for" cycle: if (item.getArgumentCount() == 0) { for (ObjectName name : mbsc.queryNames(null, null)) // [6] Add else branch for if statement: }else{ //[6] Add else branch String objNameWildcard = item.getArgument(1); logger.trace("performing wildcard lookup against '{}'", objNameWildcard); Set objectNames = mbsc.queryNames(new ObjectName(objNameWildcard), null); logger.trace("wildcard output: {}", Arrays.toString(objectNames.toArray())); buildDiscoveryOutput(counters, objectNames); } ---> Edit "getPrimitiveAttributeValue" method [7] Modify "if (fieldNames.equals(""))" check: if (fieldNames.equals("")) { //[7] Modify if statement if (isPrimitiveAttributeType(dataObject.getClass())) { return dataObject.toString(); } else if (dataObject instanceof Number) { return dataObject.toString(); } else { throw new ZabbixException("data object type is not primitive: %s", dataObject.getClass()); } } [8] Modify if statement after "fieldNames.equals" check: //[8] Modify if statement: "if (dataObject instanceof CompositeData)" if (dataObject instanceof CompositeData || dataObject instanceof Map) { [9] Delete CompositeData declaration: //[9] Delete this: CompositeData comp = (CompositeData)dataObject; [10] Add prepare block before return statement: //[10] Prepare for return Object data = null; if (dataObject instanceof CompositeData) { data = ((CompositeData) dataObject).get(dataObjectName); } else { data = ((Map) dataObject).get(dataObjectName); } [11] Change return statement: //[11] Change return statement: return getPrimitiveAttributeValue(comp.get(dataObjectName), newFieldNames); return getPrimitiveAttributeValue(data, newFieldNames); [12] Add new method: //[12] Added method from: https://support.zabbix.com/browse/ZBXNEXT-3509 private void buildDiscoveryOutput(JSONArray counters, Set objectNames) throws JSONException { for (ObjectName objName : objectNames) { // Add the full JMX Object Name as a macro // in the return string JSONObject taskObj = new JSONObject(); logger.trace("building discovery output for object '{}'", objName.getCanonicalName()); taskObj.put("{#JMXOBJ}", objName.getCanonicalName()); // Add each property of the Object Name as returned macros Hashtable props = objName.getKeyPropertyList(); for (Map.Entry propEntry : props.entrySet()) { taskObj.put(String.format("{#%s}", propEntry.getKey().toUpperCase()), propEntry.getValue()); } counters.put(taskObj); } } 6) Compile of JMXItemCheck: - Go to the zabbix_java root folder - create empty folder. For example: jmx - Execute: javac -d "./jmx" -classpath "./lib/*" src/com/zabbix/gateway/*.java - Delete all files from jmx, which should not be replaced in original java gateway jar. - Copy original java gateway jar in the zabbix_java root folder - Execute: jar uf zabbix-java-gateway-3.0.4.jar -C jmx . - Execute: jar uf zabbix-java-gateway-3.0.4.jar conf.properties - Check result: jar tvf zabbix-java-gateway-3.0.4.jar [Done]