Archive for the ‘Coding’ Category

Starting a Major Update to a Shaky Application

Tuesday, September 1st, 2009

Today I started adding several new fields to an application that is targeted for a re-write, but we still need to get many more miles out of it before that point in time. The problem is, it's very brittle in the sense that I'm still not sure what touches what within the code. Sure, I'm getting closer to having a good understanding, but this level of change makes me more than a little nervous.

Still... if I take it slow, and make sure I make all the changes in the interfaces, and the factories, and the classes and the output, I should be able to get this done in one pass. That's my goal anyway.

Tracking Snow Leopard and Clever Configuration Tricks

Monday, August 31st, 2009

Today I've been doing a little Snow Leopard tracking - following all those folks that got Snow Leopard on the opening weekend and reporting their successes and failures. I'm really surprised that I have as much 'unusual' software as I have - Growl and Dropbox are the holdouts to be sure, but a ton of apps have released 'Snow Leopard' releases. Great for me, I'll try to upgrade this coming weekend.

I was also facing a tough update cycle with an application I'm working with. I needed to change the source app so that it published more data that could then be read by the 'receiver' app and presented to the clients. I didn't want to have to go through two QA and release cycles, but there didn't seem to be any alternatives.

Then, while talking to my manager about the issue something popped into my head - clever configuration! Currently, my 'collector' app looks at the data received from the 'source' - a URL-referenced web server, serving up XML files. It parses this data and then works on it. But what I really wanted to do was to have the additional information in the parsing. However, it's also valid to think of adding that in the configuration of the 'receiver'.

What I decided to do was to add optional, additional, configuration to say "for this URL, here's the 'overrides' for the values you'll be reading". With this, I was able to very easily set up the additional information I needed without the need for the release of the other 'source' application.

I'll still add in the additional information to the 'source' application, but there's no need to wait for it and this opens the door for other overrides in the future. Pretty neat.

Questioning the Use of Google Protocol Buffers

Friday, August 28th, 2009

GottaWonder.jpg

Being new at a job means trying to fit in. At least it does for me. After you've been around and seen how things are done, and why they were done that way, you can start to critique what's going on. Short of that, you're a clear outsider looking in, and your statements are written off as "...well... if you really understood how we do things here..." and dismissed. So I've been trying to understand the usage of 29West as the messaging system and Google Protocol Buffers on top of that.

I can see the many advantages of Google Protocol Buffers:

  • Language independence
  • Transmission protocol independence
  • Automatic class code generation

But if you look at these classes, they are really very thinly wrapped objects with simple setters and getters and no real place to put higher-level methods on top of the data package.

I can also see that any good messaging system has the exact same capabilities. 29West is no exception, and in it's API you can package up elemental datatypes, shoot them out, and pull them out at the receiving end in an entirely different language.

Sure, 29West is a single transmission protocol, but that's the point of settling on a standard messaging platform for the organization: you want to have one, and only one, messaging system you have to deal with. Given that you make this selection, it seems like overkill to use Google Protocol Buffers to package up the data into a generic byte stream 'payload' in a 29West message.

I suppose if 29West had adopted this, or Google Protocol Buffers had a 29West 'wrapper', it might make sense, but neither does exist. It's just payload packaging on top of a system that already handles the problem of payload packaging quite well.

And as I'm thinking this I read in their C++ tutorial:

Protocol Buffers and O-O Design Protocol buffer classes are basically dumb data holders (like structs in C++); they don't make good first class citizens in an object model. If you want to add richer behaviour to a generated class, the best way to do this is to wrap the generated protocol buffer class in an application-specific class. Wrapping protocol buffers is also a good idea if you don't have control over the design of the .proto file (if, say, you're reusing one from another project). In that case, you can use the wrapper class to craft an interface better suited to the unique environment of your application: hiding some data and methods, exposing convenience functions, etc. You should never add behaviour to the generated classes by inheriting from them. This will break internal mechanisms and is not good object-oriented practice anyway.

They echoed the exact thoughts I was thinking at the time. This is a "data encapsulation" system for transmission on multiple protocols. It's not advisable to subclass these guys because the generated code could get changed at any time and break your code -- so it's really just a data 'packager'. Which is nice, if you need it. But why do you need it if you have a messaging system that does this already?

Answer: You don't.

In the applications I'm looking at, it's clear overkill. There's no added functionality, and just added overhead. If there were the chance that we'd need to use a different transport in the future, then that would be something. If we were abstracting away the 29West messaging so that it could be changed out easily, that would be something. But we're not.

I can see this as something that someone wanted to do - no real need - just a want. That's a pretty thin reason to make organizational standards.

Who knows... maybe there's a reason for it that completely evades me at the time. But I don't think so. I think Google said it best:

...they don't make good first class citizens in an object model.

and if that's the case, and you've already standardized on a messaging system that does this same packaging, why would you choose to use them?

Writing Design Docs

Wednesday, August 26th, 2009

I know it's a good thing to do, but there are times, like today, that I just find it so hard to sit down and write design docs for something I've already written before. OK, sure... I haven't written it here before, and that's the same as not really ever having written it, but when you're writing the design docs from memory, it really doesn't have the same effect as those design docs that you really need to think about.

Still... it's something that has to be done. I just have to push through it and get it done.

Centering a div is Not Terribly Obvious

Wednesday, August 26th, 2009

WebDevel.jpg

I was once again trying to center a div on a page and I ran into the same problem I'd had before - centering that div. So when I looked this guy up this time, I decided to make a note of the solution so I could always find the solution no matter what.

This is that note.

The solution should be:

  div {
    align: center;
  }

but for some reason, the internet powers that be decided that this was not nearly as obvious and clear as the real solution:

  div {
    margin-left: auto;
    margin-right: auto;
  }

Don't get me wrong, the margin-left and margin-right attributes are nice, and they have a lot of use in a lot of cases, but to use them to center a div over the more obvious align attribute is a little... well... let's just call it non-obvious.

So there we have it. I'll probably never forget this again. Figures.

Interesting Problem with log4j, Tomcat and NullPointerExceptions

Monday, August 24th, 2009

log4j.jpg

I ran into a very interesting problem today with NullPointerExceptions and log4j. Specifically, it seemed that I was getting NullPointerExceptions on calls to log4j. I couldn't believe it at first, and I did several things to "clear up" the error, but the NullPointerException persisted on the statement:

  log.info("Time to clear the daily data.");

and in theory, that shouldn't happen when we defined at the top of the class the value for log:

  protected static Log  log = LogFactory.getLog("my.package.ClassName");

It should just always be there. Very odd.

So I hit Google and got a really good hint from one of the answers there

...when using Tomcat, it will unload the ClassLoader that held the webapp, and if you 'un-deploy' the webapp, and maintain the thread, it'll keep going. However, it's lost it's static variables in the unloading and now you're going to get a NullPointerException.

Since there is no way to close out the class that's loaded and instantiated for an H2 trigger, I had been just shutting down the chat interface of the alerts. But what I needed to do was to kill the alert thread(s), and then stop them for good, and clear all references so that they could be cleaned up.

So I did just that. I'm thinking that this is going to make a big difference in the overnight roll-over, as we'll have shut everything down and if the class loader had been dropped, there's no chance of it making a call and getting a NullPointerException.

It Always Feels Good to Make Progress.

Friday, August 21st, 2009

cubeLifeView.gif

Intellectually, I know that there are people that really do enjoy doing nothing. The Dilbert Wally's of the world. They enjoy the amount of work they don't have to do. I'm not one of them. Today was a very un-Wally day for me, and I loved a lot of it. While not everything was going my way, the vast majority was, and it was really fun.

I was able to get several things done for my webapp. They weren't terribly hard, and it didn't take more than an hour each, but the cumulative effect is to make the app seem like I was really making progress. Lots of little things that had been nagging at the users were cleared off my TO DO list.

It's great to have that feeling of accomplishment.

A Bit of Personal Growth – Keeping My Mouth Shut

Thursday, August 20th, 2009

Today I was in a meeting about a service/project and realized that the best thing I could do was to keep my big mouth shut. This is a big step in personal growth for me, folks. There are a lot of ways to write systems - lots. You can do the huge design docs and then go off in a room and code, you can sit with the users and have them involved from the jump, lots of ways. But today I ran into yet another person that wanted to do what they thought was best - regardless of what the users were asking for.

This isn't new. Letting technology drive the project is common, and often a horrible mistake. Today I saw a user of this project ask (twice) for a C++ wrapper for the low-level RPC calls that the group felt was their interface. I would have written the wrapper before it was asked for, but that's OK, being asked isn't so bad.

But this manager said they were going to write it. Several people very gently objected, and it was still maintained that this was what was going to be delivered.

The funny thing is, they have to write some kind of wrapper in order to test their code, so why not take a few more days, make it nice, and let everyone have it? Don't know the answer to that one, but I was glad that I saw what I saw as it led me to believe that my opinion wasn't being requested (on this topic), and I should therefore just let them do what they want.

In the end, I can write a wrapper for the service, and probably will. If someone wants to use it, great, if not, then that's OK too. I'm not trying to make my stuff used in every project in the Shop. I'm just interested in doing a good job.

After the meeting I talked with my Manager - a nice guy that's trying to understand my point of view. After about 30 mins of talking to him I think I made it clear as to why I was feeling the way I was, and why it was futile for me to try and express those opinions and feelings to the group responsible for the project - it'd be completely unwanted and make me look like a judgmental individual.

While the latter may be true, it's not exactly the point. They asked for feedback on the project, someone asked for something that was very reasonable for them to provide, and it was rejected. Period. End of story. Done.

I really don't like working with people like this, but there are people like this in all walks of life. You just have to do your best to identify them and hope you don't have to deal with this too awfully much.

Working on a Barrier Breach Alert System

Tuesday, August 18th, 2009

Today I've been working on a lot of ideas for a barrier breach alert - something where a data stream is coming into the system and you have set up a series of barriers defined by an expression - typically something like this:

  value > (2.0*n + 1)*10000.0

where:

  n = 0..5

so that the first barriers are actually at:

n Expression
0 value > 100000.0
1 value > 300000.0
2 value > 500000.0
3 value > 700000.0
4 value > 900000.0
5 value > 1100000.0

so now we have the barriers we'll be crossing through.

The trick is that when I cross any two barriers, I need to alert on the last one we crossed. So if we're going from 50,000 to 550,000 I want to alert on the 500,000 barrier not all the ones getting up to that value. Likewise, if I fall from 550,000 to 50,000 I need to alert on the 100,000 barrier not anything before that.

So we have to have an idea of direction of each barrier we're crossing, and we have to maintain a history of some sort to know what we crossed last, so as to know if we need to report on the crossing we're making right now.

This has been something I've been working on most of the day. Sadly, I do not, as yet, have a solution to the problem, but I'm sure I'll get something tomorrow.

[8/19] UPDATE: Yeah, I have something that seems to work rather nicely. I have two arrays of booleans - one for the previous state of all the barrier equations and another for the current state of the same equations. Then, I can compare the differences. If there's a difference, that's the "edge detection" we need. By looking at the values, we can tell if the current values are rising or falling.

Slick ideas that seem to be working nicely. Love this stuff.

Added numberFormat() to BKit for Completeness

Tuesday, August 18th, 2009

BKit.jpg

I was pretty impressed with Java when it added in the String.format() method. It's very much right out of C and can make some formatting tasks very simple. I added this into the BKJEP expression parser as format() with the pretty impressive Java VarArgs. Pretty nice stuff. But over the course of the last few days I've been wishing for a little more control of the numeric formatting on the format() command. It wasn't allowing the optional decimal place like the DecimalFormat class.

So I decided to put in another method to the BKJEP parser: numberFormat(). This guy takes two arguments: a Number, and a String format consistent with the DecimalFormat class. This helped me clear up a nasty little formatting problem on one of the logging messages I was working on in a project. Very nice to have the flexibility of both, that's for sure.

While I admit the argument list is backwards from the format() function, it's in keeping with the dateFormat() function already in the BKJEP parser. I decided to keep these two similar, and let format() stand alone. It's not perfect, but I didn't want to switch everything and then worry about the things that might break.