how to fix Java WebStart on MacOSX 10.5.7

I don’t know when this broke – maybe around the time Safari 4 was released? Anyway, Java WebStart stopped working. Downloading a .jnlp file and doubleclicking it brought up an editor (Dashcode) rather than the application launched via Java WebStart. I tried using Spotlight to find “Java WebStart” so I could manually launch the app. But nothing was found. WTF?

Apparently, the solution, of course, is to navigate in the Finder to /System/Library/CoreServices and click on Java WebStart.app – an entirely intuitive and obvious solution. This triggers some hidden magic to somehow restore access to JWS. Who knows. It works after doing this.

Debugging WebObjects

I got the chance to play with debugging a running WebObjects app today, with the added fun of having a roomful of 20 users of the app taking turns to mention “did you know that [X|Y|Z] isn’t working?”

Long story short, if you need to get the status of threads of a running WebObjects app, jdb provides some great tools. I have only scratched the surface of it, thanks entirely to the great intro document by Andrew Lindesay. (Andrew recently moved his website to .Mac from some New Zealand host, so I’m linking to help throw some Google Juice his way so others can find his article)

I’ve put a wikified crib sheet together to make it easier to get set up.

I got the chance to play with debugging a running WebObjects app today, with the added fun of having a roomful of 20 users of the app taking turns to mention “did you know that [X|Y|Z] isn’t working?”

Long story short, if you need to get the status of threads of a running WebObjects app, jdb provides some great tools. I have only scratched the surface of it, thanks entirely to the great intro document by Andrew Lindesay. (Andrew recently moved his website to .Mac from some New Zealand host, so I’m linking to help throw some Google Juice his way so others can find his article)

I’ve put a wikified crib sheet together to make it easier to get set up.

Fun with Java RegEx String Replacement

In the Pachyderm presentation publishing code, there is a step where it compiles the various versions of images for use in the final product – resizing as needed, wrapping in the .swf file and burning in the metadata. It uses an XML format, provided by JSwiff, to replace the freeze-dried content of a templated flash file wrapper with the dynamically defined data (image and text).

We just do a simple find-and-replace, looking for special tags that we’ve placed in the templated .swf xml version – looking for things like “{tombstoneTitleShort}” and replacing it with “My Most Excellent Photo”. Seems simple. But I just came across a case where it failed. The extended text for an image included a $ – which would be fine, but it’s a Magic Regex Character, symbolizing the end of a line of text (likewise, ^ symbolizes the beginning of a line). And, it was unescaped (and not at the end of a line), so the String.replaceAll() method was barfing appropriately. I think this is what was happening… Looked like it from the debug output, anyway…

I just switched that bit of string replacement to use the Apache Commons Lang StringUtils replacement method (org.apache.commons.lang.StringUtils.replace(String, String, String) ), and all appears fine now.

As an aside, there are a lot of handy little goodnesses in the Apache Commons Lang library (as in the other Commons libraries). I need to make sure I’m taking advantage of it more, rather than writing my own utility code…

Update: Nope. That didn’t work as cleanly as I’d hoped. Now it was complaining that some of the replaced characters were invalid UTF-8. So, I’m now replacing characters in my replacement string to attempt to escape them properly before feeding them to String.replaceAll( pattern, value ), using the “oldReplace” method from this tip.

In the Pachyderm presentation publishing code, there is a step where it compiles the various versions of images for use in the final product – resizing as needed, wrapping in the .swf file and burning in the metadata. It uses an XML format, provided by JSwiff, to replace the freeze-dried content of a templated flash file wrapper with the dynamically defined data (image and text).

We just do a simple find-and-replace, looking for special tags that we’ve placed in the templated .swf xml version – looking for things like “{tombstoneTitleShort}” and replacing it with “My Most Excellent Photo”. Seems simple. But I just came across a case where it failed. The extended text for an image included a $ – which would be fine, but it’s a Magic Regex Character, symbolizing the end of a line of text (likewise, ^ symbolizes the beginning of a line). And, it was unescaped (and not at the end of a line), so the String.replaceAll() method was barfing appropriately. I think this is what was happening… Looked like it from the debug output, anyway…

I just switched that bit of string replacement to use the Apache Commons Lang StringUtils replacement method (org.apache.commons.lang.StringUtils.replace(String, String, String) ), and all appears fine now.

As an aside, there are a lot of handy little goodnesses in the Apache Commons Lang library (as in the other Commons libraries). I need to make sure I’m taking advantage of it more, rather than writing my own utility code…

Update: Nope. That didn’t work as cleanly as I’d hoped. Now it was complaining that some of the replaced characters were invalid UTF-8. So, I’m now replacing characters in my replacement string to attempt to escape them properly before feeding them to String.replaceAll( pattern, value ), using the “oldReplace” method from this tip.

Fun with jGenerator

We’re using jGenerator for the Pachyderm project – to replace the abandoned Macromedia Generator product – for wrapping images in .swf files for display within Pachyderm presentations. The .swf files provide value-add stuff like “tombstone” data, and a lightweight, unobtrusive form of DRM.

However, jGenerator has been rather neglected for 3 years now, and as a result it’s starting to show cobwebs etc… Remember my friend Murphy? Largely a result of these cobwebs.

Today, days after we thought we nuked the jGenerator problem, it came back in full force. Building presentations would occasionally hang (sometimes not reliably, or sometimes very reliably). We tracked down the problem thanks to the handy dandy java debugger jdb (handy document on using jdb in a running WebObjects app), and it was the result of jGenerator using java.awt.Rectangle classes rather than java.awt.geom.Rectangle2D.

The methods had been altered to use Rectangle2D in the signatures, but were actually passing around Rectangle objects instead. This apparently causes problems on MacOSX and other Unix-like systems, as was discovered by the OpenLaszlo folks. They had to start their own fork of jGenerator 2.2 to fix this (and potentially other) problems. We just did the same.

We had another round of Team Programming at a Distance – the three of us brainstorming and hacking and researching. That is soooo much more fun and rewarding than copying and pasting…

We’re using jGenerator for the Pachyderm project – to replace the abandoned Macromedia Generator product – for wrapping images in .swf files for display within Pachyderm presentations. The .swf files provide value-add stuff like “tombstone” data, and a lightweight, unobtrusive form of DRM.

However, jGenerator has been rather neglected for 3 years now, and as a result it’s starting to show cobwebs etc… Remember my friend Murphy? Largely a result of these cobwebs.

Today, days after we thought we nuked the jGenerator problem, it came back in full force. Building presentations would occasionally hang (sometimes not reliably, or sometimes very reliably). We tracked down the problem thanks to the handy dandy java debugger jdb (handy document on using jdb in a running WebObjects app), and it was the result of jGenerator using java.awt.Rectangle classes rather than java.awt.geom.Rectangle2D.

The methods had been altered to use Rectangle2D in the signatures, but were actually passing around Rectangle objects instead. This apparently causes problems on MacOSX and other Unix-like systems, as was discovered by the OpenLaszlo folks. They had to start their own fork of jGenerator 2.2 to fix this (and potentially other) problems. We just did the same.

We had another round of Team Programming at a Distance – the three of us brainstorming and hacking and researching. That is soooo much more fun and rewarding than copying and pasting…

Murphy: 1, D’Arcy: 1

After what felt like a very long weekend of debugging jGenerator, I finally figured out what was going wrong, and how to fix it. It didn’t make sense at all, which is why I didn’t pursue that line of investigation earlier. The library worked fine before. It hadn’t changed. Then it didn’t work. I was figuring that meant something outside of the library had changed, and had borked something used by jGenerator.

Whatever the cause, I wound up using a java decompiler (jad) to figure out exactly where the problem was, while comparing to the versions of available jGenerator source code. I removed what appeared to be the offending line (calling Log.logRB() – which is a utility log method within jGenerator), and recompiled a fresh copy of jgen.jar using the Ant build script.

Deployed that sucker, restarted the Mavericks instance of the Pachyderm authoring app, and cést voila! I had it working early this morning, then published fresh copies of all of the Mavericks sections for review. *touches wood* It’s working great now!

So… in the future, when debugging something that isn’t behaving as expected… throw away all assumptions – no matter how “sure” you are about something, test and verify each and every line of investigation.

OK. Murphy, you can go to hell now…

After what felt like a very long weekend of debugging jGenerator, I finally figured out what was going wrong, and how to fix it. It didn’t make sense at all, which is why I didn’t pursue that line of investigation earlier. The library worked fine before. It hadn’t changed. Then it didn’t work. I was figuring that meant something outside of the library had changed, and had borked something used by jGenerator.

Whatever the cause, I wound up using a java decompiler (jad) to figure out exactly where the problem was, while comparing to the versions of available jGenerator source code. I removed what appeared to be the offending line (calling Log.logRB() – which is a utility log method within jGenerator), and recompiled a fresh copy of jgen.jar using the Ant build script.

Deployed that sucker, restarted the Mavericks instance of the Pachyderm authoring app, and cést voila! I had it working early this morning, then published fresh copies of all of the Mavericks sections for review. *touches wood* It’s working great now!

So… in the future, when debugging something that isn’t behaving as expected… throw away all assumptions – no matter how “sure” you are about something, test and verify each and every line of investigation.

OK. Murphy, you can go to hell now…

JAI vs. ImageMagick image resizing

Part of the functionality of the Pachyderm authoring application is the dynamic and on-the-fly resizing of images to whatever dimensions are required by the flash templates that are used to display a screen in a presentation.

I wrote the first version of the image resizing code using Java Advanced Imaging (JAI), and it worked quite well. But, during the authoring of the Mavericks prototype, it became apparent that the quality of the resized images wasn’t quite up to snuff. I tried setting JAI to use bicubic interpolation (InterpolationBicubic and InterpolationBicubic2) instead of the default nearest-neighbour (InterpolationNearest) method. Still produced inconsistent results.

I had looked at using ImageMagick, using the java JMagick bridge, but that was just plain funky. It relies on a JNI bridge that apparently doesn’t compile well on MacOSX (I never got it compiled, and Google only turned up one person in the history of the internets that had success – on an older version of the OS).

Fast forward to last night. I decided to try an ImageMagick solution using java’s Runtime.exec() – and it works perfectly. Image quality is MUCH better. The memory issues we were seeing with JAI disappeared (JAI was barfing on Very Large Images, where ImageMagick chews through them with ease). The downside is that it takes considerably longer to process the resized images, and since ImageMagick can only work with local files (not URLs), I have to download the image from the web each time I want to process it (this can be done more intelligently – I just haven’t done that yet).

Compare the output of the two resize methods:

JAI vs. ImageMagick Resizing in Pachyderm

Update: I get asked by email every now and then for some sample code to show how we used Runtime.exec() in this case. For the Googlers out there, here ‘s the goods…

	/**
	 * Uses a Runtime.exec()to use imagemagick to perform the given conversion
	 * operation. Returns true on success, false on failure. Does not check if
	 * either file exists.
	 *
	 * @param in Description of the Parameter
	 * @param out Description of the Parameter
	 * @param newSize Description of the Parameter
	 * @param quality Description of the Parameter
	 * @return Description of the Return Value
	 */
	private static boolean convert(File in, File out, int width, int height, int quality) {
		System.out.println("convert(" + in.getPath()+ ", " + out.getPath()+ ", " + newSize + ", " + quality);

		if (quality < 0 || quality > 100) {
			quality = 75;
		}

		ArrayList command = new ArrayList(10);

		// note: CONVERT_PROG is a class variable that stores the location of ImageMagick's convert command
		// it might be something like "/usr/local/magick/bin/convert" or something else, depending on where you installed it.
		command.add(CONVERT_PROG);
		command.add("-geometry");
		command.add(width + "x" + height);
		command.add("-quality");
		command.add("" + quality);
		command.add(in.getAbsolutePath());
		command.add(out.getAbsolutePath());

		System.out.println(command);

		return exec((String[])command.toArray(new String[1]));
	}


	/**
	 * Tries to exec the command, waits for it to finsih, logs errors if exit
	 * status is nonzero, and returns true if exit status is 0 (success).
	 *
	 * @param command Description of the Parameter
	 * @return Description of the Return Value
	 */
	private static boolean exec(String[] command) {
		Process proc;

		try {
			//System.out.println("Trying to execute command " + Arrays.asList(command));
			proc = Runtime.getRuntime().exec(command);
		} catch (IOException e) {
			System.out.println("IOException while trying to execute " + command);
			return false;
		}

		//System.out.println("Got process object, waiting to return.");

		int exitStatus;

		while (true) {
			try {
				exitStatus = proc.waitFor();
				break;
			} catch (java.lang.InterruptedException e) {
				System.out.println("Interrupted: Ignoring and waiting");
			}
		}
		if (exitStatus != 0) {
			System.out.println("Error executing command: " + exitStatus);
		}
		return (exitStatus == 0);
	}

Part of the functionality of the Pachyderm authoring application is the dynamic and on-the-fly resizing of images to whatever dimensions are required by the flash templates that are used to display a screen in a presentation.

I wrote the first version of the image resizing code using Java Advanced Imaging (JAI), and it worked quite well. But, during the authoring of the Mavericks prototype, it became apparent that the quality of the resized images wasn’t quite up to snuff. I tried setting JAI to use bicubic interpolation (InterpolationBicubic and InterpolationBicubic2) instead of the default nearest-neighbour (InterpolationNearest) method. Still produced inconsistent results.

I had looked at using ImageMagick, using the java JMagick bridge, but that was just plain funky. It relies on a JNI bridge that apparently doesn’t compile well on MacOSX (I never got it compiled, and Google only turned up one person in the history of the internets that had success – on an older version of the OS).

Fast forward to last night. I decided to try an ImageMagick solution using java’s Runtime.exec() – and it works perfectly. Image quality is MUCH better. The memory issues we were seeing with JAI disappeared (JAI was barfing on Very Large Images, where ImageMagick chews through them with ease). The downside is that it takes considerably longer to process the resized images, and since ImageMagick can only work with local files (not URLs), I have to download the image from the web each time I want to process it (this can be done more intelligently – I just haven’t done that yet).

Compare the output of the two resize methods:

JAI vs. ImageMagick Resizing in Pachyderm

Update: I get asked by email every now and then for some sample code to show how we used Runtime.exec() in this case. For the Googlers out there, here ‘s the goods…

/**
* Uses a Runtime.exec()to use imagemagick to perform the given conversion
* operation. Returns true on success, false on failure. Does not check if
* either file exists.
*
* @param in Description of the Parameter
* @param out Description of the Parameter
* @param newSize Description of the Parameter
* @param quality Description of the Parameter
* @return Description of the Return Value
*/
private static boolean convert(File in, File out, int width, int height, int quality) {
System.out.println(“convert(” + in.getPath()+ “, ” + out.getPath()+ “, ” + newSize + “, ” + quality);

if (quality < 0 || quality > 100) {
quality = 75;
}

ArrayList command = new ArrayList(10);

// note: CONVERT_PROG is a class variable that stores the location of ImageMagick’s convert command
// it might be something like “/usr/local/magick/bin/convert” or something else, depending on where you installed it.
command.add(CONVERT_PROG);
command.add(“-geometry”);
command.add(width + “x” + height);
command.add(“-quality”);
command.add(“” + quality);
command.add(in.getAbsolutePath());
command.add(out.getAbsolutePath());

System.out.println(command);

return exec((String[])command.toArray(new String[1]));
}

/**
* Tries to exec the command, waits for it to finsih, logs errors if exit
* status is nonzero, and returns true if exit status is 0 (success).
*
* @param command Description of the Parameter
* @return Description of the Return Value
*/
private static boolean exec(String[] command) {
Process proc;

try {
//System.out.println(“Trying to execute command ” + Arrays.asList(command));
proc = Runtime.getRuntime().exec(command);
} catch (IOException e) {
System.out.println(“IOException while trying to execute ” + command);
return false;
}

//System.out.println(“Got process object, waiting to return.”);

int exitStatus;

while (true) {
try {
exitStatus = proc.waitFor();
break;
} catch (java.lang.InterruptedException e) {
System.out.println(“Interrupted: Ignoring and waiting”);
}
}
if (exitStatus != 0) {
System.out.println(“Error executing command: ” + exitStatus);
}
return (exitStatus == 0);
}

BatchXSLT – Batch processing of XML files with Xalan

I’m in the process of migrating a copy of the metadata records from CAREO into an XStreamDB database. As part of that process, I’m transforming all documents from various malformed IMS LOM versions to the clean IEEE LOM schema. I looked around for a batch tool, and didn’t find one that didn’t rely on VB or MSXML or something equally unusable for me. So, I rolled my own java command line utility, called “BatchXSLT”.

It’s so brain-dead simple to write a tool like this, that I’m SURE it exists already, and must be part of the Xalan distribution (buried somewhere? the sample tools didn’t appear to handle batching). The other Xalan batch tool I saw used a shell script which spawned the java process fresh for each xml doc. That’s just plain wasteful, so this one just uses one java process, and walks through the directory as required.

Anyway, with about half an hour of coding (over half of that spent googling), I had a working tool. It’s a simple utility, but it takes 3 parameters that make it pretty useful, so I thought I’d share it with the rest of the class, just in case…

I drop the .jar file into my /Library/Java/Extensions/ directory, so it’s available system-wide.

USAGE:


java BatchXSLT inputSource XSLTFile outputDirectory

inputSource: either a file or a directory containing files to be transformed. It will attempt to transform every file in a directory, but won’t recurse through nested directories (yet).

XSLTFile: the XSLT file to be used to direct the transformation

outputDirectory: the directory where you want to store the transformed files (it doesn’t overwrite the originals, but has to stick them someplace else) – it would probably be a Good Idea for this to be a different directory than the inputSource, so there isn’t any kind of recursive/destructive cycle going on….

Here’s what I typically call:

java BatchXSLT ~/temp/rawxml ~/Documents/XSLT/LRMv1p2p1-LOMv1p0.xsl ~/temp/transformedxml

Doing that will run through the ~4000 xml documents, transforming them into nice, valid IEEE LOMs.

The source code and compiled .jar is available for download, including an XCode project. download here.

Oh, and there isn’t any kind of license or anything for this BatchXSLT app or source code. Help yourself. Make it do whatever you need. I wouldn’t mind hearing from anyone who found it useful, though… 😉

There is also no warranty of any kind… It works great for me, in my own little world and very specific use-case. I won’t guarantee that it won’t run amok and attempt to transform your kernel or swap file or something silly…

I’m in the process of migrating a copy of the metadata records from CAREO into an XStreamDB database. As part of that process, I’m transforming all documents from various malformed IMS LOM versions to the clean IEEE LOM schema. I looked around for a batch tool, and didn’t find one that didn’t rely on VB or MSXML or something equally unusable for me. So, I rolled my own java command line utility, called “BatchXSLT”.

It’s so brain-dead simple to write a tool like this, that I’m SURE it exists already, and must be part of the Xalan distribution (buried somewhere? the sample tools didn’t appear to handle batching). The other Xalan batch tool I saw used a shell script which spawned the java process fresh for each xml doc. That’s just plain wasteful, so this one just uses one java process, and walks through the directory as required.

Anyway, with about half an hour of coding (over half of that spent googling), I had a working tool. It’s a simple utility, but it takes 3 parameters that make it pretty useful, so I thought I’d share it with the rest of the class, just in case…

I drop the .jar file into my /Library/Java/Extensions/ directory, so it’s available system-wide.

USAGE:

java BatchXSLT inputSource XSLTFile outputDirectory

inputSource: either a file or a directory containing files to be transformed. It will attempt to transform every file in a directory, but won’t recurse through nested directories (yet).

XSLTFile: the XSLT file to be used to direct the transformation

outputDirectory: the directory where you want to store the transformed files (it doesn’t overwrite the originals, but has to stick them someplace else) – it would probably be a Good Idea for this to be a different directory than the inputSource, so there isn’t any kind of recursive/destructive cycle going on….

Here’s what I typically call:

java BatchXSLT ~/temp/rawxml ~/Documents/XSLT/LRMv1p2p1-LOMv1p0.xsl ~/temp/transformedxml

Doing that will run through the ~4000 xml documents, transforming them into nice, valid IEEE LOMs.

The source code and compiled .jar is available for download, including an XCode project. download here.

Oh, and there isn’t any kind of license or anything for this BatchXSLT app or source code. Help yourself. Make it do whatever you need. I wouldn’t mind hearing from anyone who found it useful, though… 😉

There is also no warranty of any kind… It works great for me, in my own little world and very specific use-case. I won’t guarantee that it won’t run amok and attempt to transform your kernel or swap file or something silly…

dom4j – Open Source library for working with XML in Java

I’m working on finishing the EOAdaptor for XStreamDB, and one route I’m exploring is taking the source XML from XStreamDB, running it through DOM and then into full EOs. I’ve been playing around with DOM libraries, and just checked out the latest beta of dom4j.

It’s evolved into one sweet library – basically takes the standard Document model, and wraps XPath, XSLT and other goodness around it. They’re even working on adding schema and validation support (which will be very handy for anyone creating XML documents on the fly. Like, say, in APOLLO…

I’ve just modified a sandbox copy of our Teaching Resources application to use dom4j, and it’s quite fast, too. It only takes about 2ms to parse a full IMS LOM record into a Document. When tied with the EOF caching stuff, that is totally acceptable (depending on what additional overhead is required to get it into EOs, that is…)

I’m working on finishing the EOAdaptor for XStreamDB, and one route I’m exploring is taking the source XML from XStreamDB, running it through DOM and then into full EOs. I’ve been playing around with DOM libraries, and just checked out the latest beta of dom4j.

It’s evolved into one sweet library – basically takes the standard Document model, and wraps XPath, XSLT and other goodness around it. They’re even working on adding schema and validation support (which will be very handy for anyone creating XML documents on the fly. Like, say, in APOLLO…

I’ve just modified a sandbox copy of our Teaching Resources application to use dom4j, and it’s quite fast, too. It only takes about 2ms to parse a full IMS LOM record into a Document. When tied with the EOF caching stuff, that is totally acceptable (depending on what additional overhead is required to get it into EOs, that is…)

Radeox – Wiki Formatting Render Engine in Java

I’ve been poking around for a decent way to implement text formatting without requiring folks to know HTML. This is for use in our Workshops management app, as well as the Discussion/Review component of CAREO (and coming soon for APOLLO).

At the bare minimum, I’d like to at least translate linefeeds into br and p tags, but ideally I want to support Textile and/or Wiki formatting.

I came across Radeox, linked from the c2 wiki.

Looks like it supports Textile and Wiki formatting out of the box. Cool. Claims to be embeddable pretty easily, so I’m working up a simple WebObjects app to try it out.

UPDATE: woah. That was fast. And simple. Had it running in under 5 minutes (would have had this posted back then, but I forgot to click “Post”, and Kung Log’s been sitting patiently under a ton and a half of open windows…)
All I did was import the radeox.jar, and add one method to my component:

private String renderTextWithRadeox( String text ) {
	RenderContext context = new BaseRenderContext();
	RenderEngine engine = new BaseRenderEngine();
	return engine.render(text, context);
}

Also, looks like it supports only a subset of the full Wiki syntax, but way more than enough for what I need…

I’ve been poking around for a decent way to implement text formatting without requiring folks to know HTML. This is for use in our Workshops management app, as well as the Discussion/Review component of CAREO (and coming soon for APOLLO).

At the bare minimum, I’d like to at least translate linefeeds into br and p tags, but ideally I want to support Textile and/or Wiki formatting.

I came across Radeox, linked from the c2 wiki.

Looks like it supports Textile and Wiki formatting out of the box. Cool. Claims to be embeddable pretty easily, so I’m working up a simple WebObjects app to try it out.

UPDATE: woah. That was fast. And simple. Had it running in under 5 minutes (would have had this posted back then, but I forgot to click “Post”, and Kung Log’s been sitting patiently under a ton and a half of open windows…)
All I did was import the radeox.jar, and add one method to my component:

private String renderTextWithRadeox( String text ) {
	RenderContext context = new BaseRenderContext();
	RenderEngine engine = new BaseRenderEngine();
	return engine.render(text, context);
}

Also, looks like it supports only a subset of the full Wiki syntax, but way more than enough for what I need…

Verifying email addresses

I’ve been working on the app that manages workshop registrations here in the Learning Commons, and have been tackling one of the major problems in the current version – people can enter invalid email addresses, and may never even know they did it. They won’t receive confirmation, and can’t receive updates/modifications.

Often, these addresses are trivially incorrect (an errant space, a missing . or whatever).

Anyway, here is the code I whipped up for the app to attempt to verify the email address. It relies on the Java InetAddress class, and does a lookup of the hostname. If there’s a machine at the hostname, I’ll assume it’s correct. (could get fancy and look up only MX records etc… but it’s a start.)


import java.util.*;
import java.net.*;

...

try {
NSLog.out.appendln("Validating email address...");

// get the hostname from the email address
StringTokenizer st = new StringTokenizer(_email, "@");
String accountName = st.nextToken();
String hostName = st.nextToken();

InetAddress emailhost = InetAddress.getByName(domainName);
NSLog.out.appendln("mailhost IP: " + emailhost.getHostAddress());

} catch (UnknownHostException e) {
NSLog.out.appendln("UnknownHostException: " + e.getMessage());
comment = "This email address appears to be invalid. Please verify your email address";

} catch (SecurityException e) {
NSLog.out.appendln("SecurityException: " + e.getMessage());
comment = "This email address appears to be invalid. Please verify your email address";

} catch (Exception e) {
NSLog.out.appendln("Unknown Exception: " + e.getMessage());
comment = "This email address appears to be invalid. Please verify your email address";

}

I’ve been working on the app that manages workshop registrations here in the Learning Commons, and have been tackling one of the major problems in the current version – people can enter invalid email addresses, and may never even know they did it. They won’t receive confirmation, and can’t receive updates/modifications.

Often, these addresses are trivially incorrect (an errant space, a missing . or whatever).

Anyway, here is the code I whipped up for the app to attempt to verify the email address. It relies on the Java InetAddress class, and does a lookup of the hostname. If there’s a machine at the hostname, I’ll assume it’s correct. (could get fancy and look up only MX records etc… but it’s a start.)


import java.util.*;
import java.net.*;

...

try {
NSLog.out.appendln("Validating email address...");

// get the hostname from the email address
StringTokenizer st = new StringTokenizer(_email, "@");
String accountName = st.nextToken();
String hostName = st.nextToken();

InetAddress emailhost = InetAddress.getByName(domainName);
NSLog.out.appendln("mailhost IP: " + emailhost.getHostAddress());

} catch (UnknownHostException e) {
NSLog.out.appendln("UnknownHostException: " + e.getMessage());
comment = "This email address appears to be invalid. Please verify your email address";

} catch (SecurityException e) {
NSLog.out.appendln("SecurityException: " + e.getMessage());
comment = "This email address appears to be invalid. Please verify your email address";

} catch (Exception e) {
NSLog.out.appendln("Unknown Exception: " + e.getMessage());
comment = "This email address appears to be invalid. Please verify your email address";

}