Wednesday, January 30, 2008

Beginning with SQL Server

Given changes in the environment in which our business does it's business, I've had to start learning to use SQL Server and various other Microsoft technologies lately. A quick note on connecting to a foreign SQL Server instance (ie another company's ...) :


Create an alias for the database so that Enterprise Manager has something to work with

Open up the Client Network Utility which should be included in the Start menu programs group for your SQL Server installation.
Start -> Programs -> Microsoft SQL Server -> Client Network Utility -> Alias (tab) -> Add... (button).
Under 'Server alias' enter an easy to remember name for the connection. Under 'Network libraries' select the TCP/IP option. Under 'Connection parameters' enter the DNS name or IP address under 'Server name' of the server you wish to connect to. Change the option for 'Dynamically determine port' if the server you're attempting to connect to doesn't run under the standard port of 1433 for SQL Server. Hit 'Ok' to save your settings, then 'Ok' to close out of the Client Network Utility.

Create a new SQL Server Registration to add your SQL Server instance to the Enterprise Manager

Open Enterprise Manager. It should be in the same programs group in the start menu as the Client Network Utility. Once open, create a new SQL Server Group if you haven't already got one (or haven't got one that you want to add your new SQL Server instance to). Then add a new SQL Server Registration. You should be prompted by a Wizard at this point. (If you're not, then you've probably already disabled the Wizard and don't need to be reading this tutorial.) In the wizard, click on 'Next' to proceed to the SQL Server selection screen. Under the list of available servers, you should see the alias you just created in the previous step. Select it and click on 'Add >' to add it to the list of added servers, and then click on 'Next'. After this, you should be prompted for credentials, and the rest is pretty self explanatory.

Thursday, December 20, 2007

Cool MySQL tricks

It's been a while since I've written a blog post, and I figured this was a good topic to write about. For the most part, I don't use SQL. There's numerous ORM (Object-Relational Mapping) tools and frameworks out there (ie Hibernate) that abstract away all the boiler-plate CRUD code. When I do have to use SQL (be it on the command line or with a query browser), I'm not afraid to dive right in, and it's interesting to learn new things about SQL because there's so much to learn and it's such a ridiculously powerful query language.

I had to update the configuration in one of my databases, but the configuration required inserting numerous new lines into a table for user roles. I could've written a stored procedure to do it, but given my (admittedly somewhat limited) knowledge of SQL, I figured this would take too much time and I didn't want to do it. (This is what I like to call constructive laziness). I kept Googling and found MySQL's INSERT INTO ... SELECT syntax, which allows you to conveniently insert the results of one query into another table. I'm sure that most other database implementations out there have a similar convenience syntax, but I happen to work with MySQL so there you go. It took what would've been a numerous line script with looping and separate SELECT and INSERT statements down to a one liner. If you use MySQL (especially with LAMP / AJAX) I recommend that you read about it.

Monday, December 03, 2007

Deleting .svn folders

Subversion is a great tool, but unfortunately it has to store metadata somewhere, and like all other code repository tools, it stores them in metadata directories ... for each directory in whatever project you're working with. I recently found that I have to copy parts of my project documentation out for some of our clients to access our APIs, and I wanted to quickly delete all the SVN metadata and trim certain other files where necessary. I figured the quickest way to do with would be a simple command. Windows PowerShell provides a good (though not great, and certainly not as good as bash) way of doing it :


Get-ChildItem -Recurse -force |where {$_.PSIsContainer -AND $_.Name -match "svn"} | foreach ($_) {remove-item -force -recurse $_.fullname}


Two Google queries yielded the above command from this blog. Happy reading.

Sunday, December 02, 2007

Resolving logging issues with Tomcat

An idea for resolving the logging issues in Tomcat just occurred to me. I should probably be putting the logging jars in the individual lib directories for each of the webapps. I'll have to give this a try and post my results.

Thursday, November 29, 2007

Onward to Eclipse Europa ... and then right back

Ok, so after Eclipse Europa (3.3) has been out for quite some time, I decided to give it a try. I was shocked to discover a lot of the changes that had happend :
it seems that the Eclipse foundation has become Red Hat's bitch. There's a ton of new Red Hat sponsored / produced editors (none of which are very good.) There's a ton of useless JBoss integration. The editor overall is slower. All my hotkeys (save one or two, literally) were standard with installation in Eclipse 3.2, and are now broken in Eclipse 3.3. I'm severely disapponted after using Europa for three weeks. The only good part about it is that access to my SVN repository was considerably faster. And it seems I'm not the only one who feels this way about Europa. Get it together Eclipse.

Oh, and the thing that brought me to writing this post in the first place : the XML schema editor is flat out broken. What the fuck ?!

Thursday, November 15, 2007

Spring, Tomcat and memory

As my application has been growing more and more in functionality, it has also been growing in its memory footprint. To that end, I've started getting OutOfMemoryErrors because the heap has started overflowing. That's really not a problem if you have access to the external Tomcat server, you can just increase the heap size using "-Xms128M -Xmx512M" (or other applicable sizes) on the command line, or do this via the GUI if you're running Tomcat in Windows. However, it's not as obvious if you're using Tomcat for debugging within the Web Tools Platform plugins for Eclipse. I started running into this problem recently and it ground my development to a halt until I was able to fix the problem for WTP in Eclipse. WTP passes its arguments to the Tomcat server via the Launch Configuration. To get to it, right click on the Tomcat server in the Servers view -> 'Open' -> 'Open launch configuration' -> 'Arguments' tab -> 'VM arguments:' text box, then add the "-Xms128M -Xmx512M" segment to the end of the parameter list.

Saturday, November 03, 2007

Actual plugin development for Maven 2

Ok, so after Googling around and hours of patient command line testing (yeah, I know, it's horrible, you don't have to tell me) I managed to complete my ToLDya plugin for generating TLD files. Hopefully this plugin will be a great aid to people developing JSP tag libraries other than myself. But along the way, I learned a lot about plugin development in Maven, and I'm quite certain that I've got a shitload more to learn.


  1. Starting out with a barebones Mojo from the Maven provided archetype literally doesn't get you much. It gets you just enough to plug into the Maven framework so that maven can actually run your Mojo, but that's about it.

  2. The AbstractMojo provided by Maven is pathetic. It gives you a logger, and that's about it. By default, it does not give you many of the things a plugin is quite likely to want (more about that later)

  3. Despite the fact that Maven 2 was supposed to be the "lessons learned" version of Maven, I don't think that the Maven developers learned much at all. Maven is grossly behind the times, still relying on XDoclet annotations and pre-JDK 5.0 compatibility. Yes, there is something to be said for keeping things backward compatible (especially in a corporate environment, I know), but at some point you have to move on and do better, in this case : getting up to date with the latest JDK (1.6.03 at the time of this writing).

  4. If you need anything (ie from Maven) while writing a Maven plugin, you have to specifically request that it be injected for you. (See the Maven documentation, this is the one area where they're actually good about documenting things and helping out developers)

  5. If your plugin needs to access any of the classes in the project on which it's run, you need to load them yourself with your own classloader. Maven will not give you one (which is pretty ridiculous to my mind).



Here are some important bits of knowledge for doing anything with a Maven plugin:

  • If you need access to anything from the project (ie any information stored in the POM), you'll need to include the following dependency :


    <dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-project</artifactId>
    <version>${maven.version}</version>
    </dependency>

    In my current POM, the property 'maven.version' is set to 2.0.7. You'll then need to have a property in your plugin Mojo called 'property' (or whatever else you find suitable) and annotate it like so (from within a Javadoc comment of course):



    * @parameter expression="${project}"
    * @required


  • As mentioned previously, if you want to load any of the classes that are in the project on which your plugin is to execute, you have to load them yourself. The same goes for any of the project's dependencies. In order to do this, you'll have to get the list of dependencies (compile, test, runtime) from the MavenProject object ('property', remember?) The MavenProject object has a property called 'runtimeClasspathElements'. This gives you a list of strings that are fully qualified file system paths to the classes in the ${project.build.outputDirectory} as well as all of the dependency JARs on which the client project depends. You'll then have to load them yourself. I did so with a URLClassLoader (part of the JDK). I used the following function for creating the classloader :


    private static URLClassLoader getDependencyClassloader(List dependencies) throws MalformedURLException {
    List classpathUrls = new Vector();

    URL url = null;
    for(int index = dependencies.size() - 1; index >= 0; index--) {
    url = new File(dependencies.get(index)).toURI().toURL();

    classpathUrls.add(
    url.toExternalForm().endsWith(".jar") ?
    url :
    new URL(url.getProtocol(),url.getHost(),url.getPort(),url.getFile() + "/") //add the '/' o indicate a directory );
    }
    URLClassLoader ucl = new URLClassLoader(classpathUrls.toArray(new RL[] {}), Thread.currentThread().getContextClassLoader());

    return ucl;
    }

    Once you have this class loader, you can use it in the long version of Class.forName() to load any classes you may need, as well as perform any loading logic you need with the .getResources() functions on the classloader.





I'll be doing more plugin development in the coming months I'm sure, so I'll try to post what I learn here, but that's about it for now.

Thursday, November 01, 2007

Plugin development with Maven, obsessed

Ok, I let my obsessions get the better of me and I couldn't drop it : I kept searching the interwebs until I had found a solution for my problem. Surprise, surprise, the maven-plugin-testing-harness is a broken ass piece of shit. Enough editorializing though, here's how things went :

1) I had to make sure all of this sh*t was in my POM :
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-descriptor</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-plugin-testing-harness</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>

2) I then had to change from using 'lookupMojo' to instantiating my own mojo and using 'configureMojo' on the test harness. With the former, you'd have to put the /META-INF/maven/plugin.xml file somewhere on the classpath so that the MavenPluginDiscoverer module can detected it.

Why didn't they just tell you helpful things like these on the wikis for the plugins ? God dammit, I'm quickly hating Maven more and more. And to boot, it doesn't properly evaluate the required expressions and inject stubs for them, but maybe I've just missed something (easy, given how poor the documentation for the project is).

The anniversary

I didn't even notice it until today that it's the one year anniversary of this blog. Actually, the anniversary was two days ago, but close enough. Considering my general dislike of (non-development) blogs, that's actually quite impressive. I didn't think it'd last this long. Yay blog.

Maven ... OMG

My recent foray into developing Maven plugins has led me to a horrible discovery : the Maven developers ... suck. They're just not professional. There's no javadoc for the core classes. There's no javadoc for the base plugin classes and interfaces. And the AbstractMojo class which is supposed to be a good starting base class for all other plugins is, to say the least, horribly designed : it doesn't contain access to the MavenProject that's currently being operated on, you have to add it in manually Ironically (or appropriately, take your pick) they made that a plugin too. The supposed "tutorial" on the Maven main site doesn't show any mention of this. The plugin "cookbook" on the site has been "coming soon" for so long that you have to wonder if it's ever going to get written. And, on top of all this, there's no generics and no direct support for JDK 5 annotations and enums. (See previous post). I've now reached a point of severe disappointment with the Maven project, and I'm fast approaching the point where I'm genuinely sorry that I've made this much of a time investment in it.

Wednesday, October 31, 2007

Maven 2 quirks and the "bandwagon"

I recently found myself developing (and using) a lot of small tag libraries to make my life easier when it comes to developing my web applications. The only thing that really gets me is that when I write these tag libraries, I have to manually update all of the TLD (tag library descriptor) files that are necessary for using the tags in JSPs. This irks me and it occurs to me that there's no reason I can't have Maven generate the TLDs for me based on annotations I place on the tag classes. The only problem with this is that no such plugin exists, so I figured that as a foray into Maven plugin development, I'd try making such a plugin as my first try. It is then that I ran across a rather large and bothersome quirk with Maven : it's not entirely ready for Java 5 and up. In fact, rather than using proper Java 5 annotations, it uses XDoclet comment annotations to provide metadata for building plugins, but that's not the quirk. The real quirk is that it can't handle having Java 5 annotations in the same project as the plugin. It can handle Java 5 enums just fine, but not annotations, which seems rather strange to me.

This is all part of the bigger problem of companies not keeping themselves up to date with the latest Java technology and staying with Java 1.4.2 and earlier. Sun has done a great job of maintaining backward compatibility, and there's (almost) no reason that companies shouldn't be upgrading the JVMs on their servers to the latest and greatest versions. The only real reason I can think of is that somewhere in their code, they've used variables named 'enum' which becomes a Java keyword in Java 5 and up (aka Java 1.5, 1.6, etc), and this can be mitigated by refactoring the code. Hell, Eclipse makes that job quick and easy, especially when you really know your keyboard shortcuts. I'm fortunate enough to be able to use Java 6 (and very quickly upgrade to Java 7 as soon as it's released and stable). As much as this is going to make me a snob, I'm getting really tired of being dragged down by other people's need for backward compatibility (and hence also tool developers' appeasement of these people which then affects me). Seriously people, get your act together.

Wednesday, October 24, 2007

Java enums are even cooler than I ever knew !

A quick note on Java enums : I discovered today that not only can enums have methods (which is exceedingly useful to begin with), but that you can individually override methods on a per-enum-value basis! That's so cool. I read it on this blog.

Sunday, October 21, 2007

An interesting Spring Framework quirk

Recently, I discovered the joy of the PropertyEditorRegistrar interface in the Springframework, for conveniently registering property editors to bind between objects and text when rendering forms. This joy led me to discover an interesting quirk : if you subclass a Form Controller and register property editors that way, the object of a field will be bound to the BindStatus.value property, but if you use a PropertyEditorRegistrar, that value gets edited and the spring representation of it bound to BindStatus.value. This is a small distinction that makes a huge difference when writing (and rendering) your pages.

Wednesday, October 17, 2007

RSS and Me

I love RSS, I think it's a great way to read the news and generally stay up to date on any sites you read and any (legit) torrents you may want to download, or podcasts if that's your thing. I've been kicking around the idea of having an RSS notifier for our system at work, so that I wouldn't have to be sending out extraneous emails all over the place. According to this guy, creating an RSS feed is stupid simple. Maybe when I get the chance I'll give it a try.

*EDIT* : Ok, me being me, I was fascinated with the idea of dealing with something new and couldn't let it go. I followed one breadcrumb after another and found, fortunately for me, that Spring already has an (Abstract)RSS view class in the Spring Modules library that uses the Java Rome RSS library in the background. I can't wait to slog through the crap I have to deal with at the moment so that I can fool around with RSS and have RSS feeds supplying the notifications for our production system. This is going to save so many headaches.

*EDIT 2* : Heh, this guy's page is awesome. It shows that you can use security with RSS feeds, which will be perfect for my company.

Monday, October 15, 2007

Moar Hibernate !!!

Yet again, I'm posting because of fucking hibernate. One of the old quirks I had run across was that if you had a setter for a collection, ie :

public void setItems(List items)
{
this.items = items;
}

...this would replace the hibernate-backed collection that already existed (if one did) and could replace it with a non-hibernate implementation such as java.util.Vector, and any cached items would not get properly dealt with, and the collection would not get properly persisted, even to the point of throwing an exception. This resulted in me having to change my setters to this :

public void setItems(List items)
{
if(this.items == null)
{
this.items = items;
} else
{
this.items.clear();
this.items.addAll(items);
}
}

The only problem with this is that depending on the scenario, hibernate gets the collection, and then sets exactly the same list object back into the persistent entity we're dealing with, which would result in clearing exactly the same list we're trying to assign. The remedy :

public void setItems(List items)
{
if(this.items == null)
{
this.items = items;
} else if(this.items != items) //fix: identity check the two lists!
{
this.items.clear();
this.items.addAll(items);
}
}

That really should have been there anyway, but hibernate inspired it. Fuck you hibernate.

Saturday, October 13, 2007

Spring and PropertyEditors, important details

As mentioned in the documentation, the Spring Framework uses property editors in two places:
1) When parsing ApplicationContexts from XML configuration files
2) When binding beans from HTTP requests.

It's all well and good if the only classes you need to bind are already covered by the editors built in with the Spring Framework, but if you need property editors for other kinds of classes, here's how to get Spring to include them, for both situations :
1) Use a CustomEditorConfigurer like so :

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.text.DateFormat">
<bean class="com.mypackage.CustomDateFormatEditor"/>
</entry>
<entry key="java.util.TimeZone">
<bean class="com.mypackage.TimeZoneEditor"/>
</entry>
<entry key="java.text.MessageFormat">
<bean class="com.mypackage.CustomMessageFormatEditor"/>
</entry>
<entry key="java.text.NumberFormat">
<bean class="com.mypackage.CustomNumberFormatEditor"/>
</entry>
</map>
</property>
</bean>

* Note * : The editors can be singletons because they're going to be the only instances needed by the application context to parse string values.

2) Implement and instantiate (or otherwise use) an implementation of PropertyEditorRegistrar. This will be used with your form controllers to register property editors for individual fields or whole types.

Thursday, October 04, 2007

Ubuntu Linux is finally in the right place

I love Linux. Now, at this point, you're probably thinking that I'm just one of these fanboy nerds that loves to sit on a computer all day and hack on code. You're partially right : I do love to sit on computers and hack on code, but certainly not all day and certainly not at the expense of other fun activities like going to hockey games and being with friends. That said, I like Linux because it's good for doing development and it's ridiculously stable. It's even quite performant as well, which is
quite nice. I like it to the point that I'd want to put it on all of the computers here in the office, and as per the title of this post, I think that Ubuntu Linux is at the point where that's a practical possibility. In the past few days, I've installed Ubuntu 7.04 (Feisty Fawn) on two machines here in the office, set them up to do networked printing, networked file sharing, and everything else that may be needed by office workers. Hell, they can even use the built in Terminal Services client to remote into our server here in the office if they need to do any centralized work. They even have all their networked drives mounted for them, and they can see the Windows domain on which this place runs. The only thing remaining is for the systems to pass the Boss Test : sit the big boss of the company down on one, and if he can print his stuff, access his stuff and access our server exactly the same as he could in Windows, then it stays.

There's a great tutorial on setting up Samba with Windows Shares in Ubuntu here. Printing was
ridiculously easy to set up : I went to System -> Administration -> Printing , it autodetected the printers on our LAN and setting them up was merely a matter of following on screen directions.

Wednesday, September 26, 2007

MySQL character sets, the end

Many times in the past I've tried to get our foreign MySQL server to properly store and handle unicode character sets. Despite the fact that I repeatedly set 'default-character-set=utf8' all over the config files and set the server and client character sets and collations in my.cnf, it still wouldn't handle them properly. Here's the kicker : to make absolutely sure that the server uses only server settings for handling character set (and sets 'fuck you' to whatever the client requests), you have to use the '--skip-character-set-client-handshake' argument when starting the MySQL daemon (server). This is what finally got it going for me. I hope this post helps somebody out someday. (Given my rate of forgetting things, it's likely to be me)

Tuesday, September 11, 2007

<rage>MOAR HIBERNATE! :@</rage>

God damn, I'm getting so fucking tired of Hibernate and its quirks. Here's a new one regarding Criteria queries :

When you create a criteria query, you almost invariably have to specify a result transformer of Criterion.DISTINCT_ROOT_ENTITY (that's a quirk, but not the topic of this post). When you have an entity on which you want to build a criteria query and you want to limit the number of search results (ie distinct root entities), things get really tricky. Specifying 'setMaxResults' on the query affects the number of rows returned from the database that are actually inspected. Therefore, if there are any joins on your entity that have collections, this will cause a fetch with an outer join strategy to generate an excessive number of rows and affect the results when using a maxResults setting. In the case of using embedded properties, specifying a fetch mode of SELECT will not override these (this is a glitch in hibernate). You'll have to specify the fetch mode manually in the metadata (be it XML or Annotations) permanently for the embedded class. I fucking hate Hibernate sometimes, I really do.

Friday, September 07, 2007

Spring AOP rage ...subsiding

Spring AOP is breaking my heart. Spring overall is a great framework and I love working with it. The idea of using aspects to interweave code and keep concerns separated and code clean is a wonderful though to somebody who loves to architect software, such as myself. But I swear, it feels like I'm hitting every bug in the book when it comes to using AOP in Spring. Certain pointcuts don't get matched properly, regexp based pointcuts get loaded when they shouldn't, the list goes on. I really want to use AOP to design the next big phase of my project that's coming up, but they're making it really hard to justify the decision to do so. You're making my heart cry, Spring.