{"id":21177613,"url":"https://github.com/tersesystems/jmxbuilder","last_synced_at":"2025-10-04T15:45:46.282Z","repository":{"id":36751013,"uuid":"229106896","full_name":"tersesystems/jmxbuilder","owner":"tersesystems","description":"Fluent API for building JMX Beans","archived":false,"fork":false,"pushed_at":"2024-12-04T00:49:52.000Z","size":691,"stargazers_count":9,"open_issues_count":0,"forks_count":5,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-10T00:38:40.607Z","etag":null,"topics":["java","jmx"],"latest_commit_sha":null,"homepage":"https://tersesystems.com/blog/2019/12/24/controlling-logging-in-a-running-jvm/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tersesystems.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-12-19T17:33:45.000Z","updated_at":"2024-12-04T00:49:54.000Z","dependencies_parsed_at":"2024-12-03T01:29:46.471Z","dependency_job_id":"6849003a-66e0-47f7-ab8e-f13a347a2060","html_url":"https://github.com/tersesystems/jmxbuilder","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/tersesystems/jmxbuilder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tersesystems%2Fjmxbuilder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tersesystems%2Fjmxbuilder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tersesystems%2Fjmxbuilder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tersesystems%2Fjmxbuilder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tersesystems","download_url":"https://codeload.github.com/tersesystems/jmxbuilder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tersesystems%2Fjmxbuilder/sbom","scorecard":{"id":874844,"data":{"date":"2025-08-11","repo":{"name":"github.com/tersesystems/jmxbuilder","commit":"4d20e841af8f5c6b6e39a385de61faba4cbb63dc"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.6,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/workflow.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 2/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":9,"reason":"binaries present in source code","details":["Warn: binary detected: gradle/wrapper/gradle-wrapper.jar:1"],"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/workflow.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/tersesystems/jmxbuilder/workflow.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/workflow.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/tersesystems/jmxbuilder/workflow.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/workflow.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/tersesystems/jmxbuilder/workflow.yml/main?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":3,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Info: 'branch protection settings apply to administrators' is required to merge on branch 'main'","Warn: could not determine whether codeowners review is allowed","Warn: no status checks found to merge onto branch 'main'","Warn: PRs are not required to make changes on branch 'main'; or we don't have data to detect it.If you think it might be the latter, make sure to run Scorecard with a PAT or use Repo Rules (that are always public) instead of Branch Protection settings"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 17 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-24T05:35:29.463Z","repository_id":36751013,"created_at":"2025-08-24T05:35:29.464Z","updated_at":"2025-08-24T05:35:29.464Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278335451,"owners_count":25970113,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-04T02:00:05.491Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","jmx"],"created_at":"2024-11-20T17:16:36.630Z","updated_at":"2025-10-04T15:45:46.246Z","avatar_url":"https://github.com/tersesystems.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JMXBuilder\n\n\u003c!---freshmark shields\noutput = [\n\tlink(shield('Maven central', 'mavencentral', '{{group}}:{{artifactIdMaven}}', 'blue'), 'https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22{{group}}%22%20AND%20a%3A%22{{artifactIdMaven}}%22'),\n\tlink(shield('License Apache2', 'license', 'Apache2', 'blue'), 'https://www.tldrlegal.com/l/apache2'),\n\t'',\n\tlink(image('Travis CI', 'https://travis-ci.org/tersesystems/jmxbuilder.svg?branch=master'), 'https://travis-ci.org/tersesystems/jmxbuilder')\n\t].join('\\n')\n--\u003e\n[![Maven central](https://img.shields.io/badge/mavencentral-com.tersesystems.jmxbuilder%3Ajmxbuilder-blue.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.tersesystems.jmxbuilder%22%20AND%20a%3A%22jmxbuilder%22)\n[![License Apache2](https://img.shields.io/badge/license-Apache2-blue.svg)](https://www.tldrlegal.com/l/apache2)\n\n[![Travis CI](https://travis-ci.org/tersesystems/jmxbuilder.svg?branch=master)](https://travis-ci.org/tersesystems/jmxbuilder)\n\u003c!---freshmark /shields --\u003e\n\nJMXBuilder is a library that creates [Dynamic MBeans](https://docs.oracle.com/javase/8/docs/api/javax/management/DynamicMBean.html) from a set of attributes and operations, provided by functions.  \n\nJMXBuilder is intended to help provide an admin interface for applications by exposing components in the most minimal way possible. \n\nJMXBuilder does not require you to understand the hairy internals of JMX.  It uses the [MXBean](https://docs.oracle.com/javase/8/docs/api/javax/management/MXBean.html) open type mappings, together with [CompositeData](https://docs.oracle.com/javase/8/docs/api/javax/management/openmbean/CompositeData.html) and [TabularData](https://docs.oracle.com/javase/8/docs/api/javax/management/openmbean/TabularData.html).  Roughly, the MXBean style exposes a \"JSON style\" for exposing information, where you keep things to strings, numbers, and booleans, and then composites are sub objects and tablular data are arrays.\n \nIf you are running on your laptop, then I like using [Zulu Mission Control](https://www.azul.com/products/zulu-mission-control/).\n\nYou should not use JMX Remoting, aka JSR-160, in production.  It uses Java serialization over RMI, which is fiddly to set up in production and exposes the server [Java Serialization attacks](https://tersesystems.com/2015/11/08/closing-the-open-door-of-java-object-serialization/).  JSR-160 is much slower than JSON over HTTPS.  It does not cover user authentication (TLS client authentication only covers the channel), or deal with fine grained authorization.  And it's also harder for non-Java based tools to integrate with.\n \nIf you want to use JMX remotely, you should use [Jolokia](https://jolokia.org/) as an agent to expose JMX over HTTP with the [appropriate authentication and authorization](https://jolokia.org/reference/html/security.html) and [Hawt.io](http://hawt.io/) to view it using an HTML GUI.  Making a [JAAS module](https://docs.oracle.com/javase/10/security/jaas-authorization-tutorial.htm#JSSEC-GUID-D43CF965-8A5F-4A23-A2AF-F41DD5F8B411) is pretty easy, and the Jolokia manual is comprehensive.\n\nIf you want to use JMX to pull out metrics from the JVM, then [JMXTrans](https://www.jmxtrans.org/) or the [Prometheus JMX Exporter](https://github.com/prometheus/jmx_exporter) may be a good fit.  Alternately, you can pull the information that the JVM exposes through the system mbeans through [Yammer Metrics JVM instrumentation](https://metrics.dropwizard.io/4.1.2/manual/jvm.html) and then send that through one of the reporters there.\n\nIf you are happy with Java annotations, I recommend [JMXWrapper](https://github.com/uklimaschewski/JMXWrapper) as a similar \"no JMX manual required\" solution.  JMXBuilder can also be used alongside JMXWrapper if that works better for you.\n\n## Attributes\n\nLet's start with a simple example where we want to create a user object and expose that through JMX.  The user will have a name, an age, and an address, but we'll only expose the name and age here.\n\nUsing JMXBuilder, we can provide that with the following code:\n\n```java\nclass UserExample {\n    static final MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();\n\n    public static void registerUser() throws Exception {\n        Address address = new Address(\"street1\", \"city\", \"state\");\n        final User user = new User(\"name\", 12, address);\n\n        final DynamicMBean userBean = DynamicBean.builder()\n                .withSimpleAttribute(String.class, \"name\", user::getName, user::setName)\n                .withSimpleAttribute(Integer.TYPE, \"age\", user::getAge, user::setAge)\n                .build();\n\n        ObjectName objectName = new ObjectName(\"com.tersesystems.jmxbuilder:type=UserBean,name=User\");\n        mBeanServer.registerMBean(userBean, objectName);\n    }\n}\n```\n\nThis will provide something that looks like this:\n\n![screenshot.png](docs/screenshot.png)\n\n\n\u003e **NOTE**: JMXBuilder will attempt to infer the type when setting operations if it is not provided, but JMX has issues with primitive types.  Specify the type explicitly and use the `TYPE` field to be safe.\n\nIf you want to use javabeans, then you should use the `withBeanAttribute` property:\n\n```java\npublic class DebugEnabledClass {\n    private boolean debug;\n\n    public boolean isDebugEnabled() {\n        return debug;\n    }\n\n    public void setDebugEnabled(boolean debug) {\n        this.debug = debug;\n    }\n}\n\nDebugEnabledClass debugEnabledClass = new DebugEnabledClass();\nfinal DynamicMBean serviceBean = DynamicBean.builder()\n        .withBeanAttribute(Boolean.TYPE, \"debugAttributeName\", debugEnabledClass, \"debugEnabled\")\n        .build();\n```\n\n## Composites\n\nYou can also specify composite data more generally and build up a mapping of data, exposing the user and the address by using a `CompositeDataWriter` to expose `User` and `Address` information in a nested \"tree\" interface.\n\n```java\npublic class CompositeExample {\n\n    static final CompositeDataWriter\u003cAddress\u003e addressWriter = CompositeDataWriter.builder(Address.class)\n            .withTypeName(\"address\")\n            .withTypeDescription(\"Address\")\n            .withSimpleAttribute(String.class, \"street1\", \"Street 1\", Address::getStreet1)\n            .withSimpleAttribute(\"city\", Address::getCity)\n            .withSimpleAttribute(\"state\", Address::getState)\n            .build();\n\n    static final CompositeDataWriter\u003cUser\u003e userWriter = CompositeDataWriter.builder(User.class)\n            .withTypeName(\"user\")\n            .withTypeDescription(\"User\")\n            .withSimpleAttribute(\"name\", User::getName)\n            .withSimpleAttribute(\"age\", User::getAge)\n            .withCompositeAttribute(\"address\", user -\u003e user.getAddress(), addressWriter).build();\n\n    public static void compositeBean() throws Exception {\n        final Address address = new Address(\"street1\", \"city\", \"state\");\n        final User user = new User(\"name\", 12, address);\n        final DynamicMBean userBean = DynamicBean.builder()\n                .withCompositeAttribute(\"User\", () -\u003e user, userWriter)\n                .build();\n\n        ObjectName objectName = new ObjectName(\"com.tersesystems:type=DynamicBean,name=CompositeBean\");\n        mBeanServer.registerMBean(userBean, objectName);\n\n        final CompositeData userItem = (CompositeData) mBeanServer.getAttribute(objectName, \"User\");\n        printUser(userItem);\n    }\n\n}\n```\n\n![composite.png](docs/composite.png)\n\n## Tables\n\nWe can also do lists of users, using the same writers we defined earlier and mapping them to an `Iterable\u003cUser\u003e`, using the `TabularDataWriter`:\n\n```java\npublic class TabularExample {\n    // ... composite writers as above\n\n    static final TabularDataWriter\u003cUser\u003e usersWriter = TabularDataWriter.builder(User.class)\n            .withTypeName(\"users\")\n            .withTypeDescription(\"Users\")\n            .withIndexName(\"name\")\n            .withCompositeDataWriter(userWriter)\n            .build();\n\n    public static void tabularBean() throws Exception {\n        final Address address = new Address(\"street1\", \"city\", \"state\");\n        final List\u003cUser\u003e usersList = Collections.singletonList(new User(\"name\", 12, address));\n\n        final DynamicMBean usersBean = DynamicBean.builder()\n                .withTabularAttribute(\"Users\", () -\u003e usersList, usersWriter)\n                .build();\n\n        ObjectName objectName = new ObjectName(\"com.tersesystems:type=DynamicBean,name=TabularBean\");\n        mBeanServer.registerMBean(usersBean, objectName);\n\n        final TabularData users = (TabularData) mBeanServer.getAttribute(objectName, \"Users\");\n        for (Object row : users.values()) {\n            printUser((CompositeData) row);\n        }\n    }\n}\n```\n\nWhich looks like this:\n\n![tabular.png](docs/tabular.png)\n\n## Operations\n\nYou can also provide [operations](https://docs.oracle.com/javase/8/docs/api/javax/management/MBeanOperationInfo.html) to a builder, which is useful for services.  You can specify by passing in the function:\n\n```java\nclass ExampleService {\n    private boolean debug;\n\n    String dump() {\n        return (\"Dumping contents\");\n    }\n}\n\npublic class DumpExample {\n    public void exposeDump(Service service) {\n        static final MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();\n        final DynamicMBean serviceBean = DynamicBean.builder()\n                .withOperation(\"dump\", service::dump)\n                .build();\n        // ...\n    }\n}\n```\n\nOr you can use reflection and just pass in the object you want the operation called on.\n\n```java\npublic class DebugExample {\n    public void exposeDebugOperations(Service service) {\n        ParameterInfo paramInfo = ...;\n        final DynamicMBean debugBean = DynamicBean.builder()\n                .withOperation(\"turnOnDebugForMinutes\", service, \"timedDebug\", paramInfo)\n                .build();\n        // ...\n    }   \n\n}\n```\n\n## Some Caveats\n\nJMX does not have great performance or resolution, so you should not use this to render 100K of data or poll for data repeatedly.\n\nThe platform MBeanServer is tied to the lifecycle of the JVM itself.  If you are running applications with a different lifecycle, i.e. a Java EE app that may reload its classloader, then you are responsible for unregistering the MBean in an application shutdown hook.\n\nJMX does not have any knowledge of thread safety, and doesn't provide any kind of protection for multiple clients calling operations concurrently.  \n\nAgain, do not use JMX-160 aka Java Remoting, as it is slow, fiddly, and [insecure](https://tersesystems.com/2015/11/08/closing-the-open-door-of-java-object-serialization/).\n\n## Internals\n\nInternally, the DynamicBean builder assembles a DynamicBean, using Open MBean type data in much the same way as an [MXBean](https://docs.oracle.com/javase/8/docs/api/javax/management/MXBean.html).   This is the same approach taken by [JMXWrapper.java](https://github.com/uklimaschewski/JMXWrapper/blob/master/src/com/udojava/jmx/wrapper/JMXBeanWrapper.java).\n\nThe DynamicBean consists of attributes, operations, and notifications which are put together from Info objects.  Each of these has their own builder APIs, i.e. `AttributeInfo` is created from `AttributeInfo.builder()`.  This allows for filling out details like the description and the descriptor, which aren't available from the default API.\n\nOpenMBean API has some issues, because it doesn't handle primitive types like `int` or `boolean`.  To correct this, the `MBeanInfo` returned is not an `OpenMBeanInfo` and there is some special case handling..  From the [MBeanInfo contents for an MXBean section](https://docs.oracle.com/javase/8/docs/api/javax/management/MXBean.html): \n\n\u003e An MXBean is a type of Open MBean. However, for compatibility reasons, its MBeanInfo is not an OpenMBeanInfo. In particular, when the type of an attribute, parameter, or operation return value is a primitive type such as int, or is void (for a return type), then the attribute, parameter, or operation will be represented respectively by an MBeanAttributeInfo, MBeanParameterInfo, or MBeanOperationInfo whose getType() or getReturnType() returns the primitive name (\"int\" etc). This is so even though the mapping rules above specify that the opendata mapping is the wrapped type (Integer etc).\n.\n\u003e\n\u003e The Descriptor for all of the MBeanAttributeInfo, MBeanParameterInfo, and MBeanOperationInfo objects contained in the MBeanInfo will have a field openType whose value is the OpenType specified by the mapping rules above. So even when getType() is \"int\", getDescriptor().getField(\"openType\") will be SimpleType.INTEGER.\n\u003e \n\u003e The Descriptor for each of these objects will also have a field originalType that is a string representing the Java type that appeared in the MXBean interface. The format of this string is described in the section Type Names below.\n\u003e\n\u003e The Descriptor for the MBeanInfo will have a field mxbean whose value is the string \"true\".\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftersesystems%2Fjmxbuilder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftersesystems%2Fjmxbuilder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftersesystems%2Fjmxbuilder/lists"}