2014-12-08 3 views
2

실제의 형태 및 속성은 실행시에 결정되는 속성을 가지지 않는 추상 형을 돌려주는 MXBean 조작을 작성하려고하고 있습니다. 다음과 같이 내 데이터 모델은 간단하게 넣을 수 있습니다MXBean 조작 시그 니챠의 추상 형

public interface I extends CompositeDataView { 
    // empty 
} 

public final class A implements I { 
    private final String foo; 

    @ConstructorProperties({"foo"}) 
    public A(final String foo) {/* ... */} 

    public String getFoo() {/* ... */} 

    @Override 
    public CompositeData toCompositeData(CompositeType ct) {/* ... */} 

    public static A from(final CompositeData cd) {/* ... */} 
} 

public final class B implements I { 
    private final String bar; 

    @ConstructorProperties({"bar"}) 
    public B(final String bar) {/* ... */} 

    public String getBar() {/* ... */} 

    @Override 
    public CompositeData toCompositeData(CompositeType ct) {/* ... */} 

    public static B from(final CompositeData cd) {/* ... */} 
} 

... 그리고 MXBean의 작업 서명은 다음과 같습니다

@MXBean 
public interface Baz { 
    I f(); 
} 

작업은 foo 속성 중 하나 A의 인스턴스를 반환 할 수 있습니다, 또는 예를 들어 B의 인스턴스는 bar입니다. 나는 반짝 NotCompliantMBeanException 제시하고있어 물론 즉시 나는 MBean 인스턴스를 등록하려고 :

Caused by: javax.management.openmbean.OpenDataException: Can't map I to an open data type 
    at com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory.makeCompositeMapping(DefaultMXBeanMappingFactory.java:458) 
    at com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory.makeMapping(DefaultMXBeanMappingFactory.java:292) 
    at com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory.mappingForType(DefaultMXBeanMappingFactory.java:257) 

거기 일반 MBean들과 내가 할 수있는 일이 그리고 Serializable하지만 보인다 수 없습니다 MXBean s 및 CompositeDataView와. 아니면 내가 틀렸어?

답변

1

당신이 원하는 것보다 더 많거나 적은 것을 할 수는 있지만 모든 것이 그렇게 간단하지는 않습니다. 요점은, MXBean 스펙에는 CompositeData에 적어도 1 개의 항목이 필요합니다. 기본 클래스에 type 속성을 지정하면이 요구 사항을 충족시킬 수 있습니다. 여기서는 AnyCompositeData을 호출했습니다. type 속성은 CompositeData에서 FooBar과 같은 특정 유형으로 다시 변환하는 방법을 결정하는 역할을 할 수도 있습니다. 여기 코드에서 나는 AnyCompositeData 클래스에 모든 것을 채웠다.하지만 실제로는 클래스가 분리되어있다. 나는 콘크리트 클래스 Foo의 철자만을 사용했지만 다른 클래스를 지원하기 위해 패턴을 확장하는 방법을 분명히해야합니다.

public abstract class AnyCompositeData implements CompositeDataView { 
    private final String type; 

    public AnyCompositeData(String type) { 
    this.type = type; 
    } 

    public String getType() { 
    return type; 
    } 

    public static AnyCompositeData from(CompositeData cd) { 
    switch ((String) cd.get("type")) { 
     case "Foo": 
     return new Foo((String) cd.get("foo")); 
     default: 
     throw new IllegalArgumentException("Don't know how to reconstruct: " + cd.get("type")); 
    } 
    } 

    public static class Foo extends AnyCompositeData { 
    private final String foo; 

    Foo(String foo) { 
     super("Foo"); 
     this.foo = foo; 
    } 

    public String getFoo() { 
     return foo; 
    } 

    @Override 
    public CompositeData toCompositeData(CompositeType ct) { 
     try { 
     String[] items = {"type", "foo"}; 
     OpenType<?>[] itemTypes = {SimpleType.STRING, SimpleType.STRING}; 
     Object[] itemValues = {"Foo", foo}; 
     CompositeType compositeType = new CompositeType("Foo", "Foo", items, items, itemTypes); 
     return new CompositeDataSupport(compositeType, items, itemValues); 
     } catch (OpenDataException e) { 
     throw new RuntimeException(e); 
     } 
    } 
    } 

    @MXBean 
    public interface Baz { 
    AnyCompositeData f(); 
    } 

    static class BazImpl implements Baz { 
    @Override 
    public AnyCompositeData f() { 
     return new Foo("whatever"); 
    } 
    } 

    public static void main(String[] args) throws Exception { 
    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 
    ObjectName objectName = new ObjectName("test:baz=baz"); 
    mbs.registerMBean(new BazImpl(), objectName); 
    Baz bazProxy = JMX.newMXBeanProxy(mbs, objectName, Baz.class); 
    AnyCompositeData result = bazProxy.f(); 
    assert result instanceof Foo; 
    assert ((Foo) result).getFoo().equals("whatever"); 
    } 
} 

당신이 Foo 같은 서브 클래스를 많이 가지고 있다면, 당신은 from(CompositeData) 방법을 어떤 방법으로 반사를 사용하는 것이 아니라 가진 것을 고려할 수 있습니다이에 대한 모든 서브 클래스를 알고있다.

+0

감사합니다. Eamonn! 저는이 기회를 빌어 JMX의 블로그 게시물 (https://www.java.net/blogs/emcmanus)에 감사드립니다. 그들은 정말 훌륭합니다. 일상 업무에서 사용합니다. – Bass