I annotated the bean with @MXBean then returned CompositeData[] creating instances of CompositeDataSupport.
Exposing Collection<Something> from ManagedResource bean?
-
07-12-2021 - |
Question
@ManagedResource
@Component
public class MyBean {
Map<String, Something> map = new HashMap<String, Something>();
@ManagedAttribute
public Collection<Something> getFoo() {
return map.values();
}
}
The foo attributed shows as 'unavailable' in the visualvm mbeans tab. Why?
Solution 3
OTHER TIPS
The MXBean solution is the way to go most of the time, although there is a slightly easier way than generating CompositeDataSupport instances. Let's say your class is:
public class Something {
private String foo;
private Date date;
<Insert Ctor here>
public String getFoo() {
return foo;
}
public Date getDate() {
return date;
}
}
You can create an MBean interface as follows:
public interface SomethingMBean { // same package please...
public String getFoo();
public Date getDate();
}
Make Something implement SomethingMBean:
public class Something implements SomethingMBean {
.....
}
Now in your actual MBean (the @MXBean annotated one), you can define a method like this:
public List<SomethingMBean> getSomethings() {
.....
}
The Java6+ MBeanServer will automatically generate CompositeDataTypes and instances at runtime. As a simple diagnostic tool, I frequently swap out the JVM's ThreadMXBean with a wrapped one that exposes ThreadInfos using this technique. (See ExtendedThreadManager for an example) It looks like this in JConsole:
It will work if Something
is part of the JDK (such as String).
If Something
is a custom class, VisualVM won't know about it; hence 'unavailable'.
You can see more information if you go to the operations
tab and click getFoo()
.
I have not tried it, but I believe you can add stuff to VisualVM's class path with
jvisualvm -cp:a /path/to/Something/top/level/package
(or jar).
Then, it might work; even then, though, Something
(and its fields) needs to be Serializable
.