magpiebrain

Sam Newman's site, a Consultant at ThoughtWorks

Posts from the ‘Java’ category

A while ago, I wrote an “article”:http://today.java.net/pub/a/today/2003/08/08/rss.html on RSS and the Java “Informa API”:http://informa.sourceforge.net/ for O’Reilly’s “java.net”:http://java.net site. This morning, my Google blog search called up an odd search result – it seems as though a certain Dr. Charlie Peng had copied the article wholesale for his BlogSpot blog, ‘IT Architect’. It looks like a blatant attempt to create a high-ranked blog in order to achieve something (probably commercial gain – I don’t think it’ll help him get girls). If achieving high-ranking is his goal, I’m sure he could of picked some better articles to steal, with some better buzzword density – RSS is _so_ 2003.

I’ve flagged the site, left a comment and informed O’Reilly. Knowing how responsive Google are at removing dodgy blogspot blogs, I don’t expect much to happen anytime soon – unless O’Reilly decide to throw so weight around that is. In the meantime, you can view the stolen article at “architectit dot blogspot dot com /2006/07/rss-in-jsp-using-rss-in-jsp-pages-by.html” (no link referrals for _him_) – although I’d prefer it if you simply read the original article over at “Java.net(Using RSS in JSP)”:http://today.java.net/pub/a/today/2003/08/08/rss.html.

I’ve been struggling with configuring a password protected Resin-deployed JMX application on windows recently. This is being blogged in the hope that Google will pick this up and make the process much simpler for someone later on.

These instructions assume you are using Resin, but should work for any container.

h3. Enabling Password Protection

Starting Resin secured using a password is pretty simple. Firstly, start Resin with the following properties:

com.sun.management.jmxremote.port=
com.sun.management.jmxremote.authenticate=true
com.sun.management.jmxremote.ssl=false
com.sun.management.jmxremote.password.file=
com.sun.management.jmxremote.access.file=

Next, you’ll need to create @jmx.access@ file, like so:

joeblogs readwrite

And a @jmx.passwd@:

joeblogs password1

p. jmx.passwd needs to be secured such that only the user running the Resin process can access the file. On Linux or Unix, this is simply a case of running @chmod 400 jmx.passwd@. However on Windows this is more involved – the “five step process(How to a Secure Password File on Microsoft Windows Systems)”:http://java.sun.com/j2se/1.5.0/docs/guide/management/security-windows.html required to secure the file is rather baroque, and worst of all makes running JMX applications secured in this manner rather hard for development teams, as this has to be done each time the file is checked out. I suspect a “Calcs”:http://www.ss64.com/nt/cacls.html or “SetAcl”:http://setacl.sourceforge.net/ script could be folded into the build, but it really shouldn’t be that hard. I suspect Sun want us all to use SSL instead.

h3. Programatically working with password protected JMX

This “sample from sun”:http://java.sun.com/j2se/1.5.0/docs/guide/jmx/examples/Security/simple/client/Client.java shows how to work with your newly password-protected JMX app:

public class Client {

  public static void main(String[] args) {
  try {
      HashMap env = new HashMap();

      String[] credentials = new String[] { "username" , "password" };
      env.put("jmx.remote.credentials", credentials);
      JMXServiceURL url = new JMXServiceURL(
         "service:jmx:rmi:///jndi/rmi://localhost:9999/server");
      JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
      MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
      String domains[] = mbsc.getDomains();
      for (int i = 0; i < domains.length; i++) {
         System.out.println("Domain[" + i + "] = " + domains[i]);
      }

      ObjectName mbeanName =
          new ObjectName("MBeans:type=SimpleStandard");
      mbsc.createMBean("SimpleStandard", mbeanName, null, null);
      // Perform MBean operations
      [...]

      mbsc.unregisterMBean(mbeanName);
      jmxc.close();
    }  catch (Exception e) {
      e.printStackTrace();
    }
  }
}

When connecting to a database from Java, it’s very handy to tag your connections. When tracking down performance issues and monitoring at a database levels, being able to seperate out your program’s connections (which could come from a variety of machines). Most database drivers allow you to specify a program name when creating your connection.

With SqlServer, you can specify a program name “on the query string(The MS SQL Server Driver – connection properties)”:http://edocs.bea.com/wls/docs81/jdbc_drivers/mssqlserver.html#1074599 of your JDBC connection. However with Oracle it’s not quite as simple. I spent ages trying to track down how to do this with Oracle, but it seems that where Oracle is concerned useful documentation lies behind expensive consultants or registration screens. Eventually resident database guru (thanks Jason) sent me a snippet of code which does exactly that, and I’m blogging it here for prosperity (and for consumption by the Google spider).

This code opens a connection with the name Test. By querying the database’s @v$session@ dictionary view we can see each connection from our application (by the way, good luck searching
Google using a $ in a search term). @v$session@ exposes a variety of information – including the program name. The final lines of the code prints out the program name of every session currently connected to the database, helping confirm that the snippets code has worked.

class SetProgram
{
  public static void main (String args [])
       throws SQLException
  {
    // Load the Oracle JDBC driver
    DriverManager.registerDriver(new oracle.jdbc.OracleDriver());

    java.util.Properties props = new java.util.Properties();
    props.put("v$session.program", "Test");

    // Connect to the database
    Connection conn =
      DriverManager.getConnection ("jdbc:oracle:thin:user/tiger@localhost:1521:xe",
				   props);

    // Create a Statement
    Statement stmt = conn.createStatement ();

    // Select the PROGRAM field from the V$SESSION table
    ResultSet rset = stmt.executeQuery ("select program from v$session");

    // Iterate through the result
    while (rset.next ())
      System.out.println (rset.getString (1));
  }
}

h3. Specifying program name with C3P0

When configuring this value using the “C3P0(C3P0 – Java database connection pool)”:http://sourceforge.net/projects/c3p0 connection pool, if you want to specify properties like @v$session.program@, you cannot configure login and password using the normal @setPasword@ or @setUser@ methods as it gets its knickers in a twist. Instead you’ll have to place those in the properties object which you pass to the connection pool using the @setProperties@ method on @ComboPooledDataSource@.

This is worth noting, as where @setUser@ and @setPassword@ will be JDBC driver agnostic, the properties bundle passed in isn’t – or more correctly, the properites themselves aren’t.

[java]
Table person = new Table(“person”);
return select(person.star())
.from(person)
.where(person.column(“startDate”).greaterThan(“2005-01-01”)
.and(person.column(“numberOfFriends”).greaterThan(100))
.and(person.column(“age”).greaterThan(21)));
[/java]

[java]
Table person = new Table(“person”);
Column startDate = person.column(“startDate”);
Column numberOfFriends = person.column(“numberOfFriends”);
return select(person.star())
.from(person)
.where(startDate.greaterThan(“2005-01-01”)
.and(numberOfFriends.greaterThan(100)
.or(numberOfFriends.lessThan(50))));
[/java]

[java]
Table person = new Table(“person”);
return select(star())
.from(person)
.where(person.column(“psnId”).notIn(new String[] { “1”, “2” }));
[/java]

From the Squiggle acceptance tests…

[java]
Table person = new Table(“person”);
return select(person.star()).
from(person).
orderBy(person.column(“name”));
[/java]

[java]
Table person = new Table(“person”);
Column age = person.column(“age”);
return select(person.star()).
from(person).
where(age.lessThan(25))
[/java]

[java]
Table person = new Table(“person”);
Column wage = person.column(“wage”);
return select(count(person.star())).
from(person).
where(wage.greaterThan(52000))
[/java]

Yes, I know what you’re thinking – “So soon after the announcement of the “March meeting(magpiebrain – London RC3 March Meetup)”:http://www.magpiebrain.com/archives/2006/02/25/london20_rc3? Has Sam started getting organised?”. Well, kind of – actually I heard from Harry Pot “Simon W(Simon Willison’s Weblog)”:http://simon.incutio.com/ that one of the Django devs, “Adrian Holovaty(Adrian Holovaty’s Weblog)”:http://www.holovaty.com/, was going to be in town.

Given that it’s so far in advance, I’m sure many of you won’t know if you can make it, but once again it’ll be the same cross-language cross-technology meetup, broadly aligned along Web 2.0 lines – all are welcome, whether or not you think Web 2.0 is great, or just a crock of poo.
Continue reading…

Just a quick note after a long absence (no doubt a flood of posts will now follow, preceding another too long gap). Anyway, “London 2.0rc2(London 2.0rc1 on Upcoming.org)”:http://upcoming.org/event/47958/ is on for this Tuesday. Once again it’ll be combining the Python meetup, and will be open to all Ruby, Django, Rails, Python, RSS, Catalyst, web.py, TurboGears, Java, RDF and Struts enthusiasts, and interested observers. After missing the last two (which is bad form as an organiser) I’ll be making a concerted effort to put in a prolonged apperance.

If you’re coming, you could either signup on “Upcoming.org”:http://upcoming.org/event/47958/, or leave a comment here. As normal, it’s from 6pm til late at the “Old Bank of England(Upcoming’s entry for the Old Bank of England)”:http://upcoming.org/venue/16413.

*We need a snappier name…

As the calendar gets a little crowded in December, myself, Simon and Jez have decided to combine the Java, Django/Rails and Python nights together in one big bash at the Old Bank Of England, on the 12th of December, from 7pm onwards. As normal there is no particular agenda, although people wanting to do demos are more than welcome (just let me know first so we can publicise it).

Oh, and as Jez has had to stick a deposit down for the reserved space, please leave a comment to let us know you’re coming!

A recent post by Cedric in response to an article by Michael Feathers (danger, community navel gazing alert! Obviously this blog is above such things) casts doubt on the necessity of unit tests.

Michael’s rules on what a unit test is seem overly draconian to some (not being able to touch the filesystem for example – 99% of the time I’d agree, but if I’m testing my FileConfiguration class, what the hell am I supposed to do?) – and despite many other people attempting to define what a unit test is, Cedric’s take on it comes the closest to my own understanding of what a unit test is:

…a unit test is traditionally defined as a set of test that exercises a single class in isolation of all others.

Cedric then goes on to say that 90% of the tests he sees written with JUnit are not unit tests. I for one would be wary of working on those codebases. He also states that he doesn’t care if the test he writes is a unit or functional test – which immediately makes me worry about working on his codebase.

The point that gets missed here is that Unit and Functional tests are not different because of how they work, how long they take or the tools required to make them work, but they are different because they fulfill different roles in development.

Unit tests, because they focus on testing one class and one class only, make it much easier to create highly-focused loosely coupled code, as you create and test a class in isolation of other code. As you have good test coverage at a single class level, you can then safely refactor the class and know you haven’t changed the behavior of the unit. As you are writing code and testing at a small level, you can commit your code more frequently, enabling frequent, smaller-scale integration. If you are testing at a class level, the test themselves become a living document detailing how your code works.

Functional tests are supposed to test slices through your system – from UI to back-end and back if possible. You are asserting that your system conforms to the behavior expected by your users.

Unit tests tend to be fast because they limit the code they test. Functional tests tend to be slow, because they test more code, and also interact with slow components (e.g. databases, browsers, networks etc) but their speed doesn’t define what type of test they are.

Often there is the need to separate fast tests from slow tests – and TestNG’s categorisation of tests is perhaps the first feature of the TestNG that has interested me. But the categorisation is done in order to define fast feedback cycles (e.g. run a quick build on checkin, and longer build on the hour, everyday etc – see Speeding up the build and build pipelining for more details) this should not be used to confuse functional and unit tests. Developers need to understand the different requirements for, and benefits of, these two different types of tests.

It’s been a while since I’ve had to unleash the angry kitten, but it seems that the OpenAdaptor developers have rather inadvisably irked me, to the extent that I’ve withheld the kitten’s food for two days now, to make the ensuing carnage all the more…well, carnagy.

To start with, I like the concept and some of the architecure behind Open Adaptor. It’s a fine arhictecture – it’s no suprise that plenty of other APIs out there have come up with similar solutions to the same problems. The JBI spec obviously owes a lot to OpenAdaptor. That said its implementation frequently makes me want to have a few minutes with the developers, a pair of pliers and a blowtorch.

Creating sinks, pipes and sources

Let’s start with the fact that to create anything you’re pratically forced to use property files. No Inversion Of Control for you my son, oh no – here we have a special init method, which is not a constructor because…well, it’s called init, its enforced by the API, and it takes a Properties object. The only benifit over being able to construct objects the way you want seems to be it made it easy for the developers to use property files (I hope for the next version they at least look at spring). That makes tesing so much fun. Please note the sarcasm.

JARs not built using debug information

Yes, you heard me right. Here was I, thinking we lived in the age of high-speed internet connections. But in fact it seems internet bandwidth is so tight that the developers considered providing debug information so we could work out for which odd reason an Adaptor fails a luxury.

Errors that are not errors – or might be

So when your adaptor fails with no clear reason why – well, what should you do? That’s right, turn on debug – chances are a debug message will detail why your adaptor failed. Even better, sometimes the error message will be vague, for example the one that tells me that either my JNDI server may be unavailable, or that it is there but the thing I want isn’t, or that it is there and the thing I want is there, only I might be missing a class, only it won’t tell me what class that might be. That is an error message that can be really fun to work with. And I don’t mean the good type of fun either, I mean the achingly irritating kind of fun that can only result in me hurting my foot kicking office furniture.

A nice idea crippled by an allergy to interfaces

OpenAdaptor has a rather sensible and useful (sounding) feature called message hospitals. Normally, if a message causes an exception the app shuts down. You can however choose to configure a message hospital which will capture all messages which throw an exception – but only an exception of a given type. However by “type” OpenAdaptor means “class” – you have to throw a checked PipelineException. This is bad enough – I now have to have a top-level catch throwable clause that rethrows PipelineException – but the constructor doesn’t even take a root cause. Quite why a simple ExceptionType interface couldn’t be used I have no idea.

Conclusion

OpenAdaptor has a sound premise, but it’s implementation needs bringing up to date. A full rewrite in the form of OpenAdaptor 3 is underway – get involved.