Who’s On Phirst

Official blog of Phurnace Software.

Wesley Willard's Blog
Description:
My name is Wesley Willard, and I am a Staff Engineer at Phurnace. I have been a software developer for 22+ years. The first 13 years of my career were spent working in C/C++, primarily in the area of Oil/Gas software development. For the last 9 years, I have been doing mostly Java, both client and server-side development, with various companies in Austin.

Posted by: Wesley Willard on

To a non-geek, spending a weekend in hotel conference rooms listening to presentations on the latest technologies in software development might make them beg, "just shoot me now, please". But to someone interested in keeping abreast of these sorts of things, for both company and personal reasons, it was a very nice way to do just that. Plus, it was hot as hell outside, the neighborhood pool is even hot, and the lake is just too far away.

The Lone Star Symposium was held this past weekend here in Austin, and it was a great show. The lack of vendor presence at these conferences allow software developers to focus on the technology itself. The people who put this conference together go out of their way to provide all the amenities to the attendees, such as good food, snacks, not to mention some of the best industry experts out there. With regard to the experts, I am always pleased to find not only those who write about the technologies at this show, but also those who have had a hand in developing them. A case in point, the presenter for the Spring Framework was Keith Donald, one of principals and founders.

It's always a shame that you can't make it to all the sessions in this type of conference, but you generally can't go wrong with any selection. Just to sort of sum up, the hottest topics this year were the ones concerning dynamic languages, such as Groovy, and it's related framework, Grails. Also, Spring continues to be THE overarching framework for J2EE development.

My favorite session, though, was one by Neil Ford, titled "Productive Programmer: Acceleration & Automation". I am a sucker for cool command line tools, and he talked about such great productivity enhancers such as Auto-Hot Key, which allows you to define (and redefine) hot keys in Windows, and clcl, which allows you to maintain multiple clipboards. I am very keyboard-oriented, and these tools will allow me to stay away from my carpal-inducing mouse.

Next time one of these conferences makes its way near you, check it out. Especially if its a hot summer weekend!

In Spring FrameworkGroovy
Comment (0) Read More...


Posted by: Wesley Willard on

The Spring Framework has become the most popular open source application framework in the Java space in recent years. One of its most powerful features is its ability to allow developers to create Spring Beans, which can be configured together to create an application's object graph, or data structure. The framework provides a consistent interface to accessing these beans which avoids unnecessary dependencies between components.

JMX (Java Management Extensions) is a technology that enables the configuration, instrumentation, and monitoring of Java applications of all sorts, both J2SE and J2EE. It has gained wide-spread acceptance in the Java community as the standard API for these tasks. JMX provides access to MBeans (JMX's version of Spring's Beans), which compose its management interface. This is handled through a software layer known as the MBeanServer.

One useful piece of the Spring Framework is its direct support for JMX. Spring provides the ability to register its Beans in an MBeanServer, which can then be interrogated and modified by management applications by Spring Bean interface methods. The interface to Spring Beans is more intuitive and easier to use than the MBean interface, and abstracts many complicated details.

The follow example shows how Spring JMX can be used to provide remote management capability of its Beans. It will illustrate both server and client configuration and code. It will assume some Spring and JMX knowledge.

First, I create the Spring server-side application context configuration:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
 "http://www.springframework.org/dtd/spring-beans.dtd"> 
 
<beans>
    <bean id="registry" class=
"org.springframework.remoting.rmi.RmiRegistryFactoryBean">
        <property name="port" value="1090"/>
    </bean>
    
    <bean id="exporter" 
class="org.springframework.jmx.export.MBeanExporter" 
lazy-init="false"
         <property name="beans">
             <map>
                 <entry key="spring:name=jmxBean">
                     <ref local="jmxBean"/>
                 </entry>
             </map>
         </property>
         <property name="assembler" ref="assembler" />
         <property name="server">
             <ref local="mbeanServer"/>
         </property>
    </bean>
 
    <bean id="mbeanServer" 
        class="org.springframework.jmx.support.
MBeanServerFactoryBean"/> <bean id="jmxBean" class="com.phurnace.JmxBeanImpl"> <property name="name"> <value>Daffy Duck</value> </property> <property name="rating"> <value>5</value> </property> </bean> <bean id="jmxAttributeSource" class="org.springframework.jmx.export.annotation.
AnnotationJmxAttributeSource"/> <bean id="assembler" class="org.springframework.jmx.
export.assembler.MetadataMBeanInfoAssembler"> <property name="attributeSource" ref="jmxAttributeSource"/> </bean> <bean id="serverConnector" class="org.springframework.jmx.support.
ConnectorServerFactoryBean"> <property name="objectName" value="connector:name=rmi"/> <property name="serviceUrl" value="service:jmx:rmi://localhost/jndi/rmi://localhost:
1090/myconnector"/> </bean> </beans>

The MBeanExporter class is used to specify the Spring Beans that are to be exposed via JMX by the MBeanServer. The MBeanServer is implemented by the Spring MBeanServerFactoryBean class. In this example, it will expose the specifed Beans via RMI. If there is an existing MBeanServer, such as in a web container like Tomcat or JBoss, Spring JMX will use that one. Spring also allows for the specification of an RMI registry for the MBeanServer. It will be started when the application context file is loaded.

The AnnotationJmxAttributeSource and MetadataMBeanInfoAssembler classes are used allow Java 5 Annotations to indicate which classes and methods which will be exposed in the MBeanServer.

The final bean in the configuration file configures a ConnectorServerFactoryBean to provide remote access to the Spring Beans. This connector will be running over RMI, on port 1090.

Now, I configure the Spring Bean (jmxBean), which looks a whole lot like a standard Java Bean:


//
// Interface class
//
package com.phurnace;

public interface JmxBean {
    public String getName();
    public void setName(String name);
    public int getRating();
    public void setRating(int rating);
}



//
// Implementation of JmxBean interface
//
package com.phurnace;

import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedResource;

@ManagedResource(objectName=
"spring:name=jmxBean", description="Managed Bean")
public class JmxBeanImpl implements JmxBean {
    private String name;
    private int rating;

	
    @ManagedAttribute(defaultValue="animal")
	public String getName() {
		return name;
	}
     
    @ManagedAttribute
       (description="Name Attribute",
        defaultValue="animal")
	public void setName(String name) {
		this.name = name;
		System.out.println("Setting name to " + this.name);
	}

	@ManagedAttribute
	    (description="Rating Attribute")
	public int getRating() {
		return rating;
	}

	public void setRating(int rating) {
		this.rating = rating;
	}
}

As I indicated before, Spring allows usage of Java 5 Annotations to specify which classes and methods will be loaded into the MBeanServer, as well as metadata about them. Annotations are straight-forward to use, and provide great visibility to the developer as to which methods are exposed.

Finally, here is an example server, which loads up the Spring application context file.


package com.phurnace;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.
ClassPathXmlApplicationContext; public class SpringJmxServer { private static Logger logger =
Logger.getLogger(SpringJmxServer.class); /** * @param args */ public static void main(String[] args) { org.apache.log4j.BasicConfigurator.configure(); ApplicationContext ctx = new
ClassPathXmlApplicationContext("/com/phurnace/server-jsr160.xml"); if (ctx != null) { logger.info
("Successfully loaded ApplicationContext"); } JmxBean jmxBean = (JmxBean) ctx.getBean("jmxBean"); String name = jmxBean.getName(); logger.info("Name is " + name); while ( !name.toUpperCase().equals("EXIT") ) { try { Thread.sleep(5000); name = jmxBean.getName(); } catch (Exception e) { logger.error("Trapped error " +
e.getMessage()); System.exit(1); } } System.exit(0); } }

Now, on to the client-side of things. First, I will show how to access the Spring Bean as a standard JMX client:


package com.phurnace;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import org.apache.log4j.Logger;

public class TestJmxClient {
	private static Logger logger = Logger.getLogger(
TestJmxClient.class); private final String objectNameStr = "spring:name=jmxBean"; private final String jmxRmiStr = "service:jmx:rmi://localhost/jndi/rmi://localhost:1090/
myconnector"; private ObjectName objectName; private JMXServiceURL jmxUrl; private JMXConnector jmxConnector; private MBeanServerConnection mbsc; /** * @param args */ public static void main(String[] args) { org.apache.log4j.BasicConfigurator.configure(); if (args.length == 0) { logger.info("Usage: java com.phurnace.
TestJmxClient "); System.exit(0); } TestJmxClient jmxClient = new TestJmxClient(); jmxClient.init(); jmxClient.accessBean(args[0]); System.exit(0); } public void init() { try { objectName = new ObjectName(objectNameStr); jmxUrl = new JMXServiceURL(jmxRmiStr); jmxConnector = JMXConnectorFactory.connect
(jmxUrl); mbsc = jmxConnector.getMBeanServerConnection(); } catch (Exception e) { logger.error("Error initializing
connection"); } } public void accessBean(String newName) { String name = getName(); if (name == null) { return; } logger.info("Original name is " + name); logger.info("Setting new name to " + newName); setName(newName); // // Access the name again to check it's value // name = getName(); if (name == null) { return; } logger.info("New name is " + name); } private void setName(final String name) { final String operationName = "setName"; try { Object[] params = new Object[1]; params[0] = name; String[] signature = new String[1]; signature[0] = new String("java.lang.String"); mbsc.invoke(objectName, operationName, params, // no parameter signature ); } catch (Exception e) { logger.info( "Error setting name value in bean "
+ e.getMessage()); } } private String getName() { final String operationName = "getName"; try { final String status = (String) mbsc.invoke(objectName, operationName, null, // no parameter null ); return status; } catch (Exception e) { logger.info("Error getting name value from
bean " + e.getMessage()); } return null; } }

This example does not need any Spring classes to access the MBean, even though it is created on the server as a Spring Bean. The test client accesses the MBeanServer via the RMI protocol.

You may notice that in order to make a connection to the MBeanServer, several intermediate objects must be created, such as a JMXServiceURL, a JMXConnector, and a MBeanServerConnection. In the process of creating these objects, checked exceptions must be handled.

This leads me to my final piece of code, which illustrates the same functionality, but is implemented using Spring.

First, here is a client-side Spring configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
 "http://www.springframework.org/dtd/spring-beans.dtd">
 
<beans>
 
<bean id="clientConnector" class=
"org.springframework.jmx.support.MBeanServerConnectionFactoryBean">
  <property name="serviceUrl" value=
"service:jmx:rmi://localhost/jndi/rmi://localhost:1090/myconnector"/>
</bean>
 
<bean id="proxy" class=  
"org.springframework.jmx.access.MBeanProxyFactoryBean">
  <property name="objectName" value="spring:name=jmxBean"/>
  <property name="proxyInterface" value="com.phurnace.JmxBean"/>
  <property name="server" ref="clientConnector"/>
</bean>
 
</beans>
This configuration file configures an MBeanServerConnectionFactoryBean to provide the client with a connection to the server, via the RMI protocol. Then, an MBeanProxyFactoryBean is configured to create a proxy for the MBean registered under the specified ObjectName. Finally, the client connection bean is referenced, to allow remote access. Finally, here is the the Spring client:

package com.phurnace;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.
ClassPathXmlApplicationContext; public class TestSpringJmxClient { private static Logger logger = Logger.getLogger
(TestSpringJmxClient.class); private ApplicationContext ctx; private JmxBean jmxBean = null; /** * @param args */ public static void main(String[] args) { org.apache.log4j.BasicConfigurator.configure(); if (args.length == 0) { logger.info("Usage: java com.phurnace.
TestSpringJmxClient "); System.exit(0); } TestSpringJmxClient jmxClient = new TestSpringJmxClient(); jmxClient.init(); jmxClient.accessBean(args[0]); System.exit(0); } public void init() { ctx = new ClassPathXmlApplicationContext
("/com/phurnace/client-jsr160.xml"); if (ctx != null) { logger.info("Successfully loaded
ApplicationContext"); } jmxBean = (JmxBean)ctx.getBean("proxy"); } public void accessBean(String newName) { String name = getName(); if (name == null) { return; } logger.info("Original name is " + name); setName(newName); name = getName(); if (name == null) { return; } logger.info("New name is " + name); logger.info("Rating is " + jmxBean.getRating()); try { jmxBean.setRating(10); } catch (Exception e) { logger.warn("Unable to set rating -
attribute is read-only"); } logger.info("Rating is still " +
jmxBean.getRating()); } private String getName() { return jmxBean.getName(); } private void setName(String name) { jmxBean.setName(name); } }

You might notice that the code is much more concise and clean. Except for the loading of the application context file, and the Bean access, there are no references to Spring code needed.

A try-catch block wraps the call JmxBean.setRating(10), as this method was specifically not exported by the server-side. This essentially makes this property read-only.

Hopefully, this code might encourage you to investigate Spring JMX as a technology worth incorporating in your next application. Providing external access to applications can pay off in valuable, unforseen ways after the it has been deployed.

In Untagged 
Comment (0) Read More...


Posted by: Wesley Willard on

In the last 10 years, Open Source software has provided an incredible benefit to the software development process. Most open source software projects present quality, well-tested APIs and libraries that can be quickly integrated into a product, providing much-needed functionality that does not have to be developed in-house. While there are too many projects to even begin to mention, the software produced by the Apache Project, and SpringSource provide frameworks and utilities that would take companies man man-years to develop on their own.

There are, however, a few issues that every organization should consider before choosing to include open source software in their commercial products. While these issues are usually not show-stoppers in the decision process, but should be viewed as risk factors. Failure to consider these issues can leave a company with problems that cause development and maintenance nightmares.

First, I would take the time to consider the involvement of the project's community of users and developers. Is work on the project ongoing, or does it seem to be stagnant? Are there discussion forums for the project, and do the developers post to the forum? An active Open Source project community enables you to resolve usage issues, obtain patches, and generally integrate the project more quickly into your product. A less active community can be an indicator that the project has not been well-received, perhaps because of stability, or even issues with its usefulness.

Licensing is a potential Pandora's Box of issues for anyone wishing to include Open Source software in their product. In general, software which fall under BSD or Apache licenses are the safest to use. For example, the Apache License allows free use, modification, and distribution of their software, provided that the appropriate notice is included. A great source of information concerning Open Source licensing issues is the Open Source Initiative. This group maintains the definition of open source software, and vets licenses in order to certify that the license adheres to it. In this litigative age that we live in, no one needs the hassle of a potential lawsuit involving their product.

In my opinion, while there are issues involved in the choice to include open source software in a commercial software product, the benefits far outweigh the drawbacks.

In Open Source
Comment (0) Read More...


Posted by: Wesley Willard on

Beginning in the 90’s, American software companies began farming out development work to companies overseas, or "off-shoring". These efforts mirrored what had been taking place for quite some time in other industries, such as textile manufacturing, and sent tremors through the software community. The heady days of the dot-com boom gave way to fear and gnashing of teeth in the early part of this decade. CEO’s were pictured riding astride elephants in India, and executives were predicting that soon all non-design development work would take place off-shore. Would there be any jobs left for American software developers?

Now entering the latter part of this first decade of the 21st century, the software development community state-side finds itself in what appears to be a better situation, jobs-wise. What happened? Why did the gloom-and-doom scenarios not play out?

A couple of realities have become apparent as the decade has played itself out. First, globalization of software development has actually worked against itself, as the cost of doing business in countries like India has increased to the point where the cost savings benefit is in question. Software developers are able to demand more money there, as the need for them has increased.

But secondly, and I believe just as importantly, companies seeking to off-shore their development made critical mistakes in choosing the products that they would send overseas. The products they chose were mostly mainstream, legacy products, which tend to be, by their sheer longevity, much more complex and intricate. From my experience in this business, I have found that "old" does not equal "simple". In fact, just the opposite is true. This software has generally been developed over the years by hundreds of developers, all with different programming styles, and do not always follow textbook patterns. Asking primarily inexperienced developers to maintain or enhance these products without day-to-day guidance from at least a few senior developers is tough. Couple this fact with the risk of losing market share for these products (oh yeah, they’re probably still profitable, why else would development continue?), and you have a recipe for disaster.

What seems like such a great idea when discussed at cocktail parties 8 years ago, should now be one that should be considered with at least some trepidation.

In Untagged 
Comment (0) Read More...


Posted by: Wesley Willard on

As a software developer, maintaining concentration is something that requires discipline, and sometimes the aid of a good set of headphones, and some music.  While this usually does the trick, I find that familiar music can be its own distraction, since I find myself jumping to some memory that the song brings back.  In addition to this, transporting CDs back and forth from home to work is a pain.

For these, and other reasons, I've looked for alternative listening sources, and one I've found very enjoyable are the Internet radio channels streamed at Soma FM.  This full-time, Internet-only station began as a pirate radio broadcast at the Burning Man festival in 1999, and now streams 16 different channels.  My personal favorites are Groove Salad, which plays music in the Ambient genre, and indie pop rocks!, playing new and old tunes.  In listening to these two channels, I've discovered a lot of new music (which is harder to do the older I get), but at the same time, I find that I'm able to keep my focus on my development work, since I'm not as familiar with the bands.

If you're looking for some really great music to work by, check them out.  I think you'll find some great music which just requires an Internet connection to enjoy.

In Untagged 
Comment (0) Read More...


Posted by: Wesley Willard on

While Robert Reeves is correct in his assessment that scripting can be evil, especially in cases where scalable and durable automation is needed (like deployments of apps),there are occasions where a script can definitely serve as a useful problem-solving tool. A script can act as another way to view an application's data, allowing the developer to verify the state of the data independently. Creating a script does not generally require the same amount of time to code/compile/edit as a regular programming language, thus can be more quickly developed in an iterative fashion. Also, since scripting languages are not used as often to create commercial applications as are programming languages like Java, a script can be used to prototype some experimental functionality, without danger that the prototype will escape the building.

I have resisted taking the time to learn much about the many scripting languages which have been created in the last few years, but Groovy is one which, as a Java developer, has really caught my eye. It is built on Java, but provides additional features which have been inspired by other languages such as Ruby and Objective-C.

I find Groovy to be my current scripting language of choice for a few simple reasons:

  • Java-like syntax is extremely easy to pick up
  • Ability to leverage the many powerful Java APIs
  • Useful built-in features like Categories, which enable dynamic extension of any class

In the following code, I’ll demonstrate some of these things. I will be making a remote connection to a JBoss Application Server in order to retrieve MBean attributes, as well as invoke operations on the MBean.

First, I will import some classes, and make a connection to the server:


package com.groovy

import javax.management.ObjectName
import javax.management.MBeanServerConnection
import javax.naming.InitialContext
import org.apache.xpath.XPathAPI
import groovy.xml.dom.DOMCategory
import org.w3c.dom.Element

def
password = ""
def initialContextFactory = "org.jboss.security.jndi.
JndiLoginInitialContextFactory"
def JMX_INVOKER_RMI_ADAPTOR = "jmx/invoker/RMIAdaptor"
def port = 1099
def host = "localhost"
def username = ""
def password = ""
def initialContextFactory = "org.jboss.security.jndi.
JndiLoginInitialContextFactory"

//
// Connect to JBoss
//
Properties props = new Properties(System.getProperties())
props.put("java.naming.factory.initial", initialContextFactory)
props.put("java.naming.provider.url", host + ":" + port)
props.put("java.naming.security.principal", username)
props.put("java.naming.security.credentials", password)
def ctx = new InitialContext(props)
Object obj = ctx.lookup(JMX_INVOKER_RMI_ADAPTOR)
def mbsc = (MBeanServerConnection) obj
ctx.close()

Once I have made my connection, I will then use it to invoke an operation on a JBoss MBean.


//
// Create a class to be used as a String Category
// StringCategory extends the String class with
// a new method that splits a String at the newline delimiter
//
class MyStringCategory {
public static List splitOnNewLine(String string) {
return string.tokenize("\n")
}
}
//
// Invoke the operation listDeployedURLs on the Groovy MBean
// Use the category defined above to split up the return string
//
use (MyStringCategory) {
def deploymentScanner =
new GroovyMBean(mbsc, "jboss.deployment:flavor=URL,
type=DeploymentScanner")
def deployedURLs = deploymentScanner.listDeployedURLs()
def deployedList = deployedURLs.splitOnNewLine()
deployedList.each( { println it } )
}

This snippet illustrates a couple of interesting Groovy features. The class MyStringCategory is an example of a Groovy Category. A Category in Groovy is a class which defines methods which can extend any specified class. In the example, the method splitOnNewLine is a category method on the Groovy class String, due to the fact that the method is static, and the first argument (or target) is of type String. This method can be called on any instance of a String, and will return a List containing one entry per new line found in the String. To enable the category method to be called, the call must be enclosed in a use statement, which references the name of the category.

Also notice that I have created an instance of a GroovyMBean, constructing it using the server connection and the name of the JBoss MBean. The GroovyMBean is a built-in Groovy class, which allows an MBean to be used as a regular Groovy object. I use this object to call the listDeployedURLs() method on the JBoss MBean, which returns a String representation of the currently deployed URLs on the server. I then use my splitOnNewLine() category method to create a List, which can then be iterated.

The next snippet of code illustrates how easy it is to make use of an existing Java API within Groovy.

 


//
// Create GroovyMBean to retrieve the JBoss Mail Service
// configuration information, which is returned by JBoss
// as an XML Element object
//
def mailBean = new GroovyMBean(mbsc, "jboss:service=Mail")
def configurationXML = mailBean.Configuration

//
// Use the Apache XPath API to select the nodes,
// and iterate through them with a closure
//
def nodeList = XPathAPI.selectNodeList(configurationXML,
"//property[@name]")
def printNode = { println it.getAttribute("name") + "=" +
it.getAttribute("value")
nodeList.each(printNode)

After the creation of another GroovyMBean, the Apache XPath API is used to select the nodes in the returned XML Element. The resulting NodeList is then iterated. Using an existing Java API in this fashion is just as simple as importing the appropriate class, and then calling its methods.

The final part of this example uses another category, MyDOMCategory, in conjunction with a built-in Groovy category, DOMCategory, to process the same XML Element. The call to list() is a category method which transforms a NodeList object into a List object. The List object is iterated, and its attributes are retrieved using the Element category method attribute(Element node, String attrName) to retrieve the name and value attributes.

 


//
// The class MyDOMCategory extends the Element class
// to return the value for the specified attribute
//
class MyDOMCategory {
static String attribute(Element node, String attrName) {
return node.attributes[attrName]
}
}

//
// Use Groovy Categories to iterate through the NodeList
//
use (DOMCategory, MyDOMCategory) {
configurationXML."property".list().each(
{ println "MyDOMCategory: " + it.attribute("name") + "="
+ it.attribute("value") } )
}

Hopefully, these short snippets of code illustrate the simplicity that I think makes Groovy a very attractive option for scripting use in the Java development world. I would highly recommend it as a useful addition to your software developer's toolkit.

In ScriptsScripting LanguageGroovy
Comment (0) Read More...