Thursday, June 05, 2008
Why you should always export your sources with your Java projects
JAXB schemagen - Finally got it working
For those not in the know, schemagen is a program that comes as part of the Java Web Services Developer Pack and it's used to generated XML schemas from JAXB annotations on Java beans. It so happens that the creators of the JAXB reference implementation also made a Maven 2 plugin for this program. I had previously attempted to use it to generate schemas in my initial attempts with JAXB, but had been presented with a slough of unfriendly exceptions being thrown at me whenever I ran the plugin. Not having the time back then to really play around with it and being considerably less experienced with JAXB, I had to shelve it and find other, less satisfying solutions to my problems with generating documentation.
Recently, I've had to come back to using JAXB because I'm making a RESTful Web Services API that leverages the power of both JAXB and Hibernate to do all my heavy lifting for me. This time around, I wasn't willing to tolerate a lack of schema to give to our users of the API, because it would mean a lot more work for them, and a lot more work for me. This time, I decided to be persistent and dig around the jaxb-schemagen plugin to make sure I could get it working. I'm proud to say that my perseverance paid off, and I now have my RESTful API schema being automatically generated for my application. Here are the problems and the solutions I ran into when I was trying to get going on this:
- NullPointerException
- I came across persistent NullPointerExceptions while trying to run the plugin at first. The stack trace indicated that the problem was with apt, the Java annotation processing tool. I later discovered that in order to properly map your classes into XSD schema types, you must specify an @XmlType annotation on *all* of the classes you wish to map (at least with JAXB 2.0, which is the version I'm currently using)
- ClassCastException
- After I resolved the first problem, I came across another pesky exception that likewise did not provide any useful debugging information. The plugin output indicated that it was finding annotations that it didn't know how to deal with, specifically the Java Persistence API annotations that I was using for Hibernate. After much digging around on Google and some detective work, I discovered that any annotations encountered by the jaxb-schemagen plugin had to be on the Maven runtime classpath. I double checked my POM to find that I had specified the scope of the JPA / Hibernate annotations as 'provided', which instructs Maven not to load them into either the compile or runtime classpaths. The initial reason I had for specifying the dependency scope as 'provided' was so that they would not needlessly get included with my project WAR files. I changed their scope to 'compile' (which also includes 'runtime') and voila, apt could now properly detect the unknown annotations, and get past them to deal with the JAXB annotations it needs to create the XML schema.
If anybody else encounters similar errors with JAXB-schemagen, I hope they find this page and find it useful.
Tuesday, June 03, 2008
Fixing package retrieval quirks in Ubuntu Gutsy Gibbon Server
/etc/apt/sources.list, and you'll have to find a line similar to :
deb cdrom:[Ubuntu-Server 7.10 _Gutsy Gibbon_ - Release i386 (20071016)]/ gutsy main restricted
Comment out this line, try your update again and you should be good to go.
Tuesday, May 27, 2008
Fixing Messenger when you've accidentally screwed it up
Monday, May 26, 2008
How to recurlively delete a folder and its contents in PowerShell
Remove-Item -recurse -force [directory name]
The really sad thing is that I googled this and there are no sites that explicitly state how to do this. The comparable command in bash :
rm -rf [directory name]
Yet one more reason I hate Microsoft and PowerShell in particular.
RESTful web services with JAXB 2.0
Thursday, May 08, 2008
Logging for tests using the Spring Framework
It's been a while since I've posted to the blog 'cause I've been so busy, and it seems fitting that this be a good way to resume posting, as this issue has pissed me off quite a bit and been a major thorn in my side for the longest time.
The Spring Framework has some pretty good support for creating test classes for your application, however it by default does not properly initialize log4j logging when doing tests, and I found out today why. When running your application in a Servlet container, you'd configure Spring logging in web.xml. However, when running in a standalone context, Spring has no way of knowing how you want logging configured, so it leaves it up to log4j to configure itself. On that front, you have to realize what log4j's default configuration strategy is : reading a 'log4j.properties' file from the root of the classpath. Once this hits you (and it took me a while), getting logging running for your test cases becomes a simple matter of placing a valid 'log4j.properties' config file in the root of your test classpath, and logging starts working properly, so now you can read those pesky hibernate generated queries off your test log .
Monday, March 31, 2008
Determining which version of Ubuntu you're running
cat /etc/issue
I learned of this little trick from here.
*Edit (2008-10-29)*
A much better command for determining the current Ubuntu version you're running :
lsb_release -a
Sunday, March 30, 2008
More random MySQL glitches
java.lang.NullPointerException
at com.mysql.jdbc.StringUtils.indexOfIgnoreCaseRespectQuotes(StringUtils.java:959)
at com.mysql.jdbc.DatabaseMetaData.getCallStmtParameterTypes(DatabaseMetaData.java:1296)
at com.mysql.jdbc.DatabaseMetaData.getProcedureColumns(DatabaseMetaData.java:3670)
at com.mysql.jdbc.CallableStatement.determineParameterTypes(CallableStatement.java:702)
at com.mysql.jdbc.CallableStatement.(CallableStatement.java:513)
at com.mysql.jdbc.Connection.parseCallableStatement(Connection.java:4422)
at com.mysql.jdbc.Connection.prepareCall(Connection.java:4496)
at com.mysql.jdbc.Connection.prepareCall(Connection.java:4470)
at org.apache.commons.dbcp.DelegatingConnection.prepareCall(DelegatingConnection.java:275)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.prepareCall(PoolingDataSource.java:292)
As it turns out, there was a permissions issue whereby the function was created with a line specifying the definer and this causes the 'SHOW CREATE FUNCTION' call to fail and return null unless the user calling the statement has permissions for select on the 'mysql' database. Some recommended solutions (that I didn't get around to trying) were changing the call to 'prepareStatement' as opposed to 'prepareCall'. The issue is logged as MySQL Bug #24065. Lately it just seems as if I keep hitting every bug out there, and can't get anything done. I hope this helps somebody.
Commons VFS (FTP) problems
Monday, March 03, 2008
Software developers are arrogant assholes
Tuesday, February 26, 2008
Setting up your own domain in (Ubuntu) Linux
I'd love to be able to write a coherent guide based off of the information from these pages, but I'm just too busy at work to do it at the moment.
Monday, February 25, 2008
A Quick note on SFTP jails
Thursday, February 14, 2008
Understanding Linux ACLs
Ok, so for a while, I've had an SFTP jail setup within our company for our clients to connect and dump batch files to our systems. It later became necessary to have an administrator user for our staff to be able to go in and read any of the files from any of the clients without having to use a bunch of different logins to login as each individual client. This makes sense as doing so would be far too cumbersome. This is where ACLs came in. I learned what I had to so that I could get going, but that wasn't very much (forunately at the time, unfortunately later). I've since learned a couple of interesting things since then:
There are two types of ACLs in Linux :
- The access ACL which controls access to files and directories
- The default ACL which applies to directories only and acts like a template for newly created files and subdirectories within that directory.
The former I knew about right from the beginning (pretty obvious), but I didn't really know the proper name for what I was manipulating. The latter I learned about today, and had previously assumed that Access and Default ACLs were one and the same (I didn't know about the distinction because it wasn't mentioned in the fucking
manpage.
Wednesday, February 13, 2008
Today's karmic balance
Use DTDs, they're there for a reason
As the title of this post states, if you're a web developer, use a fucking DTD. They exist for a reason, that reason being to allow web browsers to have a reasonable expectation of the content and layout of your website so they can deliver the desired experience to your user. If you're a web developer and you don't know what a DTD is, then you're in serious fucking trouble. In the event that you don't know, DTD stands for Document Type Definition, and it's a single line of XML that goes at the very beginning of HTML documents and almost at the very beginning of XML documents (if they're validated by DTDs). An example of a DTD :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
That DTD is for a strictly validated XHTML 1.0 compliant HTML document. This means that it's strongly validated and web browsers can expect everything after it to be well-formed quality. That's right bitches, I use a good version of HTML and I'm standards compliant like a mofo.
</rant>
Sorry, but I just had to get that out. Lately, I'm being inundated with pages from our partners that don't use DTDs, don't validate to anything, and are just generally horrible markup. Now, normally, a person wouldn't need to care, but when your partners are lame and you have to scrape their pages for data, the lack of developing to a DTD becomes a giant pain in the ass.
Tuesday, February 12, 2008
A letter to Apple
Dear Apple,
In case you haven't figured it out from my buying patterns, I've stopped buying music from you that isn't DRM-free. This is because, as Steve Jobs has admitted himself, DRM is archaic, and frankly doesn't work. What your company doesn't seem to realize is that if you want to continue your high level of sales, (especially to technophiles / audiophiles such as myself) you're going to need to get going on casting off the DRM that exists on your considerable library of music. I steadfastly refuse to purchase any music that is not DRM-free. I want to be able to play it anywhere on whatever device I may happen to own, and I'm not going to cave into unreasonable demands of an already clearly greedy music industry that refuses to evolve and adapt to technological reality. If I can't purchase music through large corporations such as yourself, I'm going to look elsewhere : smaller sites, independent labels, and independent artists who publish their music for free. So, until you get your head out of your ass : screw you, you're not getting one thin dime from my pocket.
Wednesday, January 30, 2008
Beginning with SQL Server
- 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
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
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.