magpiebrain

Sam Newman's site, a Consultant at ThoughtWorks

Posts from the ‘Development’ category

I was asked again today of what my opinion was about Web 2.0 – what was it about all the buzzwords that was actually important? I probably end up anwsering this question a couple of times a week, and thought that todays response was as worth blogging as any of my previous anwsers.

Web 2.0, being a grab-bag of new technologies that emerged at the same time, can mean many things to many people. For myself, there are two primary trends which I think are important – the availability of cheap hardware and infrastructure software, and the ability to create compelling user interfaces on the web.

We’ve seen the emergence of a robust stack of free software on which Web 2.0 applications can be built. Where previously companies seed funding would be spent on buying Oracle and Application Servers, nowadays people are turning to cheap if not free alternatives such as the LAMP stack. Couple this with the low cost of hosting and bandwidth, and companies can focus their money on delivering what is most important – software that differentiates them from their competitors.

The fact that people are creating more impressive, more usable interfaces on the web, is due to one simple fact – the browsers got better. The lowest common denominator browsers have a good enough standard implementation of CSS, (X)HTML and JavaScript that we are freed from much of the work required to make our code cross-browser compatible. This has been followed by a number of third parties creating Web APIs (such as the Yahoo Toolkit) which further isolates ourselves from browser quirks, and help us concentrate on delivering valuable software.

If any of you are interested in Web 2.0 (or beer) and are in London (or want to travel for beer), then feel free to pop along to the next “London 2.0 meet-up(magpiebrain.com – Posts on London 2.0)”:http://www.magpiebrain.com/blog/category/web-20/london-20-meet-ups/.

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.

Amazon web evangalist Jeff Barr will be “giving a talk(Unixdaemon – Jeff Barr in London)”:http://blog.unixdaemon.net/cgi-bin/blosxom.pl/events/aws_jeffreybarr.html on their webservice offerings at Westminster University on the 15th of May. Unfortunately I’ll be unable to attend – I’d of liked to pick Jeff’s brains about “S3”:http://www.amazon.com/gp/browse.html/002-7839271-9683254?node=16427261 off the back of my “recent post(magpiebrain – Is Amazon S3 the first tier 0 Internet service?)”:http://www.magpiebrain.com/blog/2006/03/21/is-amazon-s3-the-first-tier-0-internet-service/ – but I’m sure it will be an interesting event.

If you want to attend make sure you contact organiser Dean Wilson (email: dwilson at unixdaemon.net) so he can let you know of any changes. I’ve added the event to the London 2.0 calendar too.

[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…

On a Wednesday instead this week, just for kicks, but once again at the “Olde Bank of England”:http://www.pubs.com/pub_details.cfm?ID=214 from 7pm. No agenda as yet, but I want demos! Leave a comment if you’ll be coming so I can get an idea of numbers.

Though the magic of Google Calendar (I’m so Web 20 it _hurts_) I now have publically available “ical(London 2.0 meet-up events – iCal)”:http://www.google.com/calendar/ical/c7ilcesmkkn0e3bkirk4kgf5cc@group.calendar.google.com/public/basic and “rss(London 2.0 meet-up events – rss)”:http://www.google.com/calendar/feeds/c7ilcesmkkn0e3bkirk4kgf5cc@group.calendar.google.com/public/basic feeds. Once I get home it’ll be on upcoming too (damn corporate firewall tagging it as a dating site…), although unless upcoming starts letting me splice in my Google events soon I’ll probably stop using the service.

p(update). _Update_: I’ve added a simple block on the bottom of this site listing the upcoming London 2.0 events using dwc’s “iCal WordPress plugin”:http://dev.webadmin.ufl.edu/~dwc/2005/03/10/ical-events-plugin/. There is also a specific “category”:http://www.magpiebrain.com/blog/category/web-20/london-20-meet-ups/ and “rss feed”:http://www.magpiebrain.com/blog/category/web-20/london-20-meet-ups//feed for all London 2.0 meet-up information.

Thanks to everyone who attended London 2.0 RC 4 last night (in rather cramped conditions). The “usual(Simon Willison’s weblog)”:http://simon.incutio.com/ “suspects”:http://www.brunningonline.net/simon/blog/ were in attendance, as well as Adrian Holovaty who was in for a few days.

“Phil Dawes”:http://www.phildawes.net/blog/ demonstrated both “Bicycle Repair Man(Bicycle Repair Man – Python Refactoring Tool)”:http://bicyclerepair.sourceforge.net/ and the Python testing tool “Protest”:http://www.phildawes.net/blog/2006/03/17/protest-rocks-generate-documentation-from-tests/ (we need screencasts of both!), and I pointed numerous people towards the impressive “DabbleDB”:http://dabbledb.com/utr/ screencast. Demo of the night probably had to be Remi Delon showing off “Python Hosting”:http://www.python-hosting.com/. They offer a very slick, one-click install of a variety of different webapp frameworks (everything from TurboGears to Zope to Django) for a very “reasonable price(Python Hosting shared hosting plans)”:http://www.python-hosting.com/shared_hosting. His screencast is out soon – but put it this way, TextDrive’s TextPanel is going to have a lot to live up to, not to mention their forthcoming Rails-dedicated hosting (note: I’m a TextDrive user myself). Despite their name, Python-Hosting do also provide Rails hosting, however it’s not yet integrated with their slick user interface.

Details on next month’s London 2.0 RC5 coming up soon.

[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]