One of the drawbacks of JMX is the lack of cluster support, you have
to invoke the operation in each one of the servers. The solution? use a
JMX client that does that for you, as jManage.
You setup the servers as in any other administration console and then
you can group them in clusters, allowing you to see the value of the
properties in each one of the servers in the cluster and invoke operations
in all of them getting the results of each server in a single page.
Category Archives: development
Using jManage with JBoss 4
Download jManage version 0.5.3.
Go to jmanage-0.5.3/modules/jboss and copy there the following jars from jboss installation.
- jboss-4.0.2/client/jbossall-client.jar
- jboss-4.0.2/lib/jboss-jmx.jar
Start JBoss servers with the java option -Djava.rmi.server.hostname=hostname (you can set JAVA_OPTS environment variable)
Run jManage with jmanage-0.5.3/bin/startup.sh, you’ll be asked for a password (123456 by default). Then you can login at http://localhost:9090 with username/password admin/123456
Hibernate 3.0.5 statistics + TreeCache bugs
When working at a client site we decided to enable Hibernate
statistics, so we can access all this information about cache
hits/misses, transactions, entities,… and all kind of cool stuff
through a JMX interface at runtime, allowing runtime configuration
changes and monitoring.
But seems that not many people is using this feature, because we
got the frustrating NullPointerException. After debugging a bit through
the Hibernate sources (if you have ever tried you know that it’s a PITA) I found the errors, same exception in two places,
and told JBoss support (the client was paying for it). Anyway I fixed them
locally while they fixed them in CVS, see the cvs diff or the JIRA issue. This bugs are present in hibernate 3.0.5 when using TreeCache.
Now we can get a lot of useful information at runtime, through a JMX console, I really like jManage,
mostly due to it’s cluster support, but you’ll need some tricks to make
it run with JBoss 4, that I’ll post in a separate entry.
dbUnit, useful more than just for unit tests
I really like dbUnit for unit tests, but I like it more for other
tasks, as exporting data from the database in xml or Excel formats with
a few lines of code and without bothering about writing xml tags or
interacting with POI to write Excel cells.
For
instance the next code can be used to export the result of a query into
an Excel file.
public class Report {
private DataSource dataSource;
public void exportData() throws Exception {
IDatabaseConnection connection = new DatabaseConnection(dataSource
.getConnection());
try {
// partial database export
QueryDataSet partialDataSet = new QueryDataSet(connection);
String query =
"SELECT a, b FROM t WHERE a = 'whatever'");
partialDataSet.addTable("Report", query);
XlsDataSet.write(partialDataSet, new FileOutputStream(
"report.xls"));
} finally {
connection.close();
}
}
Maven tips and Tricks: Avoid running tests twice
Sometimes you may find that your tests are run twice, once to make
the report for the site (thus not breaking the build if they fail) and
second time to create a jar, war or any other artifact, and probably in
this step you want the build to break if tests don’t succeed. This is
very common in a continuous integration scenario where the machine with
CruiseControl or any other CI tool deploys the site and generated
artifacts.
My suggestion is to create a goal in your maven.xml like this
<goal name="continuousintegration">
<attainGoal name="clean"/>
<attainGoal name="site:deploy"/>
<!-- avoid running tests again -->
<j:if test="${maven.test.failure}">
<fail message="There were test failures."/>
</j:if>
<j:set var="maven.test.skip" value="true"/>
<attainGoal name="jar:deploy"/>
<j:set var="maven.test.skip" value="false"/>
</goal>
The trick is checking the maven.test.failure property after creating
the site, if it’s true the build has to fail and if it’s false you can
skip tests in next steps.
Maven tips and Tricks: Perforce
Lately I had the bad time to use the Perforce SCM system. I created a maven goal to sync (=cvs update) my sources from the SCM.
You need:
- jakarta oro as a dependency in your project.xml and loaded by the root classloader.
<!--
| Oro is needed by the Perforce tasks and needs to be loaded
| by the root classloader
+-->
<dependency>
<groupId>oro</groupId>
<artifactId>oro</artifactId>
<version>2.0.8</version>
<properties>
<classloader>root</classloader>
</properties>
</dependency>
- The actual goal in maven.xml
<!-- perforce --> <goal name="p4sync"> <p4sync view="//depot/whatever/..." /> </goal>
You can check all the perforce ant tasks you can use besides p4sync.
Cobertura, an open source alternative to Clover
Cobertura is a free Java tool that calculates the percentage of code
accessed by tests. It can be used to identify which parts of your
Java program are lacking test coverage. It is based on jcoverage, but more actively developed.
I will talk about the maven cobertura plugin,
after releasing the first two versions (7/11 and 7/21) you can have
cool reports about test coverage and the ability to see all the classes
that don’t meet your minimum coverage criteria, both at line and branch
level.
The first report about code coverage is pretty similar to the one provided by Clover, but the second one
makes the difference, not provided by clover and in fact neither by
cobertura ant tasks, just the maven plugin. Another interested feature
to be used for instance in conjuction with a continuos integration tool
as CruiseControl is the option to make the build fail if any of the
classes test coverage fails below a threshold you can set. AFAIK clover
only allows to fail the test if the overall code coverage doesn’t meet
the requirements, not class by class, which is very convenient.
To use it in your maven projects you can add the dependency to the plugin
<dependency>
<groupId>maven-plugins</groupId>
<artifactId>maven-cobertura-plugin</artifactId>
<version>1.1</version>
<type>plugin</type>
</dependency>
and the report
<report>maven-cobertura-plugin</report>
I hope you find it useful.
Inheriting annotations from implemented interfaces
In relation to Rick Hightower entry on annotations and inheritance I also checked if annotations on implemented interfaces are accesible
from the class implementing them. The answer is NO, neither using the
@Inherited annotation on the annotation class. The only way is getting
the implemented interfaces and iterate over them to see if they have
annotations.
public class AnnotationTest extends TestCase {
@Retention(RetentionPolicy.RUNTIME) // This makes the annotation available at runtime
@Inherited
public static @interface Developer {
String name();
String email() default “[email protected]”;
int rank() default 1;
}
// Using the annotation to decorate a class and a method
@Developer(name = “RickHightower”)
interface MyInterface {
@Developer(name = “ScottFauerbach”, email = “[email protected]”)
void myMethod();
}
class MyClassSub implements MyInterface {
public void myMethod() {
// …
}
}
// Testing the annotation
public void testAnnotation() throws Exception {
assertFalse (MyClassSub.class.isAnnotationPresent(Developer.class));
Method method2 = MyClassSub.class.getMethod(“myMethod”, (Class[]) null);
assertFalse (method2.isAnnotationPresent(Developer.class));
Class[] interfaces = MyClassSub.class.getInterfaces();
boolean annotationPresent = false;
for (Class iClass : interfaces) {
if (iClass.isAnnotationPresent(Developer.class)) {
annotationPresent = true;
break;
}
}
assertTrue(annotationPresent);
}
}
Spring Framework 1.2.2 released
Juergen has annonced the release of Spring 1.2.2, which I’ll make
available for maven users in a few hours through the central repository
at ibiblio. This has came out before having time to finish the Maven 2
POMs for 1.2.1, so I’ll try to update them to 1.2.2 asap.
Dear Spring community,
I’m pleased to announce that Spring 1.2.2 has just been released. This is a
bugfix and minor enhancement release. It also provides a unified basis for
the upcoming Spring WebFlow release candidate.
Besides refinements in the JTA transaction synchronization and SQLException
translation, this release introduces a variety of internal refactorings and
new helper classes. Furthermore, support for JDK 1.5’s XML-based properties
format has been added to all relevant Spring classes.
We have also extended our reference documentation in various areas. Most
importantly, it covers JDO, TopLink, OJB, and JCA CCI now.
Cheers,
Juergen
Spring: creating a bean of type java.util.Properties
I don’t know if there’s a simple way to crate a Spring bean of type java.util.Properties . This is what I needed to do.
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" depends-on="hibernateProperties.load">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="configLocation"><value>classpath:net/lmb/resources/hibernate.cfg.xml</value></property>
<property name="configurationClass"><value>org.hibernate.cfg.AnnotationConfiguration</value></property>
<property name="hibernateProperties"><ref local="hibernateProperties"/></property>
</bean>
<bean id="hibernateProperties" class="java.util.Properties"/>
<bean id="hibernateProperties.load" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject"><ref local="hibernateProperties"/></property>
<property name="targetMethod"><value>putAll</value></property>
<property name="arguments">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.query.substitutions">${hibernate.query.substitutions}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">${hibernate.cglib.use_reflection_optimizer}</prop>
<prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
<prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
<prop key="hibernate.connection.username">${hibernate.connection.username}</prop>
<prop key="hibernate.connection.password">${hibernate.connection.password}</prop>
</props>
</property>
</bean>
Basically you need to create an empty bean of type java.util.Properties, and after you add the properties using Spring <props> syntax calling the method putAll. One of the tricky parts is that you need to explicitly state the depends-on attribute in the LocalSessionFactoryBean so properties get loaded before the hibernate session is created.
Update:
Marc Logemann has posted a much more elegant solution using Spring’s PropertiesFactoryBean
<bean id="hibernateProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.query.substitutions">${hibernate.query.substitutions}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">${hibernate.cglib.use_refl}</prop>
<prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
<prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
<prop key="hibernate.connection.username">${hibernate.connection.username}</prop>
<prop key="hibernate.connection.password">${hibernate.connection.password}</prop>
</props>
</property>
</bean>