[wildfly-dev] a way to obtain local ModelController within javaagent?

Jason Greene jason.greene at redhat.com
Mon Mar 13 13:51:32 EDT 2017


Thanks for the info. Sorry to be annoying and ask the same question over and over, but what is missing from the remote management protocol that WildFly already provides?  

> On Mar 13, 2017, at 12:19 PM, John Mazzitelli <mazz at redhat.com> wrote:
> 
> OK, here's the basic gist of what this is for - I'll try to keep it short.
> 
> WHAT THE AGENT DOES:
> 
> The "Hawkular WildFly Agent" looks at the tree of resources in its monitored servers (e.g. for WildFly servers, things like "/subsystem=datasources/data-source=MyH2" are resources; for JMX MBeanServers, MBeans are resources), and collects metrics from those resources. It stores that inventory and metric data to a backend Hawkular Server. Systems like ManageIQ, CloudForms, and even things like Grafana can then display in their UIs the inventory details (e.g. "here's a list of your 5 EAP servers"), and pretty graphs of all their metrics (e.g. "here's what your 5 EAP servers' heap memory usages look like").
> 
> HOW THE AGENT RUNS TODAY:
> 
> Today, Hawkular WildFly Agent MUST BE installed as a subsystem. It can be installed in EAP 6.4, EAP 7.0/7.1, and their associated WildFly versions - but it has to be hosted in one of those things because it is implemented as a subsystem extension. It can be installed in a standalone server or a host controller. It can collect inventory and metric data for the server it is running in.
> 
> WHY WE WANT TO CHANGE:
> 
> But we have received feedback that "it would be nice to support this agent in a bunch of other projects that are not EAP based." Think Karaf-based or vert-x based applications that expose inventory/metrics over JMX. We want to collect inventory and metrics from non-EAP-based products that expose JMX so ManageIQ and CloudForms can see them just like EAP-based projects can be seen today.
> 
> So I refactored the Hawkular Agent core engine so it can run EITHER as a subsystem extension OR as a VM java agent.
> 
> Then I have received feedback, "it would be nice to not have to support and maintain both versions of the agent - just support the Java Agent since it can monitor EAP and non-EAP based products. Throw away the subsystem one since it isn't needed anymore."
> 
> WHAT IS THE PROBLEM?
> 
> Right now, I have a java agent that is working well and can support both EAP and non-EAP based products. However, there are two problems:
> 
> 1) Unrelated to this email thread, but I can't run this java agent in a Host controller (that's this JIRA: https://issues.jboss.org/browse/WFCORE-2526) - the workaround for this is to run the agent in its own JVM and remotely monitor the Host Controller. Not ideal because now it has to go through the remote management endpoint. Other workaround is to rip out jboss logging entirely from my agent and use some other logging framework. But again, ignore that for now. Not relevant to this discussion.
> 
> 2) Even though the agent is running co-located inside the WildFly JVM as a javaagent, it can't get a local client so it can talk locally to it. It must go through the remote management endpoint. I would like this agent to get a local ModelController so it can build clients like it can today when running in a subsystem. The agent (when running as a subsystem) uses code similar to this:
> 
>    InjectedValue<ModelController> mcValue = new InjectedValue<>();
>   ...
>   ((ServiceBuilder) bldr).addDependency(Services.JBOSS_SERVER_CONTROLLER, ModelController.class, mcValue);
>   ...
>   WHAT_I_WANT = mcValue.getValue().createClient(...)
> 
> I need something similar in the javaagent - I need to get that local ModelController so the javaagent can build a local client and thus avoid having to configure the WildFly remote management interface and avoid having to make remote calls to its co-located WildFly Server.
> 
> Hopefully, that makes sense. Sorry - wasn't short :)
> 
> ----- Original Message -----
>> Hi John,
>> 
>> Before moving with non-traditional access like this I think we need to make
>> sure the overall strategy behind what you are building is something we can
>> support over multiple releases. Of course, a lot of that depends on your
>> compatibility expectations.
>> 
>>> On Mar 13, 2017, at 10:08 AM, Brian Stansberry
>>> <brian.stansberry at redhat.com> wrote:
>>> 
>>> Once you get access to MSC, do not use Services.JBOSS_SERVER_CONTROLLER to
>>> get a ModelController to create the client. That method is deprecated and
>>> I plan to remove it in the next release (WildFly Core 4 / WildFly 12).
>>> 
>>> Use
>>> ServiceName.parse("org.wildfly.managment.model-controller-client-factory”)
>>> to get a ModelControllerClientFactory and use it to create a client,
>>> calling createSuperUserClient.
>>> 
>>> Note that if you want that client to work properly in a SecurityManager
>>> enabled environment your code will need to have
>>> org.jboss.as.controller.security.ControllerPermission#PERFORM_IN_VM_CALL
>>> PERFORM_IN_VM_CALL. The security guys added in that requirement for WF
>>> Core 3. Note that applies even if you use the deprecated
>>> ModelController.createClient method.
>>> 
>>>> On Mar 12, 2017, at 8:32 PM, Stuart Douglas <stuart.w.douglas at gmail.com>
>>>> wrote:
>>>> 
>>>> You can call
>>>> org.jboss.as.server.CurrentServiceContainer#getServiceContainer() to do
>>>> this, however it is trickey from a JavaAgent (as the module will not be
>>>> available from the agent's class loader).
>>>> 
>>>> Unfortunately there is no getting around this, as none of the API classes
>>>> you need will be available in the module. As I see it you have a few
>>>> different options:
>>>> 
>>>> 1) Use reflection to get hold of this class, and then use reflection to
>>>> make the calls
>>>> 2) Create a class that does this directly, and then make sure it is loaded
>>>> from the server module (which has access to the classes you need).
>>>> 
>>>> There may be some other options, but that is all I can think of of the top
>>>> of my head.
>>>> 
>>>> If you want more info on how to implement either of these approaches feel
>>>> free to ask me on hipchat.
>>>> 
>>>> Stuart
>>>> 
>>>> On Sat, Mar 11, 2017 at 5:43 PM, John Mazzitelli <mazz at redhat.com> wrote:
>>>> OK, here's another one where I need some secret magical sauce - hoping
>>>> someone knows of a technique I can use.
>>>> 
>>>> Suppose I have a javaagent installed in a WildFly server (using the
>>>> standard -javaagent VM argument).
>>>> 
>>>> The javaagent would like to talk to the WildFly Server it is co-located
>>>> with. Since it is in the same VM, the javaagent wants to avoid it looking
>>>> like a remote call.
>>>> 
>>>> But I know of no way to obtain a local ModelController instance to build a
>>>> client short of injecting some service or subsystem into WildFly itself
>>>> (something I would like to avoid).
>>>> 
>>>> If the javaagent were instead a subsystem extension, it could do something
>>>> like this:
>>>> 
>>>>  InjectedValue<ModelController> mcValue = new InjectedValue<>();
>>>>  ...
>>>>  ((ServiceBuilder) bldr).addDependency(Services.JBOSS_SERVER_CONTROLLER,
>>>>  ModelController.class, mcValue);
>>>>  ...
>>>>  WHAT_I_WANT = mcValue.getValue().createClient(...)
>>>> 
>>>> But obviously, that's no good for something running outside of the WildFly
>>>> container (albeit in the same JVM).
>>>> 
>>>> Any hope at all? I was thinking some trickery on the order of what ByteMan
>>>> does in order to figure out a way to obtain a local ModelController? But
>>>> that's a last ditch effort :) Hoping there is something that uses a
>>>> little less witchcraft.

--
Jason T. Greene
WildFly Lead / JBoss EAP Platform Architect
JBoss, a division of Red Hat




More information about the wildfly-dev mailing list