JmxResource published with simplejmx does not appear in JConsole - java

I am using simplejmx to publish my JMX Resources.
I have got jmx-config.xml
<bean id="beanPublisher" class="com.j256.simplejmx.spring.BeanPublisher">
<property name="jmxServer" ref="jmxServer" />
</bean>
<bean id="jmxServer" class="com.j256.simplejmx.server.JmxServer"
init-method="start" destroy-method="stop">
<property name="registryPort" value="8123" />
</bean>
I am starting my JBoss application, everything is ok:
15:20:11,860 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] (MSC service thread 1-8) Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#1be30160: defining beans [...,beanPublisher,jmxServer,...]; root of factory hierarchy
I created a simply class.
package com.mypckg.jmx;
import com.j256.simplejmx.common.JmxAttributeField;
import com.j256.simplejmx.common.JmxResource;
#JmxResource(description = "Blah1", domainName = "Blah2", beanName = "Blah3")
public class DummyJMX {
#JmxAttributeField(description = "Blah4")
private int var = 3;
}
I am starting JConsole, I am choosing JBoss application and I am going to MBeans. That is what I see:
*
Probably, my DummyJMX class has not been published (or I just cannot find it).
About which step I forgot?
Thank you in advance
EDIT :
EDIT :
#Andrei Stefan
An error which I got using your link:
#Gray
An error which I got using localhost:8123:

Try the following url in JConsole, with Remote Process option: service:jmx:rmi:///jndi/rmi://localhost:8123/jmxrmi
It's a bit different than what I provided in the comments.

Finally, I am connected to my JMX Beans using JConsole.
Probably, I did something wrong in the beginning of my work with simplejmx.
I have not changed a lot of things. I kept jmx-config file and I still use version 1.8 of simplejmx.
I can easily connect to this bean locally - I have no idea why I was not able to do that earlier. Could you tell me, why in your opinion it should not be a local process?
Below, you can see that my JMX Bean appears in JConsole:

Probably, my DummyJMX class has not been published (or I just cannot find it).
When you are using the registryPort configuration for JmxServer then it will not show up in the "Local Process" list under Jconsole. It will be able to be accessed as a "Remote Process" with localhost:8123. If you are on a Linux box, you might use netstat -an | grep LISTEN to see what ports your application is listening on. If you don't see 8123 in the list then maybe it already has a RMI server configured?
If you want to use the platform mbean-server which does show up as a local process then use the new setter or constructor in version 1.9 which was released recently (4/2014). Unfortunately, SimpleJMX cannot programmatically register itself so it shows up in the process list -- that's not code that the JVM exports.
<bean id="jmxServer" class="com.j256.simplejmx.server.JmxServer"
init-method="start" destroy-method="stop">
<property name="usePlatformMBeanServer" value="true" />
</bean>

Related

BridgePropertyPlaceholderConfigurer camel bean

I use the following bean to manage properties in camel as below :
<bean id="ilePropertiesConfigurer"
class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer">
<property name="properties" ref="allProperties" />
</bean>
allproperties is a java class. it works very well when starting the application.
But now, I want to update properties without restarting my application. I update allproperties but it still takes the old values.
Can you help me?
This is not supported in Apache Camel with that Spring property placeholder bridge. You need to restart your application.
OSGi Blueprint has a concept of allowing to reload/restart your application when properties are changed, but it does a full bundle restart command.

HTTP Proxy Setup For Java JVM

Setting up an HTTP proxy for Java JVM 6.x isn't working for me; I'm hoping someone can spot what I'm missing.
I have a Java application deployed on JBOSS 5.1.2 that makes several calls to external web services. I'd like to be able to intercept these calls using a proxy: Fiddler version 4.4.8.0.
After doing an SO search I added the following flags to my JBOSS VM parameters at startup:
-DproxySet=true -Dhttp.proxyHost=localhost -Dhttp.proxyPort=8888 -Dhttps.proxyHost=localhost -Dhttps.proxyPort=8888
I'm running JBOSS in IntelliJ 14.
I can see traffic from the browser to the application if I start JBOSS, Fiddler, and open the UI in Chrome. I do not see any calls from JBOSS to external services being intercepted. I thought I would see all the calls from JBOSS to external services in addition to those from the browser to JBOSS.
Update:
I tried adding these to properties-service.xml per this SO answer - no joy.
I'm running Spring 3, using Apache HttpClient as my web service client. I'm going to look into configuring proxy just for it.
Thanks to bmargulies and anyone else who looked at this. I have a solution that I hope will help someone else.
Adding -Dhttp.proxyHost parameters to my JVM startup options did nothing.
Adding those same parameters to JBOSS 5.1.2 configuration in my deployment properties-services.xml did nothing.
I believe that using Spring 3.x is a factor in explaining this behavior. I had to tell the Spring web service clients to use a proxy.
I added some Spring beans to wire in a Fiddler proxy HttpClient and injected that into the web service client, replacing the non-proxied version.
It failed the first time I tried it. It took me a while to figure out that the Apache Commons HttpConfiguration class didn’t follow the Java bean standard, so Spring blew up when it tried to wire it. I had to use the Spring MethodInvokingFactoryBean to get around it.
Here's the pertinent Spring configuration XML:
<!-- New beans for Fiddler proxy -->
<bean id="fiddlerProxyHost" class="org.apache.commons.httpclient.ProxyHost">
<constructor-arg name="hostname" value="localhost"/>
<constructor-arg name="port" value="8888"/>
</bean>
<bean id="fiddlerProxyHostConfiguration" class="org.apache.commons.httpclient.HostConfiguration"/>
<bean id="fiddlerProxyHostSetter" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="fiddlerProxyHostConfiguration"/>
<property name="targetMethod" value="setProxyHost"/>
<property name="arguments" ref="fiddlerProxyHost"/>
</bean>
<bean id="fiddlerProxyClient" class="org.apache.commons.httpclient.HttpClient">
<property name="hostConfiguration" ref="fiddlerProxyHostConfiguration"/>
</bean>
Now I can see the calls from the application to the web service in Fiddler. Joy!
Those parameters, first and foremost, are read by HttpURLConnection. They are specific to HTTP, of course, and so any other means of connecting to the outside world will necessarily ignore them.
There are many good reasons for code to avoid HttpURLConnection and just open a TCP connection through a plain old socket, even if that code plans to talk HTTP. HttpURLConnection has several 'browser emulation features' that get in the way. For example, it's broken for CORS and rejects some legitimate HTTP verbs.
Code that does that and in turn happens to do HTTP might choose to respect those parameters, and it might not. For example, I'm reasonably sure that the Apache Commons HTTP library gives the caller a choice.
If you put JBoss in a debugger and break on the socket connection primitives, I think you'll find out what's happening to you pretty quick in this respect.

How do I create a TopicConnectionFactory for MQSeries in Spring?

I have read the article http://techtots.blogspot.com/2010/01/connecting-to-mq-using-spring-without.html about configuring QueueConnectionFactories and have that side of things working nicely.
# MQ related values
mq.jms.qcf=QM_Epsilon
mq.jms.request.queue=TEST.REQUEST.QUEUE
# Connection details
mq.host.url=localhost:1414/SYSTEM.DEF.SVRCONN
mq.factoryclass=com.ibm.mq.jms.context.WMQInitialContextFactory
# Authentication details
mq.auth=simple
mq.user=******
mq.password=********
<bean id="queueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${mq.jms.qcf}" />
<property name="resourceRef" value="false" />
<property name="jndiEnvironment">
<props>
<prop key="java.naming.factory.initial">${mq.factoryclass}</prop>
<prop key="java.naming.provider.url">${mq.host.url}</prop>
<prop key="java.naming.security.authentication">${mq.auth}</prop>
<prop key="java.naming.security.principal">${mq.user}</prop>
<prop key="java.naming.security.credentials">${mq.password}</prop>
</props>
</property>
</bean>
Using this configuration the queueConnectionFactory bean is easily injected into my classes as an MQQueueConnectionFactory.
But I am wanting to use the publish/subscribe model and, as I understand it, I need to get an MQTopicConnectionFactory for this. I have searched everywhere and tried numerous things but I cannot find any information on how to modify this configuration, or the MQ installation so that I get an MQTopicConnectionFactory instead of an MQQueueConnectionFactory.
The WMQInitialContextFactory is a class that implements a JNDI provider over a WebSphere MQ queue. Instead of the managed objects being stored in a .bindings file or LDAP, they are serialized and stored in a queue and this class allows you to treat that queue as just another JNDI store. This class was only ever intended to be a JNDI provider and not a replacement for the actual IBM JMS implementation. Since storing managed objects on a topic would not work, these classes have no topic factories in them. This is as expected.
In my opinion, the problem with WMQInitialContextFactory is that it must first connect to WebSphere MQ in order to to obtain a connection factory which then tells the app - you guessed it - how to connect to WebSphere MQ. This makes the article that was linked confusing because it appears that all that configuration, the WMQ connection details and so forth, are for the benefit of the application when in fact they just bootstrap a JNDI provider which is expected to have defined connection factory objects with all this same information.
What is missing from the article is that the author would have had to use IBM's JMSAdmin tool to connect to the MQInitialContext and define the ConnectionFactory and other administered objects before connecting the application to that same Initial Context in order to access them.
For the record, the WebSphere MQ JMS classes have supported JMS 1.1 ConnectionFactory and Destination classes for quite some time now. Prior to that they supported both queues and topics as per the JMS 1.0 spec.
You can download the IBM WMQ JMS implementation as SupportPac MQC7. There is a lot more there than just the jar files. For example, you get lots of sample code, diagnostic and trace utilities, documentation, etc. You also get the correct jar files.
If you want to use a .bindings file (File-system initial context) instead of the WMQInitialContextFactory, download the latest WebSphere MQ Explorer tool as SupportPac MS0T. You can create a directory, point WMQ Explorer to it and define all your connection factories and destinations. (Or go with domain-specific QueueConnectionFactory and TopicConnectionFactory if you rock it old school.) More information on using WMQ Explorer to define your managed objects may be found at: Creating and configuring JMS administered objects
If you want a tutorial that includes a demonstration of how to use IBM's JMSAdmin tool to create the .bindings file, look at Running a standalone Java application on WebSphere MQ V6.0. (The JMSAdmin tool is installed with the WMQ Server and I believe it also comes with the free MS0T WMQ Client install linked above.) The documentation for the JMSAdmin tool is here: Using the WebSphere MQ JMS administration tool
Whichever method you choose to create managed objects, you can look up all the possible properties supported in IBM's implementation at: Properties of WebSphere MQ classes for JMS objects

Can't see JMX entries in jconsole when using Tomcat JDBC Connection Pool

we're evaluating switching over from the C3P0 connection pool to the Tomcat JDBC Connection Pool (as described here).
It appears to work as a connection pool but I can't seem to see any JMX entries for it when I run jconsole.
Out of the box C3P0 gives lots of operations and attributes via JMX, the Tomcat
JDBC Connection Pool gives none (for me).
According to the page linked above there is a jmxEnabled flag that defaults to true. I've set this explicitly but it seems to make no difference.
What am I missing?
I'm running a fairly standard Java6/Spring/Hibernate app by the way.
If you configure pool in your spring context, you should export bean manually. Autoexport works only if you confiugre pool in tomcat container and import it from JNDI. See http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html#JMX
You may use this spring config for export pool information to JMX:
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource">
... skipped ...
</bean>
<bean id="jmxExporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="beans">
<map>
<entry key="bean:name=DataSource" value="#{dataSource.getPool().getJmxPool()}"/>
</map>
</property>
</bean>
Config works only in Spring version 3.0 and above, because it uses spring expression language
Do you see any entries under the tree
Catalina -> DataSource -> javax.sql.DataSource
This lists the number of active connections, idle connections, and a few other common stats.
Other then that, what kind of information are you hoping to get out of monitoring?
Darren, if you don't see the object name under Catalina/DataSource/javax.sql.DataSource/<name> in JConsole, then I wonder if the datasource is defined incorrectly or perhaps it was not connected to the database when Tomcat was started.
Bruce
In support of Sean's post:
The placement of the javax.sql.DataSource entry in MBeans of JConsole is:
Catalina
DataSource
/[Name_of_deployed_application] // e.g. "/DomainService
/[Host_name_of_the_deployed_application] //e.g. "localhost"
javax.sql.DataSource

Out of container JNDI data source

I would like to configure a DataSource using JNDI in a Java SE app. What is the best way to do this?
So far, I've come across 2 projects:
Apache Naming. The project page has a specific example for configuring a data source, but it looks like the project is super old and no longer active.
JBossNS. It looks like it's easy to configure a local-only JNDI using LocalOnlyContextFactory, but I haven't found any docs on how to actually configure a data source.
If possible, I would like to also configure the data source with a JTA transaction manager (using JOTM?).
Why are you using JNDI for this? It's not that it's a bad solution if you have a provider but there are alternatives such as dependency injection (IoC: via Spring or Guice).
The Spring JDBC data access is described here. The great thing is that you can use Spring to inject a DataSource into your code:
<bean class="com.my.Persister">
<property name="dataSource" ref="dataSource" />
</bean>
The data source can be defined using a JNDI-lookup:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource" />
In a test environment, you could inject the data source directly:
<bean id="dataSource" class="apache.db.PoolingDataSource">
<!-- config goes here -->
</bean>
These references are pretty old but may help to use jnpserver (JBoss Naming Service provider):
Working With JNDI In A J2SE Application
Standalone JNDI server using jnpserver.jar
A very easy to use solution for stand-alone JNDI is simple-jndi. It works like a charm as long as you only need it within a single JVM, since it's a library no network server.
The Simple-JNDI version, referenced by klenkes74, is not under active development any more. Because I encountered some issues with it I forked it, did some bug fixes and implemented some new features. I already used the old version not only for testing but in production too because I prefer a Service Locator pattern over Dependency Injection although the latter one is more trendy nowadays.
You can easily use Simple-JNDI to define a DataSource or a connection pool declaratively and get it bound to a JNDI Context.
Define a jndi.properties file in your classpath:
java.naming.factory.initial=org.osjava.sj.SimpleContextFactory
org.osjava.sj.root=[absolute_or_relative_path_to_a_property_file]
The property file looks like:
type=javax.sql.DataSource
driver=org.gjt.mm.mysql.Driver
url=jdbc:mysql://localhost/testdb
user=testuser
password=testing
Now you can access your DataSource from inside your code this way:
InitialContext ctxt = new InitialContext();
DataSource ds = (DataSource) ctxt.lookup("name_of_your_datasource");
For more information see https://github.com/h-thurow/Simple-JNDI

Categories

Resources