Posts

Generating thumbnail images: AffineTransformOp gotchas

AffineTransformOp is a Java 2D filter that can scale (resize), rotate, and/or skew an image. Since I was generating thumbnails, I was only interested in its scaling ability. To scale an image using AffineTransformOp, all you need to do is generate a new AffineTransform using the static method AffineTransform.getScaleInstance, then use it to construct an AffineTransformOp. When constructing an AffineTransformOp, you also need to pass a constant theat identifies the type of interpolation to use, either nearest neighbor, bilinear, or bicubic. Once you have the AffineTransformOp, you just call the filter method, passing in the original image and the destination image, which can be null, in which case AffineTransformOp will create a destination image for you. After generating my first thumbnail image and saving it as a JPEG, I was able to view my generated thumbnail image in Preview, but it looked like crap. It looked blocky, as if AffineTransformOp was using the nearest neighbor interp...

Java 2D image-processing gotchas

I've been working with Java 2D a fair bit over the past few weeks and encountered a fair number of gotchas, or least behavior that seemed strange to me at first but that eventually made sense, once I thought about it and/or UTSL and figured out why it was working that way. By way of background, I've mostly been developing web applications for the past eight years, so my experience with Java 2D is minimal. I've been investigating the image-processing capabilities of Java 2D because I need to implement a new feature for my photography web site, photoSIG . The feature will blur thumbnail images of photos on the photo-browsing pages if the "content rating" of those photos is either R or X, and the page is displaying advertising. The purpose of this new feature is to recover some advertising inventory that I currently can't use because advertisers don't want their ads appearing on the same page as R or X photos, even if they're thumbnails. At various poi...

Fighting words on Ruby

Is anyone but me dismayed by the current state of Ruby? It's a great language, and it has a lot of promise--but there are also major issues that make Ruby and related efforts seem more like a set of academic projects than serious production-quality programming tools. The main thing that prevents me from using Ruby is that the 1.8 interpreter is too weak, and the other alternatives are too immature. I can use Ruby for scripting in the same way that I'd use Perl or PHP, but I wouldn't want to write a major application using a technology that doesn't support native threads, Unicode, or some kind of GUI. Yes, I know that you can roll some primitive Unicode support into Ruby, and I know that there are several GUI toolkits out there, but overall, Ruby's support for anything beyond basic scripting is spotty. So what are the alternatives? I guess the front-runner is JRuby, but JRuby is really just a scripting language that works with Java, not something that you'd ...

JetBrains TeamCity 1.0 beta

I decided to give the JetBrains TeamCity 1.0 beta a try. JetBrains is the company that makes IntelliJ IDEA, the best Java IDE by far, and TeamCity is their new continuous build tool. You can download TeamCity as either a WAR or a ZIP, which includes Tomcat. I downloaded the ZIP and unpacked it into a directory on my iMac. It looked like a pretty standard Tomcat layout. I ran the startup script, and (after giving me a warning about a missing work directory) it started up. So far, so good. I accessed TeamCity on its default port of 8111. The main page appeared and invited me to create a new administration account. What could be easier than that? I didn't have to configure anything beforehand; the software was smart enough to know that the first account created has to be an administrator account. After logging in, I headed to the Administration page and created a new project. I use Perforce for source control, and TeamCity supports Perforce directly. I created a new client ...

Who needs DAOs when there's Hibernate?

I'm sure that everyone is familiar with the data access object or DAO pattern. The basic idea of a DAO is that you encapsulate the nitty gritty details of saving and loading data to and from a persistent store in an object so your application logic isn't riddled with SQL or filesystem access or whatever it is that your DAO does. In the two years that I've been working with Hibernate, the DAO pattern continues to bother me. I always seem to be writing the same code over and over again: save this, load that, run some query, etc. Whenever I have to repeat myself a lot, I start to think that something's wrong. I eventually put some of the common stuff into a general-purpose DAO class that I used as the superclass for all my other DAOs, but then it seemed that my DAO superclass was just a less-functional wrapper around the Hibernate Session interface. I also kept having to write code to do things that Hibernate already supports, for example, query by example. A deeper ...

Does Maven actually make things easier?

I've been using Maven 2.0.4 for the last month or two and am discovering that I spend so much time dealing with Maven that I am wondering if I should give it up completely and go back to Ant. I used Maven archetypes to set up my project modules, and that worked pretty well. But almost immediately, I found myself on the Maven treadmill. One of the improvements that Maven 2 has over Maven 1 (which I have never used) is support for transitive dependencies. That means that Maven will download not only the artifacts (usually jars) that your project needs, but also any artifacts that those artifacts need, and so forth, to any depth. It sounds cool, but it's not so simple in practice. For one thing, in order to figure out the transitive dependencies, Maven has to download the POM (project object model) files for all the dependencies, but many artifacts in the Maven 2 repository do not have POM files. In that case, I have to work out the dependencies myself and add them to my proje...

Getting more complicated

I was reading about C in Wikipedia (under C programming language ). The article first presented the ubiquitous "hello, world" program written in K&R C: main() { printf("hello, world\n"); } and then the same program in ANSI C: #include <stdio.h> int main(void) { printf("hello, world\n"); return 0; } Now I know that ANSI C is an improvement over K&R C. But in this case, the "improvement" has produced a program that needs two additional lines to accomplish the same thing. Wouldn't it be better if technologists spent time making technologies simpler rather than more complicated? It's true that simpler technologies are always arriving. But unfortunately the tendency for any single technology is to get more complicated rather than less. I think that the only real reason why C hasn't gotten significantly more complicated since ANSI C is that all the extra features got tacked on to C++ instead, making it an insa...

java.util.Date must die

I find java.util.Date to be most of the most annoying class in the entire Java class library. It is essentially a wart left over from Java 1.0, but the fact that it is used in many APIs makes it difficult to remove. The most insidious aspect of Date is that despite being nothing more than a wrapper around a long, Date is mutable. Anyone can call the setTime method and change the internal long. That causes problems with methods changing Date instances that are passed to them and code accidentally changing Date instances that are members of collections. What benefit comes from Date being mutable? Java understands the benefits of immutable objects. String is immutable. Long is immutable. Why not Date? What's worse is that the SQL date types specified by JDBC inherit from java.util.Date, making them mutable too! That's in addition to the general inconvenience imposed by having them in the first place. The inconvenience of Date might be acceptable if it actually did somethi...

UUIDs as primary keys

I wrote in my last post that I preferred to let the database just store data and and implement all the business logic in my Java code but that I usually let the database handle primary key generation. After thinking about it for a few days, I decided to experiment with using UUIDs as primary keys. Java 5 has a convenient java.util.UUID class that I used to replace the integer identifiers in my entity classes. I found a bunch of blog entries about using UUID versus integer primary keys. UUIDs do have some disadvantages: UUIDs are larger than integer IDs. A UUID, when stored in its most compact form, consumes 128 bits, or 16 bytes. That's four times larger than a regular 32-bit integer. UUIDs are binary. While they fit in a 16-byte binary column, when expanded into a string, they typically consume 32 or 36 characters, depending on whether the string is the human-friendly 00112233-4455-6677-8899-aabbccddeeff format. UUIDs are computationally harder to generate than integers. The disad...

Property methods: just shoot me now

How much time I spend, writing crap like this: class Something { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public setName(String name) { this.name = name; } } Any decent IDE will generate the property methods for you, but why is this necessary? Way back in ancient history, Visual Basic knew how to do the right thing: If you defined a setter for some property, then VB would call it when the application set the property. Set it how? With the equals operator, of course. (The equals operator was how software developers assigned values to variables prior to the release of the JavaBeans specification.) And if you defined a getter, then VB would call the getter when the app used the property in some non-lvalue context. If you didn't provide a getter or setter, then no problem, VB just treated the property as a regular old field. In an anemic domain model , whole classes ma...

Hibernate events

I'm always having an argument with myself about how much intelligence to put in the database. I have a strong preference: none. I would rather work in Java and just let the database store data. But I always make an exception for database-generated identifiers, and then I start thinking that maybe I should write a trigger to let the database take care of timestamps, or recalculate a photo's total rating in photoSIG when someone ads a new critique, or... And then I start thinking that maybe I should do the opposite, remove the database-generated IDs, use UUIDs for everything, and really use the database just for storing data. For lots of domain objects I maintain two fields, "created" and "updated." You can probably figure out what they do. Throughout the photoSIG code I am forever updating the updated field. I decided to investigate whether I can use Hibernate to do this for me. I only really care about when the object was written to the database, n...

Or maybe it was Philip Greenspun

Philip Greenspun is another prolific developer and author. He created the immensely popular photo.net web site and developed database-backed web sites back when that was cutting-edge, even writing a book about it, called Database-Backed Web Sites . I don't know if Philip came up with the subtitle himself, which is "The Thinking Person's Guide to Web Publishing," but it sounds like something that he would say. It's interesting that back then, someone was willing to publish a book just about interfacing web sites with databases. These days, of course you're going to integrate your web site with a database. The days of static web sites are pretty much over. Using code that he developed in the early days of the Internet, Philip founded ArsDigita Corporation and produced the open-source ArsDigita Community System, beating pretty much everyone in the race to develop a reusable, extensible web framework. Interestingly, ArsDigita also suffered through a somet...

Matt Raible made me do it

I'm a software developer. I've been developing web applications of varying degrees of complexity for about six years or so, mostly in Java. I investigate a lot of new technology in the Java space, and I've been noticing for a while now that whenever I google for information about some bit of technology, I always find something on Matt Raible's blog . I've never met the guy and, as far as I know, don't use any of his code, but I feel like I know him pretty well at this point. Which got me thinking: maybe there's something to this blog thing. So here is mine. I've been writing software for pretty much as long as I can remember. I can remember a time when I wasn't very good at it, which always seems to have ended about five years ago. But I can only barely remember a time at which I wasn't involved with computers in some fashion. My folks bought a computer, an Atari 800, when I was about 11, but even before that, I had taken some programming ...