Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Saturday, July 18, 2009

no fluff just stuff SLC 2009

It was pretty good. Only went to one session that was a dud. Decided to try to go to a number of different speakers in an attempt to not get burnt out. But, I should have just stuck with all of Venkat Subramanian's sessions the first day's afternoon. He's an awesome speaker.

I enjoyed seeing other dynamic languages -- groovy, scala, clojure. Definitely seems like mixing in Groovy to any java project would be pretty easy. Loved that it removed a lot of Java's verbosity, but kept the barrier of entry low. Groovy also seemed to be much more readable than clojure or scala.

Scala seemed very interesting -- liked the type inference, and concurrency support. But, I hate hate hate the underscore. And that g-damn colon that changed the operator/operand. Maybe if I used it every day, it'd seem more readable.

I guess if people can hate Python's significant whitespace (which I love), I can have an irrational hatred of Scala's underscores/colons.

Wednesday, October 08, 2008

hudson == teh awesome

Hudson is great. Lightyears beyond CruiseControl. Everything configurable through the (awesome) UI, a ecosystem of plugins, and incredibly simple installation.

We don't have that complex a build, but our SCM team looks at me like I'm a crazy person when I point out yet another issue with the build. After the umpteenth time I've found yet another build problem, I decided to give Hudson a try. We need to checkout some modules from the trunk, and others from a branch. It was bad enough when their chosen solution to that problem meant we couldn't automatically trigger the builds with a check-in -- builds had to be forced from the UI, then a pre-build step did a CVS checkout of the modules from the appropriate branches. The last straw was realizing that the pre-build script also contained some logic that overwrote any changes we made to our build.xml file with some out-of-synch version of build.xml that one of them had created at some point in the past. The sort of thing you'd like a heads up about.

With Hudson, builds have been a snap to set up -- monitor these CVS modules, run this script from the repository if any changes are checked-in, the build artifacts will match this regex pattern allow download of them from the UI, keep only X number of builds on the CI server.

Hudson doesn't let you checkout from a mixture of HEAD/branch either -- but it's simple enough to set up multiple build commands, the first of which is doing the branch checkout. We won't get a complete changelog or CI automation, but it's good enough.

Saturday, September 27, 2008

loving/hating Fit

We waste a huge amount of time on our legacy code base because we have no Unit tests, and no standard way the project's developers test their changes.

It's typically some error-prone manual process -- run some SQL in Toad, copy results to Excel, run the bill, re-run SQL, compare to the old results with eyeballs, pray.

I read about Fit a few months ago, and it seemed like it'd solve a lot of our problems. Blackbox testing would help build tests up around our legacy codebase. It'd also help bridge the communication gaps between onshore/offshore development, and development/business.

Finally took the time to play with it this week -- specifically, DbFit. Without any customization, I was able to write some simple SQL in a wiki page to generate a new test case for the issue I was working on this week.

I'm in love. It seems like with some minor customization we can make some huge leaps in our productivity. But I really hate trying to navigate the Fit/Fitnesse web sites for reference information. Ugh.

additional offshoring adventures

My project at work is a set of Java applications for which communicate over UDP / RMI. The port numbers they talk over is configurable. In our hosted environment our servers may be running the apps for multiple clients. So, the users (or our tech support people) have to configure unique port #'s in each set of config files if there are multiple s running against different databases. It's a annoying, but the least of our worries at the moment.

Monday this week, I realize our configuration editor doesn't give the user the ability to edit a certain set of port #s. I ask the offshore team to add that ability to the config UI.

When I come in the next day the offshore lead has decided the existing way we do things is too error prone. He's made a great change so that the configurable settings are just a range of port #'s and the application(s) will pick unused ports within the range.

After reviewing the changes, the only issue I found was in some output files created by the apps once they pick a port number. Once the port # is selected, an output file will be written. It was implemented with a DataOutputStream to write an int primitive to the file, and read back in with DataInputStream. I'd prefer it to be human readable, so I respond with some notes saying to make the file a text file rather than a data file.

I come in the following day, and find that the only thing he's changed is to give the file a ".txt" file extension.

Wah?

It's the 'little' things like this that drive me crazy. Things I assume don't need much specification. It's particularly annoying because this engineer is so awesome -- he's always quick to turn around any solution, and always asks great questions on our calls. And, he did a great job of taking the initiative to fix a major flaw just a day earlier.

Tuesday, September 16, 2008

further adventures in offshoring

Have not had time to do a code review for the project I've inherited. Decided to use FindBugs to pick off low hanging fruit.

aiiiiiiiieeeee.
  • bitwise '&' operator used instead of boolean '&&' operator
  • '==' operator used for Long/Integer/many-other-reference-types
  • String.equals() comparing a String to a DO object
  • Enum classes with their own extra-special equals() methods. Ick.
  • Classes with equals() but no hashCode()
  • Who implements finalize()?
  • many, many more

Saturday, August 16, 2008

an afternoon I'll never get back, thanks Eclipse!

Spent Friday afternoon fighting with Eclipse. Around lunchtime, my development environment stopped working... When launched from Eclipse the app couldn't find the log4j, Spring, or Hibernate config files. After many false starts and much gnashing of teeth, finally noticed it wasn't all config files that weren't getting copied into the projects' output folders but only .xml files.

Finally managed the right phrase in Google that found me the answer: http://dev.eclipse.org/newslists/news.eclipse.platform/msg74562.html

Apparently, Eclipse plugins may update one of the preferences that tells the builders which file extensions it shouldn't copy to the build output path. To fix it, you have to go to 'Preferences... -> Java -> Compiler -> Building' and then check all the extensions entered into the Filtered Resources text field.

I'm not sure if it was a plugin change, or (probably more likely) changes I was making to my launch configurations to not run out of the 'dist' directory into which the inter-project Ant build packages everything.

I'm not sure if I should be happy that the offshore team I've now inherited at least got the Ant build right. Or, if I should be concerned about whether they've actually been running the code / configuration they think they are when running under Eclipse.

One more in a long line of complaints I've had regarding how this set of applications is configured. Normally, I'm the one on whatever-team-I'm-on pushing for extensive runtime configurability. I don't know why this project's configuration setup -- not the Spring/Hibernate, the home-grown .properties file reading and command-line handling stuff -- rubs me the wrong way. The nonsensical or nonexistent documentation, the obfuscated search paths, the unhelpful error messages, or the fragility of the whole system when you're missing one piece... all of the above?


Even with that lost afternoon, I still love Eclipse. After all, it's free. Oooh, free. One plugin that now I can't live without: Remote System Explorer.

I've got to run Windows at work, and the corporation-approved SSH client sucks balls. When you resize a terminal window... what would you expect to happen? More columns/rows? Bah! That's too obvious and old-school for Attachmate Reflection's SSH client-- instead the mother f*&#$*#&er resizes the font. Badly.

PuTTY is mediocre. The corporation's security agent can't be disabled, and it prevents the cygwin install from running completely.

Enter Remote System Explorer. Multiple terminal windows. Does the 'right' thing when resizing or scrolling. Gives me a file-tree view of the remote system via SFTP. I can edit remote files within Eclipse and it automagically saves them to the remote system.

Eclipse is a beast, and a bit of overkill for a shell window. But, I've already got it open. And, unlike my Ubuntu system running under VMWare... I don't feel like the corporation's jackbooted thugs will re-educate me if/when they find I'm using it.

Saturday, April 19, 2008

more ponytails than should be allowed by law

Decided to go to the April UJUG meeting a couple nights ago. The presenters varied a little in quality, but were average to great. The topic was interesting, I would have enjoyed more "What went horribly wrong" war stories.

I thought it was telling that even though Maven was held up as a savior for many of the projects, everyone who spoke up mentioned their love/hate relationship with it. It sounded like the LDS church's team had embraced it the most, and a big part of their success with it appears to be because they've dedicated 2-3 engineers to supporting it full time within their organization.

Turnout was huge, 100+. I think I prefer the smaller, and less formal, UPyUG meetings. And it's not just because I think software developers with long hair look silly. So many ponytails at the UJUG meeting. And at least one beret.

Thursday, March 27, 2008

Spring, best thing since sliced bread?

I've been reading a lot about the Spring Framework lately. It's been aggravating me... realizing how much easier it could have made the last 2 years of my life, if I'd dug into it before starting on my last big project.

I'm enjoying Spring in Action. Only a few chapters into it. So far a good introductory book. I like the light tone of the examples, but the jokes are becoming grating.

I also picked up Expert One-on-One J2EE Development without EJB. I'm pretty sure it wins for the creepiest cover on a technical book ever. Kids, if he pulls up to your playground in a ice cream truck, RUN AWAY!

Thursday, September 27, 2007

nuggets from the dumb monkey sack

We've got a new developer in the group. As he's installing all the supporting tools he'll need for the projects he'll be working on, he came to me when Ant stopped working. Odd messages about Ant core/tools version incompatibilities.

We fiddle and fiddle with JAVA_HOME, with ANT_HOME, with PATH... No luck. Same messages, despite the Ant we want being right there at the start of PATH and in ANT_HOME.

Like a revelation from heaven, I realize... wait... what's in CLASSPATH? Well, there's a Documentum Jar in there... but that wouldn't have stuff to do with Ant, right?

The documentum Jar in question turned out to not have any classes in it, but it did have a giant list of other Jars in the manifest's classpath. Including Ant. More specifically, a local install of Ant 1.2 beneath the Documentum installation.

As much as I'd like to blame Sun for not providing a non-insane standard for application startup, I think its more appropriate to vent at EMC/Documentum for creating an installer that modifies the system's classpath environment variable to add their kitchen-sink Jar. For as much money as they charge, you'd think they could write an installer that doesn't screw up your system.

I'm not sure why I was surprised. Nearly every other interaction I've had with Documentum has been an exercise in agony. They must have a burlap sack full of exceptionally dumb monkeys deciding how their software gets installed and configured. Other nuggets from the monkey sack:
  • No desktop application needs to talk to more than content server, right? Well, if they do, they can manually edit this INI file in c:\windows.
  • No desktop application needs to talk to more than one version of a content server right? Well... if they do, they can uninstall/re-install to do so.
I can excuse their crappy, obfuscated APIs. Still hate them, but I can understand inflicting them on software developers. But to screw things up for all the end-users, QA, and support that need to use their crappy desktop apps, seems mind-numbingly stupid.

Sunday, June 24, 2007

Salt Lake Software Symposium, day #2

Last day. Still pretty good, but didn't rock as much as the first.

Attended a couple more of Jared Richardson's sessions: "Agile Testing Strategies", and "Software Development Techniques". Lots of good real-world examples, and lots of inspiration for changing our processes. Definitely thinking of picking up Ship It!

Neal Ford's "Pragmatic Extreme Programming" was good. But, I think it'll be easier to work in lessons from Jared's sessions (on days 1 and 2) into our existing process.

I wasn't going to attend Brian Sam-Bodden's "Complex Builds with Ant" session. From the slides, it appeared like I'd already knew the major tips on my own. But, I was wiped out by the last session. Decided it was worth going to a topic I was familiar with in order to pick an expert's brain. Only three attendees, so the session went fast and I was able to ask a lot of questions.

More sour-grapes today over all the Ruby rah-rah-rah. Again, Neal Ford declared Ruby the winner in the dynamic language race on the JVM. Neal is a very smart guy, a great presenter, and also great to talk to one-on-one. I don't have any issue with him advocating Ruby. Any language that makes developers more productive is a good thing. But, it seems disingenuous to declare a victor in a wide open race to a room full of people who have little to no experience with dynamic languages.

Personally, I prefer Python over Ruby. Others can and should disagree. Here's a fair, but slightly biased (since the author is familiar with Python), comparison of Python vs. Ruby.

I'm not sure who to blame for lack of Python excitement in the Java world (or at least at this conference). Maybe with the recent revitalization of the Jython project, it will get more Java developer's attention.

Microsoft's CLR (and the new DLR and Silverlight) seems very exciting. See here and here and here. The second link is a screencast showing interoperation between Ruby, JavaScript, Python, and VB.

All in all, the conference was very good. I'll definitely plan on going next year.

Friday, June 22, 2007

Salt Lake Software Symposium, day #1

Since this blog is all about (pick one):
  • lame book reviews
  • lame software conference anecdotes
  • odd things I've put in my mouth
Here's more software conference anecdotes.

Spent today at the Salt Lake Software Symposium (aka No Fluff Just Stuff). So far, the conference is very good. Attended presentations by Neal Ford, Jared Richardson, and Brian Sletten. All great presenters, showing off great technology.

A friend has tried 2-3 times to explain Aspect Oriented Programming to me. It sounded... like more trouble than it was worth. Brian Sletten's AOP presentation was very useful in cluing me in. Seeing the AspectJ/Eclipse tools in action got me all excited to try it out. The immediate use-case I have would to remove a bunch of cut-n-paste concurrent locking boilerplate in my pipeline application. If I understood it correctly (always a questionable assumption), I can replace all that code scattered throughout my class with an aspect that'll do the

writeLock();
try {
// .... do stuff....
} finally {
releaseWriteLock();
}

logic all from a single place for all the setters methods in my class. And a similar readLock() aspect for my getters.

Brian also presented NetKernel. Also awesome. Still trying to get a handle on how exactly we can leverage it for our needs. His Mashup/SemanticWeb/RDF presentation was also good.

Jared Richardson's presentation Shippers Unite was very good. The best part, calling sales people 'Sales Critters'. He had lots of great advice, and great best-practice type information.

Neal Ford's SOA presentation, and his keynote after dinner were also very good. His keynote, "Polyglot Programming" was very interesting. Contrasted the increasing cruft, and complexity (and irrelevancy) of the Java language against the awesomeness of the Java platform. Described the increasing place Dynamic Languages will have within the software industry. In particular their place inside managed runtime environments (either JVM or CLR).

The only major disappointment I experienced was the (apparent) disdain the conference presenters seemed to show for Python/Jython. Lots of Groovy/Ruby/JRuby/Grails rah-rah-rah. I know Rails is the new poster child, and Ruby folks should be proud. But, to give Python/Jython/IronPython hardly a mention. And, the one time the word Python appeared on a slide, to explicitly declare Ruby the winner over Python... seems premature.

Yeah, yeah. Sour grapes. Maybe I should try Ruby before deciding I don't like it... but the Perl-like $ and @ syntax rubs me the wrong way. And, maybe I should just be happy about the rising tide of dynamically typed languages that'll lift all boats.

Friday, April 06, 2007

lesson of the day: just assume Co-Worker #1 is correct

I've been reading Java 2 Performance and Idiom Guide, it's quite good. But, I think I'm too interested in experimenting with the tweaks it suggests.

As I mentioned in my last post I'm working on a data-processing pipeline, and have spent the last couple days investigating why the performance (records/second) of a particular pipeline stage drops off like it does.

The software we're working on analyzes bibliographic records and creates a representative sample. Our users create mappings between one XML schema and another. They have to go through much fewer iterations if they've got a good sample to work with. And iterations are much shorter if they can test their mapping against a sample that's <500 records, rather than 16+ million records.

The oddly performing pipeline stage normalizes XML entities by replacing them with a numeric reference to their Unicode equivalent. Yeah, the DTD should do that... but it doesn't help when the data provider escapes the entities. Or when their DTD replaces the entity... with the entity... argh.

The graph below shows the records/second performance of three stages of a pipeline (y-axis). The x-axis is time. The yellow nodes are each file's entity-replacement performance. The blue nodes are the files getting split into 5000-record chunks and inserted into a Marklogic database. The pink nodes are each 5000-record chunk being analyzed. The first 500 or so files all have 30,000 records; the rest of the files are daily updates that vary in size -- that's why the tail end of each gets a little kooky.The initial steep drop-off for the first few files was understandable. It's one of the first stages of the pipeline, and the threads doing entity-replacement don't have to compete for I/O with other pipeline stages until the following stages have entity-replaced-output to work on. But the continued decline made me worry that there was a problem in the code.

Reviewed the code. Each file is getting processed by its own thread. Each thread should create SAX handling objects that aren't shared between threads. No static fields or other stuff to interact between threads...

But! I notice that the SAX handler uses a StringBuffer to accumulate a records-worth of text as it replaces entities. When endElement is reached it calls sbuf.setLength(0), which my fancy new book learnin' suggested could cause memory/performance problems.

And I set off on my non-adventure....
There are four series on the graph above.
  1. Dark blue is the original run.
  2. Pink is the result of replacing sbuf.setLength(0) with sbuf = new StringBuffer(). No fabulous improvement. Stupid book learnin'.
  3. I decide that 'new StringBuffer()' meant that memory is getting re-allocated from initial the default StringBuffer size, which isn't as efficient as it could be. Yellow is the result replacing sbuf = new StringBuffer(INIT_LENGTH). INIT_LENGTH is a couple thousand bytes. Still no major improvement.
  4. Re-review the code. Realize that the FileInputStream/FileOutputStream objects aren't wrapped with BufferedInputStream/BufferedOutputStream. The light blue nodes are the result of changing that... Still no major improvement. I assume this was because these input files are in Zip files, and output to GZIP files -- so were already buffered (I did increase their buffer sizes along with adding the buffering to the uncompressed-file handling).
Then I remember the comment from Co-Worker #1 when I showed the graph to her before I began my journey to nowhere: "Maybe its just file-size"

I fiddle with my statistics exporting code to include the file-size in the exported spreadsheet.
*@&#$*&!

And the KB/second graph looks like:Moral of the story: Get the most complete picture of a performance problem you can, and don't be swayed by the kooky little performance trivia you read.