Description for Standard MBean - java

I want to make my Standard MBean verbose in JBoss jmx-console. DynamicMBean has getMBeanInfo() to do it. Method return MBeanInfo with description of MBean. But how I can to do the same thing for Standard MBean? E.g. I have following MBean interface:
public interface MyMBean {
String f();
}
... with following implementation:
public class My implements MyMBean {
public String f() {
return "test";
}
}
What should be done to add description in such example?
Thanks

For StandardMBeans there is no way for adding description or other meta information.
From the JavaDoc of MBeanInfo:
The remaining details of the MBeanInfo for a Standard MBean are not specified. This includes the description of the MBeanInfo and of any contained constructors, attributes, operations, and notifications; and the names and descriptions of parameters to constructors and operations.
So you need to use at least DynamicMBeans (or a ModelMBean or OpenMBean) for specifying this information. Spring can help you insofar as it allows the creation of DynamicMBeans via annotations, which at the end is even simpler to use than to write own StandardMBeans. Example (from the spring documentation) :
#ManagedResource(objectName="bean:name=testBean4",
description="My Managed Bean")
public class AnnotationTestBean {
private int age;
#ManagedAttribute(description="The Age Attribute", currencyTimeLimit=15)
public int getAge() {
return age;
}
}
See this article for details.

You can do this via an xmbean-descriptor without the need to modify the existing mbean source code.
See How to add description for MBean method to see it in jmx-console of JBOSS for an answer to this.

The way to get the description information from Spring annotations #Managed* is just to declare a standard Spring "managed bean", and not an MBean or MXBean.
To do this, in your example, you must not implements the interface with "MBean" suffix.
Then, the bean will be detected as a standard "managed bean" when MBeanExporter will registerBeanInstance(..), and will be converted to a ModelMBean using all spring annotations, including descriptions of attributes, operations, parameters, etc..
As a requirement, you should declare in your spring context the MBeanExporter with AnnotationJmxAttributeSource, MetadataNamingStrategy, and MetadataMBeanInfoAssembler attributes, which can be simplified like this :
<bean id="mbeanExporter"
class="org.springframework.jmx.export.annotation.AnnotationMBeanExporter" />
or
<context:mbean-export />
And your managed bean should look like this (as explained by Roland) :
#Component("myManagedBean")
#ManagedResource(objectName="your.domain.jmx:name=MyMBean",
description="My MBean goal")
public class AnnotationTestBean {
private int age;
#ManagedAttribute(description="The age attribute", currencyTimeLimit=15)
public int getAge() {
return age;
}
#ManagedOperation(description = "Check permissions for the given activity")
#ManagedOperationParameters( {
#ManagedOperationParameter(name = "activity",
description = "The activity to check")
})
public boolean isAllowedTo(final String activity) {
// impl
}
}
Remember to not implements an MBean interface, which would be a StandardMBean !!

Related

Sharing state between step definitions in Cucumber

I have 4 step definition classes and a set of domain object classes.
My first step definition class looks like this:
public class ClaimProcessSteps {
Claim claim;
public ClaimProcessSteps(Claim w){
this.claim = w;
}
#Given("^a claim submitted with different enrolled phone's model$")
public void aClaimSubmittedFromCLIENTSChannelWithDifferentEnrolledPhoneSModel() throws Throwable {
claim = ObjMotherClaim.aClaimWithAssetIVH();
}
}
My Claim class looks like this:
public class Claim {
private String claimType;
private String clientName;
private Customer caller;
private List<Hold> holds;
public Claim() {}
public Claim(String claimType, String clientName, Customer caller) {
this.claimType = claimType;
this.clientName = clientName;
this.caller = caller;
}
public String getClaimType() {
return claimType;
}
My second step definition class looks like:
public class CaseLookupSteps {
Claim claim;
public CaseLookupSteps(Claim w){
this.claim = w;
}
#When("^I access case via (right|left) search$")
public void iAccessCaseInCompassViaRightSearch(String searchVia) throws Throwable {
System.out.println(claim.getClaimType());
}
I've already imported the picocontainter dependency in my POM.XML and I am getting the following error.
3 satisfiable constructors is too many for 'class java.lang.String'. Constructor List:[(Buffer), (Builder), ()]
None of my step definition classes constructors receive primitives as arguments. Does anyone have any clue as to why I am still getting that error? Could it be my business object constructor that does expect a String in its constructor?
Thanks in advance for any help.
Picocontainer looks over not only your step definition classes to resolve dependencies. It also looks over all classes that your steps definitions depend on.
In this case, it's trying to resolve the dependencies for your non-default Claim constructor.
public Claim(String claimType, String clientName, Customer caller) {
...
}
According to this issue there's no way to solve this other than keeping only default constructors in all your dependencies.
Assuming your scenario looks like this:
Given some sort of claim
When I lookup this claim
Then I see this claim
Currently your test is missing the setup step of the claim.
So rather then directly sharing the claim object between steps you should create a ClaimService class with only the default constructor. You can inject this service into your step definitions.
Once you have injected the service, you can use it in the step definition of Given some sort of claim to callclaimService.createSomeSortOfClaim() to create a claim. This claim can be created in memory, in a mock db, actual db, or other persistence medium.
In When I lookup this claim you then use claimService.getClaim() to return that claim so you can use its type to search for it.
Doing it this way you'll avoid the difficulty of trying to make the DI container figure out how it should create the claim under test.

Why is there a different result of an method when modified its object with a portable extension and applied an interceptor on the same object too?

Maybe you can give a hint, where to find a solution for this problem.
Currently I discover CDI portable extensions, like the sample shown here Wrapping an InjectionTarget.
This CDI portable extension reads values from properties files and configures fields of a Java object.
Here is a snippet of the extension:
public <T> void checkForPropertyFileAnnotation(
final #Observes ProcessInjectionTarget<T> pit) {
AnnotatedType<T> at = pit.getAnnotatedType();
if (!at.isAnnotationPresent(PropertyFile.class)) {
return;
}
// found annotation
[...load properties...]
[...assign properties to fields...]
[...create new wrapped InjectionTarget...]
pit.setInjectionTarget([created InjectionTarget]);
}
Running this extension on an example class does what it should do. But when I apply a, for example LoggingInterceptor like shown here simple cdi interceptor, the extension seems not working.
The logging interceptor:
#Log #Interceptor
public class LoggingInterceptor {
#AroundInvoke
public Object log(InvocationContext ctx) throws Exception {
Logger logger = Logger.getLogger(ctx.getTarget().getClass().getName());
logger.info("before");
Object result = ctx.proceed();
logger.info("after");
return result;
}
}
The sample-class looks like:
#Named
#Model // to use EL in jsp/jsf
#Log // the interceptor annotation
#PropertyFile("myprops.txt") // the annotation used within the extension
public class MyProperties {
#Property("version")
Integer version;
#Property("appname")
String appname;
public Integer getVersion() {
return version;
}
public String getAppname() {
return appname;
}
}
The content of the result-page:
<h:body bgcolor="white">
#{myProperties.appname} v#{myProperties.version}
</h:body>
It's not really true, the extension works, means it injects the appropriate values into the desired fields as I can see in the log-file, but after the interceptor gets applied, the injected values are gone.
Do you have any idea why this can happen? Maybe the extension handles a different instance of the class than the interceptor.
Thanx in advance for your reply!
You're twiddling fields on a proxy class, and then the getters are getting the values from the underlying instance.
I had the same problem. Both the interceptor and extension work separately, but when used together, the interceptor stops working. This is due to a bug in OpenWebBeans CDI implementation where interceptors are only processed when the injection target is an instance of an OpenWebBeans specific InjectionTargetImpl.
See: https://issues.apache.org/jira/browse/OWB-897

Spring bean configuration to use singleton or prototype?

I am using Java7 and Spring3. I have below classes.
Request.java
public interface Request {
public void doProcess();
}
RequestImpl.java
#Transactional
public class RequestImpl implements Request{
private String name;
private String age;
//setters and getters
public void doProcess(){
//use name and age and call third party class which will save data into database
}
}
SpringConfig.xml
<bean id="request" class="pkg.RequestImpl.java" />
Now clients will use RequestImpl as below.
RequestImplreq = (RequestImpl)applicationContext.getBean("request");
req.setName("someName");
req.setAge("20");
req.doProcess();
Now my question is do i need to declare above RequestImpl.java scope as prototype or singleton?
Thanks!
IMHO you are not working well: processes and data to process should be separated (Can DTOs be spring managed beans?) so doProcess() should be defined as doProcess(name,age) or shaded behind a factory or something similar.
Probably the best option is to define
public interface Request {
public void doProcess(String name,String age);
}
#Transactional
public class RequestImpl implements Request{
public void doProcess(String name,String age){
// do what you want
}
}
your SpringConfig.xml stay the same and call code will change to:
Request req= applicationContext.getBean(Request.class);
req.doProcess("someName", "20");
Beside all, perform a ApplicationContext.getBean() and cast result to an implementation is (usually) bad pratice because Spring can proxy returned object and cast to implementation will fail with a ClassCastException
#user3269829 : By default the scope would be singleton now it is totally depend upon your requirement, if you want a bean object for every request then you can go for "prototype" and if you want to share single bean object among the multiple request then you can go for "singleton"
It depends on how your third party class is implemented. If you want to ensure a single instance of your class you can use factory-method of spring beans and ensure single instance.
Check "3.3.2.2 Instantiation with a static factory method" part of Spring Documentation
It should look like this in bean definition:
<!-- the factory bean, which contains a method called createInstance() -->
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
<!-- inject any dependencies required by this locator bean -->
</bean>
<!-- the bean to be created via the factory bean -->
<bean id="clientService"
factory-bean="serviceLocator"
factory-method="createClientServiceInstance"/>
and singleton creator:
public class DefaultServiceLocator {
private static ClientService clientService = new ClientServiceImpl();
private DefaultServiceLocator() {}
public ClientService createClientServiceInstance() {
return clientService;
}
}

Java Properties File binding to Java Interface

With GWT you have stuff like this:
public interface LoginConstants extends Constants {
#DefaultStringValue("Wellcome to my super app")
#Key("appDescription")
String appDescription();
#DefaultStringValue("Ok")
#Key("okButtonLabel")
String okButtonLabel();
}
Then you can use from your classes doing GWT.create(LoginConstant.class), in this way the interface is backed by dynamic implementation that, when I call loginConstants.appDescription() returns the value contained from a property file using the #Key annotation to reference the key in the property file. If the property file misses the property, then de #DefaultStringValue is returned. This is used for internationalization, but can possibly work also for configuration.
But with GWT, this is meant to be used on the client side (ie. translated to JavaScript), and for i18n, not for configuration.
But, I find this idea very convenient also for configuration handling.
I wonder if somebody knows a framework to do a similar thing on the server side, without necessarily bind your code to GWT. ie. if there is any library that implements this kind of logic specifically designed for the configuration handling. I am not aware of anything like this.
Reference to the feature in GWT: https://developers.google.com/web-toolkit/doc/latest/DevGuideI18nConstants
I implemented my own solution to the question:
BASIC USAGE
The approach used by OWNER APIs, is to define a Java interface
associated to a properties file.
Suppose your properties file is defined as ServerConfig.properties:
port=80
hostname=foobar.com
maxThreads=100
To access this property you need to define a convenient Java interface
in ServerConfig.java:
public interface ServerConfig extends Config {
int port();
String hostname();
int maxThreads();
}
We'll call this interface the Properties Mapping Interface or just
Mapping Interface since its goal is to map Properties into an easy to
use a piece of code.
Then, you can use it from inside your code:
public class MyApp {
public static void main(String[] args) {
ServerConfig cfg = ConfigFactory.create(ServerConfig.class);
System.out.println("Server " + cfg.hostname() + ":" + cfg.port() +
" will run " + cfg.maxThreads());
}
}
But this is just the tip of the iceberg.
Continue reading here: Basic usage || Website || Github
I still have a couple of features in mind, but the current implementation goes a little forward than the basic functionalities described in the questions.
I need to add samples and documentation.
I loved the idea so much that I quickly assembled some code using Java Dynamic proxies.
So basically you create an interface with relevant methods and annotate them with #Key, #DefaultStringValue annotations.
Below is the sample Java code:
Main.java
package net.viralpatel;
import net.viralpatel.annotations.DefaultStringValue;
import net.viralpatel.annotations.Key;
interface LoginConstants extends Constants {
#DefaultStringValue("Wellcome to my super app")
#Key("appDescription")
String appDescription();
#DefaultStringValue("Ok")
#Key("okButtonLabel")
String okButtonLabel();
}
public class Main {
public static void main(String[] args) {
LoginConstants constants = DynamicProperty.create(LoginConstants.class);
System.out.println(constants.appDescription());
System.out.println(constants.okButtonLabel());
}
}
Also the property file in background that we load is
config.property
okButtonLabel=This is OK
Just execute the Main java class, following output will be displayed:
Output:
Wellcome to my super app
This is OK
Here is the rest of code: http://viralpatel.net/blogs/dynamic-property-loader-using-java-dynamic-proxy-pattern/
You could mimic that with spring (but I'm not sure it's worth it):
#Component
public class SomeBean {
#Value("${appDescription:Wellcome to my super app}")
private String appDescription;
#Value("${okButtonLabel:Ok}")
private String okButtonLabel;
// accessors
}
with a PropertyPlaceHolderConfigurer.
I would like to consider the CDI as the following :-
The Qualifier
#Qualifier
#Retention(RetentionPolicy.RUNTIME)
#Target({
ElementType.METHOD,
ElementType.FIELD,
ElementType.PARAMETER,
ElementType.TYPE
})
#Documented
public #interface MessageTemplate {
#Nonbinding
String baseName();
#Nonbinding
Locale locale() default Locale.ENGLISH;
#Nonbinding
String key();
}
The Producer
public class CustomizedProducer {
#Produces
#MessageTemplate(baseName = "",
key = "")
public String createMessageTemplate(final InjectionPoint ip) {
MessageTemplate configure = null;
ResourceBundle bundle = null;
try{
configure = ip.getAnnotated().getAnnotation(MessageTemplate.class);
bundle = ResourceBundle.getBundle(configure.baseName(),
configure.locale());
return bundle.getString(configure.key());
} finally{
configure = null;
bundle = null;
}
}
}
The Service Configure
public class MyServiceConfigure {
#Inject
#MessageTemplate(baseName = "com.my.domain.MyProp",
key = "appDescription")
private String appDescription;
#Inject
#MessageTemplate(baseName = "com.my.domain.MyProp",
key = "okButtonLabel")
private String okButtonLabel;
//Getter
}
The working class
public class MyService {
#Inject
private MyServiceConfigure configure;
public void doSomething() {
System.out.println(configure.getAppDescription());
System.out.println(configure.getOkButtonLabel());
}
}
Regarding to the coding above you may use the java.util.Properties instead of the java.util.ResourceBundle and provide the default member to the Qualifier as well.
If you are running these under the JavaEE 6, the CDI is already enable for you. Just put the empty beans.xml to the META-INF or WEB-INF. If you are running under the Java SE you may need a bit further work as mentioned at the Weld web site and its documentation.
I'm using the CDI as a main part of my current production project and it works quite well.
EDITED:-
The good point to use the CDI is the Scope, we may produce the #MessageTemplate as the #ApplicationScope,#SessionScoped, #RequestScoped, #ConversationScoped or the pseudo-scope as #Singleton or #Depenendent
If you annotate the MyServiceConfigure as #Named, it is ready to use at the JSF as well.

Abstract or annotated class instead interface as MXBean

Is there a way to use abstract or annotated class as MXBean descriptor? I have interface like:
#MXBean
public interface Peer {
public String getName();
}
and want that MXBean to be combined in class with more local-side-only methods like:
public class PeerCombinedMXBean {
// Expose this as MXBean attribute
public String getName() { ... }
// This method is local-instance-oriented
public boolean isValid() { ... }
}
I need model like above to avoid chain-in proxy object instead to use complex half-proxified instance like:
PeerCombinedMXBean peer = JMX.newMXBeanProxy(connection, name, PeerCombinedMXBean.class);
if (peer.isValid()) System.out.println(peer.getName());
Edit
This question is related to java.net article. What is they progress? Can I use MBeans with annotation safely now?
What I ended up doing for this was writing a custom annotation that you place on a method or property. Then, I implemented the DynamicMBean interface in such a way that it parsed out the annotations on the class in question and then registers them with the PlatformMBeanServer. As far as I know, there are no public implementations of this available, I also searched extensively about this topic before I just did it myself.
For example, here is the class that I wish to manage from JConsole:
public class Foo
{
// In JMX Console
#Managed
private boolean isBar;
// Not in JMX Console
private boolean isFoo;
// In JMX Console
#Managed
public String getClassName()
{
return Foo.class.getName();
}
}
Then, when my application starts up, I register an instance of this class using my implementation of DynamicMBean and parse out the annotations.

Categories

Resources