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.

Follow

Get every new post delivered to your Inbox.