Java MXBean custom types - java

I am trying to create an MXBean with a custom attribute, but I get javax.management.NotCompliantMBeanException
IJmsDestinationMBean.getAttributes has parameter or return type that cannot be translated into an open type
I have read that MXBean attributes have to be OpenType compatible.
How would I make my attribute work this way?
All the classes below are in the same package.
class JmsDestinationMBean implements IJmsDestinationMBean{
protected JmsDestinationAttributes attributes = new JmsDestinationAttributes();
#Override
public JmsDestinationAttributes getAttributes() {
return this.attributes;
}
}
#MXBean
interface IJmsDestinationMBean {
JmsDestinationAttributes getAttributes()
}
class JmsDestinationAttributes {
protected String name
protected int messagesCurrentCount
protected int consumersCurrentCount
String getName() {
this.name;
}
int getMessagesCurrentCount() {
this.messagesCurrentCount;
}
int getConsumersCurrentCount() {
this.consumersCurrentCount;
}
}

The problem is the interface IJmsDestinationMBean. It returns a type JmsDestinationAttributes which is not an open type. Here's the rules-of-thumb I follow when doing this:
The actual registered MBean (which has a complex typed attribute) is called Foo and it's management interface is called FooMXBean.
The complex type (the attribute of Foo is called Bar and has a management interface called BarMBean. This guy cannot return any values that are not open types or other properly exposed complex types.
So (for this example) the "host" MBean needs to be an MXBean in order to support complex types , and the complex type needs to have an interface called <ClassName>MBean. Note that one has the MXBean interface, and the other has the MBean interface.
Here's my example:
JMSDestination implements JMSDestinationMXBean
JmsDestinationAttributes implements JmsDestinationAttributesMBean
...apologies for the loose case standard. It's an on the fly example.
Here the JMSDestination code, with a main to create and register. I am simply using the user name property to provide the name.:
public class JmsDestination implements JmsDestinationMXBean {
protected JmsDestinationAttributes attrs = new JmsDestinationAttributes(System.getProperty("user.name"));
public JmsDestinationAttributes getAttributes() {
return attrs;
}
public static void main(String[] args) {
JmsDestination impl = new JmsDestination();
try {
ManagementFactory.getPlatformMBeanServer().registerMBean(impl, new ObjectName("org.jms.impl.test:name=" + impl.attrs.getName()));
Thread.currentThread().join();
} catch (Exception ex) {
ex.printStackTrace(System.err);
}
}
}
The JMSDestinationMXBean code:
public interface JmsDestinationMXBean {
public JmsDestinationAttributes getAttributes();
}
The JmsDestinationAttributes code which uses the same name and random numbers for the values:
public class JmsDestinationAttributes implements JmsDestinationAttributesMBean {
protected final String name;
protected final Random random = new Random(System.currentTimeMillis());
public JmsDestinationAttributes(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getMessagesCurrentCount() {
return Math.abs(random.nextInt(100));
}
public int getConsumersCurrentCount() {
return Math.abs(random.nextInt(10));
}
}
.... and the JmsDestinationAttributesMBean:
public interface JmsDestinationAttributesMBean {
public String getName();
public int getMessagesCurrentCount();
public int getConsumersCurrentCount();
}
The JConsole view looks like this:
The JConsole view of the MXBean's attributes looks like this:
Make sense ?

Related

How to use multiple bounds correctly?

Im trying to create an instantiate a generic class called "MultipleBoundsClass" that has multiple bounds - a class called "OrderedPair" and an interface called "Pair"(which Ordered Pair implements).
Ive tried removing the interface boundary and that let me compile. But I dont know why that worked, and how Id get it to successfully with the interface boundary included.
public interface Pair<K, V>
{
public K getKey();
public V getValue();
}
public class OrderedPair<K, V> implements Pair
{
private K key;
private V value;
public OrderedPair(K key, V value)
{
this.key = key;
this.value = value;
}
public K getKey()
{
return key;
}
public V getValue()
{
return value;
}
}
class OrderedPair {}
interface Pair {}
public class MultipleBounds<T extends OrderedPair & Pair>
{
private T t;
public MultipleBounds(T t)
{
this.t = t;
}
public T getPair()
{
return t;
}
}
public static void main(String[] args)
{
OrderedPair<String, Integer> p1 = new OrderedPair<>("even", 8);
MultipleBounds<OrderedPair> myPair = new MultipleBounds<OrderedPair>(p1);
}
I get the error "type argument OrderedPair is not within bounds of type-variable T". Bounded types restrict the arguments a generic parameter can be, to the class you define and its subclasses, so why is the type OrderedPair not within bounds of itself when the interface is included as a present boundary?
I want to provide an example of how you might be using multiple bounds. It is freaky a lot, but may help to understand things.
Suppose we have a Container, and we are able to put something in.
abstract class Container {
private Object content;
public void put(Object object) { this.content = object; }
public Object get() { return content; }
}
Then, there are interfaces to define some properties for those containers. They may be Rollable and/or Inflammable.
interface Rollable { void roll(); /* rolls somehow */ }
interface Inflammable { void burnItself(); /* burns somehow */ }
Then, we define concrete Container classes: a CardboardBox, a GiftBox, a MetalBarrel and a WoodBarrel, and implement interfaces according to their properties:
class CardboardBox extends Container implements Inflammable {
#Override
public void burnItself() { /* omit implementation */ }
}
class GiftBox extends Container implements Rollable, Inflammable {
#Override
public void burnItself() { /* omit implementation */ }
#Override
public void roll() { /* omit implementation */ }
}
class MetalBarrel extends Container implements Rollable {
#Override
public void roll() { /* omit implementation */ }
}
class WoodBarrel extends Container implements Rollable, Inflammable {
#Override
public void burnItself() { /* omit implementation */ }
#Override
public void roll() { /* omit implementation */ }
}
Now, the real bizarre. Suppose you want to create a Stock, where all the things must be Rollable. And Inflammable. Because you want to roll all your containers inside and to be able to burn one of them. You define a Stock:
class Stock <T extends Container & Rollable & Inflammable> {
private List<T> containers;
void addContainer(T container) { containers.add(container); }
void rollAllContainers() { containers.forEach(Rollable::roll); }
void burnContainer(int index) { containers.get(index).burnItself(); }
}
And then you are able to create one of those. You are not tied to Container type; just to its properties - as they are defined by interfaces.
public static void main(String[] args) {
Stock<GiftBox> giftBoxStock = new Stock<>();
GiftBox giftBox = new GiftBox();
giftBox.put("a gift");
GiftBox giftBox1 = new GiftBox();
giftBox1.put("another gift");
giftBoxStock.addContainer(giftBox);
giftBoxStock.addContainer(giftBox1);
giftBoxStock.rollAllContainers();
giftBoxStock.burnContainer(0);
Stock<WoodBarrel> woodBarrelStock = new Stock<>();
WoodBarrel woodBarrel = new WoodBarrel();
woodBarrel.put("wine");
WoodBarrel woodBarrel1 = new WoodBarrel();
woodBarrel1.put("gas");
woodBarrelStock.addContainer(woodBarrel);
woodBarrelStock.addContainer(woodBarrel1);
woodBarrelStock.rollAllContainers();
woodBarrelStock.burnContainer(1);
}

Generically providing a setter for a Decorated object that is stored in an array

I'm probably going about this in the most complicated way, but I'm hoping what I'm trying to do makes sense here.
Suppose I have some set of unrelated, generated classes and I want to Decorate them to create some kind of common API. So something like:
public abstract class GeneratedDecorator<T> {
private T generated;
public T getGenerated() { return generated; }
public void setGenerated(T generated) { this.generated = generated; }
public abstract String getString();
public static class ClassA extends GeneratedDecorator<GeneratedClassA> {
#Override
public String getString() { return getGenerated().getThisString(); }
}
public static class ClassB extends GeneratedDecorator<GeneratedClassB> {
#Override
public String getString() { return getGenerated().getADifferentString(); }
}
}
Now, to use this new fancy class I just say:
GeneratedDecorator.ClassA a = new GeneratedDecorator.ClassA();
a.setGenerated(myGeneratedInstanceA);
a.getString();
Ok so far so-so ... but now I want to manage an array of these Decorators.
So let's try:
public abstract class DecoratorBundle<T extends GeneratedDecorator> {
private static final int MAX_ROWS = 10;
private T[] bundle;
DecoratorBundle() { bundle = createBundle(); }
public String getString(int index) { return bundle[index].getString(); }
public void setRow(??? generated, int index ) {
//check index of bundle, if null create a new instance of appropriate type and set bundle[index] = new instance
//call setGenerated on instance at index
}
protected abstract T[] createBundle();
public static class ClassA extends DecoratorBundle<GeneratedDecorator.ClassA> {
#Override
protected GeneratedDecorator.ClassA[] createBundle() {
return new GeneratedDecorator.ClassA[MAX_ROWS];
}
}
public static class ClassB extends DecoratorBundle<GeneratedDecorator.ClassB> {
#Override
protected GeneratedDecorator.ClassB[] createBundle() {
return new GeneratedDecorator.ClassB[MAX_ROWS];
}
}
}
Here's where I'm stuck ... I want this DecoratorBundle to have a setRow(??? generated, int index) where the parameter is of the GeneratedDecorator's type (i.e, GeneratedClassA or GeneratedClassB). Seems like type erasure will probably make this impossible, but it would be really nice to have this DecoratorBundle class to completely manage it's bundle array. It currently is able to instantiate the array, but I want some way for it to create a new GeneratedDecorator-type and assign it in a setRow method.
If I'm going about this completely wrong then I would love to hear another idea.

Refactoring java classes where methods have different parameter types

I have two classes that extend an abstract class in a very similar manner, and I'd like to abstract out the common parts since I will likely have to use this again. They each return a ThingLink containing data linking them to a Parent object. They also return a Widget that varies based on the class, but only up to their name. Here is the pattern:
public abstract class SomeClass extends TopClass {
protected abstract Widget createWidget();
public void someMethod() { // Does something }
}
public class ThingA extends SomeClass {
private static final String INFO_TYPE = "int";
public ThingLink newLink(Parent master, Int info) {
ThingLink link = new ThingLink(parent, ThingA.class);
link.addData(INFO_TYPE, info);
return link;
}
public Widget createWidget() {
// Stuff to get someData
return ThingAWidget.createMe(someData);
}
}
public class ThingB extends SomeClass {
private static final String INFO_TYPE = "String";
public ThingLink newLink(Parent master, String info) {
ThingLink link = new ThingLink(parent, ThingB.class);
link.addData(INFO_TYPE, info);
return link;
}
public Widget createWidget() {
// Stuff to get someData
return ThingBWidget.createMe(someData);
}
}
I have no access to TopClass, the ThingLink class, or the Widget class. I was trying to abstract out the common parts using generics, but I can't seem to figure out if that will provide a complete solution. My big problem is figuring out how to get the pieces that are self-referential. I would like a class something like:
public abstract class Thing<T> extends SomeClass {
private String infoType;
public void setInfoType(String type) { infoType = type; }
public ThingLink newLink(Parent master, T info {
ThingLink link = new ThingLink(parent, ???????????);
link.addData(infoType, info);
return link;
}
public Widget createWidget() {
// Stuff to get someData
return ??????????????.createMe(someData);
}
}
Keep in mind that I am fairly new to Java, and self-taught, but I am trying very hard to make some bigger leaps and really understand how to write good code. I appreciate your help.

Use actual type of the class when using inheritance

Let's say we have a class with the following method:
public class Entry {
private String name;
public static Entry getOrCreate(String name) {
// ...
return new Entry(name);
}
}
This class may be subclassed (e.g. SubEntry), and the logic behind "getOrCreate" does not change. But the subclasses should not return a new object of the type Entry, but of the type of the respective subclass (e.g. return SubEntry(name))
How can I realize this without reimplementing the method getOrCreate for every subclass of Entry? Is there a term for this kind of technique?
Subclassing Entry does not affect the getOrCreate method because static methods are not part of a class instance; they do not logically belong in any class.
If you instead move getOrCreate into a non-static Factory class, you can use some Generics magic to determine the returned type:
public class Entry {
private String name;
}
abstract class AbstractEntryFactory<T extends Entry>
public abstract T getOrCreate(String name);
}
public class EntryFactory extends AbstractEntryFactory<Entry>
#Override
public Entry getOrCreate(String name) {
// ...
return new Entry(name);
}
}
public class SubEntryFactory extends AbstractEntryFactory<SubEntry>
#Override
public SubEntry getOrCreate(String name) {
// ...
return new SubEntry(name);
}
}
Actually calling the getOrCreate would look different from what it would look like with your code. Instead of this:
Entry myEntry = Entry.getOrCreate("my name");
It would instead look like this:
Entry myEntry = new EntryFactory().getOrCreate("my name");
Or this:
SubEntry myEntry = new SubEntryFactory().getOrCreate("my name");
Assuming you wanted to be able to call Entry.getOrCreate() to create a type of SubEntry, you'll have to pass along some extra information. The reason is that the getOrCreate() method is not inherited by SubEntry, since it is a static method. So if you want to call it the way I mentioned, you'll have to pass along the class name that you want to create. In the code below there are no checks to validate that Class clazz is an Entry or a subtype, but this gives you a start.
import java.lang.reflect.Constructor;
public class TestClass {
public static void main(String[] args) {
Entry entry = (Entry)Entry.getOrCreate("entry", Entry.class);
SubEntry subEntry = (SubEntry)SubEntry.getOrCreate("subEntry", SubEntry.class);
System.out.println("entry class: " + entry.getClass().getName());
System.out.println("subEntry class: " + subEntry.getClass().getName());
}
}
class Entry {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static Object getOrCreate(String name, Class clazz) {
// If a constructor is created that takes a String, such as "public Entry(String name)",
// then each sub class will need to implement that method. Instead I used a getter and
// setter for the name attribute.
try {
Entry entry = (Entry)clazz.newInstance();
entry.setName(name);
return entry;
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
class SubEntry extends Entry {
}
The end result is this output:
entry class: Entry
subEntry class: SubEntry
There are two questions you are asking:
How do I do this?
What is this technique called?
The second one is much more important than the first.
It seems to me like what you are trying to achieve is similar to the concept of cloning (link) or virtual constructor. But you would like this to be a static method, which raises the question as to why? Since a static method is tied to a certain class, not an instance, you should call it through that class in which case you may just as well explicitly be calling new. But having searched for "retrive class in static context" I would say it is not possible to do exactly what you wrote in the question.
If you convert the static method to a normal method, this can be done by using reflection:
class Entry {
private String name;
public Entry(String name) {
this.name = name;
}
public Entry() {
this.name = null;
}
public Entry getOrCreate(String name) {
try {
return getClass().getConstructor(String.class).newInstance(name);
} catch (Exception e) {
return new Entry(name);
}
}
}
class BetterEntry extends Entry {
public BetterEntry(String name) {
super(name);
}
public BetterEntry() {
super();
}
}
You would then be calling the function from an instance, like so:
Entry a = new Entry().getOrCreate("First");
Entry b = new BetterEntry().getOrCreate("Second");
Entry c = b.getOrCreate("Third");
The dynamic types of a, b, c are Entry, BetterEntry and BetterEntry. You could leave out the default constructors, but I added them to make calling getOrCreate feel more like a static method.
If you really want the method to be static, the simplest way would be to just reimplement this function in every subclass.

Generic Builder in Java

I created a builder for a lookup table and using it as shown below.
public class RaceCodeDataBuilder {
private RaceCode raceCode;
public RaceCodeDataBuilder() {
raceCode = new RaceCode();
}
public RaceCodeDataBuilder code(String code) {
raceCode.setCode(code);
return this;
}
public RaceCodeDataBuilder displayName(String displayName) {
raceCode.setDisplayName(displayName);
return this;
}
public RaceCode build() {
return raceCode;
}
}
Using this builder in a test:
RaceCode mockRaceCode = new RaceCodeDataBuilder()
.code("2054-5")
.displayName("Black or African American")
.build();
I am expecting lot more similar builders for other look up tables such as StateCodeBuilder, GenderCodeBuilder and all of them have just "code" and "displayName", similar to above builder.
I want to create a generic builder and avoid creating several builder classes doing the same job with different name.
I attempted something in generics but I am way off..
public class CodeDataBuilder<T>{
private T t;
public CodeDataBuilder(T t) {
this.t = t;
}
public CodeDataBuilder code(String code) {
raceCode.setCode(code); // Cant write T.setCode here for obvious resons
return this;
}
public CodeDataBuilder displayName(String displayName) {
raceCode.setDisplayName(displayName); // Cant write T.setDisplayNamehere for obvious resons
return this;
}
public T build() {
return t;
}
}
Can someone help me with that?
Thank you.
Create an interface BuildableCodeData with the methods you need, and implement it with classes like RaceData.
Your code will then look like:
public interface BuildableCodeData {
public void setCode(String code);
public void setDisplayName(String name);
}
public class Builder<T extends BuildableCodeData> {
private T codeData;
public Builder(T codeData) {
this.codeData = codeData;
}
public Builder<T> setCode(String code) {
codeData.setCode(code);
return this;
}
public Builder<T> setDisplayName(String displayName) {
codeData.setDisplayName(displayName);
return this;
}
public T build() {
return codeData;
}
}
It looks more like you should use an interface, and just make your build method return that interface. For example:
public interface Buildable{
void setDisplayName(String name);
void setCode(String code);
}
public class CodeDataBuilder {
private Buildable mObj;
public CodeDataBuilder(Buildable mObj) {
this.mObj = mObj;
}
public CodeDataBuilder code(String code) {
mObj.setCode(code); // Cant write T.setCode here for obvious resons
return this;
}
public CodeDataBuilder displayName(String displayName) {
mObj.setDisplayName(displayName); // Cant write T.setDisplayNamehere for obvious resons
return this;
}
public Buildable build() {
return mObj;
}
}
}
Then just make any object you want to build implement the Buildable interface.
If you create an interface with the needed methods:
interface CodeModel {
public void setCode(String s);
public void setDisplayName(String s);
}
You can then ask your generic class to accept only T extends CodeModel, like so:
class CodeDataBuilder<T extends CodeModel> {
// T has setCode method now!
}
Hope this helps!
If you have an interface with some standard functions, you can create a generic builder for it. The base builder would be abstract, and for each concrete implementation, there would be a concrete builder.
Interface:
public interface CodeNameable {
String getCode();
String getName();
}
Concrete implementation:
public class CodeNamedCar implements CodeNameable {
private String code;
private String name;
public CodeNamedCar(String code, String name) {
this.code = code;
this.name = name;
}
}
Abstract builder:
public abstract class CodeNameBuilder<C extends CodeNameable> {
public String code;
public String name;
public CodeNameBuilder() {
}
}
Concrete builder:
public abstract class CarBuilder extends CodeNameBuilder<CodeNamedCar> {
public CarBuilder() {
}
public CarBuilder code(String co_de) {
this.code = code;
return this;
}
public CarBuilder name(String name) {
this.name = name;
return this;
}
public CodeNameCar build() {
return (new CodeNameCar(code, name));
}
}
Then you can use it as you hoped:
CodeNamedCar car = new CarBuilder().code("thecode").name("Mazda").build();
Using this design, you'll need to check each field for correctness (non-null and non-empty, for example) in the CodeNameCar constructor. There are other ways to design it, too.
The builder pattern is about to crate a new instance of class and initialize it as much as required to do.
In the way you are going you tend to finish with a partial setter of some properties and create a possible fake relation because two object has the same attributes.
To support this in example everything has an name attribute but you do not create a super interface to called Nameable and implements its in every possible place.
If those attribute are shared across your classes you should think to create a class for them.
class Code {
int number;
String name;
}
class Race {
Code code;
//other attributes;
}
Then you have a one builder for code and another for race.
Note also that the good design is a balance of trade offs. If two fields are common for 5 classes is the a purpose to make the code complex and create a dedicated mechanize that will only pack the initialization and will not do anything productive.

Categories