I'm in the market (so to speak) for a new bug tracking tool.. there are only a few requirements and it doesn't have to be open source or free, just good!
- Web based
- Tiered security
- Not hell to administer (don't want a full time employee just for this!)
- E-mail notification
- Decent reporting
- Integration with source control would be nice, but since we haven't picked a tool for that yet, it's not necessary.
I'm currently looking at:
BugZero
Scarab
ProblemTracker
1. If your new employer buys books, take advantage! Read them!
2. Work extra hours to finish a project that's off-schedule, it will come in handy when it's time for a performance review.
3. Always document your code, you never know when someone else might need to read it.
4. Keep daily notes on your progress, it comes in handy when you need to take a few days away from a project.
5. Take advantage of any training your employer provides, it makes you a more valuable employee.
6. Start your work day early, you can get more done in the morning before the office fills up with coworkers.
7. Don't abuse company resources, that next raise may depend on it!
.. and finally ..
8. Keep your personal items at work to a minimum, it's easier to carry out when it all fits in one box.
9. Label your office supplies, that way you can claim them as your own when it's time to pack your box.
10. Accrue your vacation days so when you get laid off you have extra paid time.
It appears every relational database has its own way of dealing with automated identifiers. Most databases, for instance Oracle, allow you to create sequences which can be used in conjunction with triggers to create a sequential ID when inserting rows of data.
MySQL has its own way of dealing with this problem which stems from its lack of triggers in all but MaxDB versions. In MySQL there is a special column attribute "auto_increment" which will increment the value of the identifier upon insert. Behind the scenes, it is really quite simple, MySQL performs a special lock on the table, selects a max value on the column and adds 1. The downfall (or for some, it may be a benefit) of this implementation is that ID numbers can be reused if data is deleted after the database server has been restarted (since MySQL stores the information in memory). With the Oracle approach, the ID numbers will not be re-used unless the sequence is renumbered - not something that would be done often.. well, in most cases.
PostqreSQL somewhat combines the two approaches. It provides the ability to create sequence but there is no need to triggers (as you would use in Oracle), instead you can use nextval('sequence_name') as part of the table declaration, much like auto_increment attribute in MySQL.
For insertion purposes all these approaches work in a similar manner: you insert a row with a zero or a null ID and the database does the work for you. The difference is in how you can retrieve the ID once a row of data is created.
There are a couple of ways this can be handled:
1. Handle it in the code using abstraction and writing separate implementation for getting the identifier based on the database type.
2. Create your own implementation of incremented Identifiers: for instance a table which stores a separate value for the last id for the table/column.
The drawback of the first approach is obvious: writing more code to implement each separate supported database. On the other hand, it utilizes built-in database functionality and simplifies insertion.
The second approach has its drawbacks as well, which brings me to the whole point of this entry. I have seen this solution used in many open source projects to simplify database compatibility code and find that to be clunky for a few reasons:
- A select statement must be made before each insertion.
- The table needs to be write locked for the duration of the transaction to prevent another process from grabbing the same ID and creating duplication
- Manually inserting data into the database becomes a hassle (you're faced with two sql statements for a row of data instead of one)
- You're not utilizing the features of the database which are optimized for this purpose.
- The whole process is likely slower
I find the extra effort spent on writing abstracted database persistence code to be well worth the hassle you avoid while later debugging and supporting the application.
Being an active contributor to technical forums I am often faced with surprisingly simple questions about basic programming environments from computer science students. Students are often lazy and why should it surprise me that so many don't bother to learn the basics, right? Maybe, but too often it is ones who are otherwise bright and not at all lazy. So what is the true problem?
Thinking back to my own basic programming classes I think I can see the problem clearly. I cannot think of one professor that explained the programming environment in class. The books tend to skip over those parts as well.
What is the number one problem students have with their Java projects?
Classpath.
Something as simple and basic as that, it's just not explained in class. Is it too simple and ought to be self-explanatory? Perhaps, but I wouldn't expect a first year CS major to grasp the concept of classpaths without at least a basic introduction, why are CS professors expecting it? Sit a student in front of a tool like eclipse and I guarantee their eyes will glaze over and a simple concept like a compiler will not occur to them on their own.. command line? Forget it.
With the development environments getting more and more complex each year and the command line being something of the past (unless you're a unix geek like me) I think CS programs should look into providing classes in basics of development environments. Using tools like source control, IDEs, etc. It would help the students understand programming better and give them a better start in the workplace.
I got into an argument today with someone over using a debugger. According to this person "debuggers are for lazy and sloppy programmers". My first reaction was "what?".. then "bullshit!"... then.. some time later and after a somewhat heated exchange (I have a temper, what can i say?) I finally understood the problem.
He thinks people use a debugger to understand the structure of the code.
Okay, perhaps some programmers do, okay, perhaps many programmers do. I don't. I can read code, thank you very much, and I do not need to single step through it to understand the flow. I use a debugger to quickly find problems. In a debugger I can examine the run-time values of variables, indeed, change those values and do other useful things that greatly speed-up fixing of code.
"You should program defensively and make sure your code can output information during run time that will help find out problems"
Of course you should, and I do, unfortunately I work in the real world where majority of the code i work with was written by other people and even though my performance review called me "refactoring queen" that is not my primary job function.
"Use print statements!"
Life is too short, see above.
"Reading the code to find the bug makes you learn the code by heart"
Oh, of course it does, and you can also stare at it for hours and not see the problem until you examine it at run time for a big "doh!" That is unless you're perfect, sadly, I'm not and I do make dumbass mistakes on regular basis.
"Linus Torvalds doesn't want you to use a debugger on the linux kernel code"
Great, good for him. Linux kernel was not written by my co-worker who is in love with abstraction. I guess I won't be working on it anytime soon, bummer.
It's no more lazy and sloppy to use a debugger than it is lazy and sloppy to use a high level language instead of assembly. It makes my job easier, makes me fix bugs faster and makes me a better programmer.
With the retirement of the sun server I used to work on at work (RIP cortez) I have moved operations to all-linux-all-the-time, which also means using Subversion (no more ClearCase!), emacs on linux - not sun, JBoss not weblogic and newer JDE (2.3.3).
It was when I tried to debug something today that I discovered I was used to a rather ancient version of JDE on my sun box. Attaching a debugger with that version required writing a JDE extension and setting up some cryptic things in .emacs. None of that works anymore, particularly since jde-db-init doesn't even exists as of 2003 or so.. obviously I was used to a very ancient version of JDE.
Thankfully, setting up the newer one to attach to an external process proved to be very, very easy.
in .emacs:
- Location of source:
jde-sourcepath ( "/home/ktrapszo/src" )
- Debugger socket:
jde-db-option-connect-socket (nil, "28380")
Default socket is 4444
That's all it takes to setup JDE to attach to a remote process with jdb. Easy!
Of course, the second part of that is running JBoss in debug mode.
-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:server=y,transport=dt_socket,address=28380,suspend=n
Easy, more reading: JDEE page
As noted here I am working on a conversion of a ClearCase repository to Subversion. Since there appear to be no resources for this available I wrote a simple perl script that handles the conversion in a relatively simplistic manner. In short, it checks out each version of a ClearCase file and checks it into Subversion, therefore creating the history. It's simple but effective and it worked quite well to convert our entire repository (some 30+ hours for the whole thing..).
Anyone who wants it, it's here, but please make sure to read the documentation, particularly the limitations before you attempt to use this thing.. and by all that is holy, run a test run and backup!
I'm researching switching our source control tool from the feature-rich and appropriately expensive Rational ClearCase to the open source and apparently quite nice and stable now, Subversion.
It appears that conversion scripts from CVS to Subversion are a dime a dozen, however I've been having a hard time finding any information on converting from ClearCase to Subversion.. I suppose it wouldn't be particularly hard to make a script to convert all our history.. but I'm more interested in finding out about pitfalls and things to watch out for from people who have done this before.
Anyone have any info?
I whole-heartedly concur with all that is good an geeky.
In my own code, I tend to also add an additional line under a comment for readability.. like so..
// This is a comment
//
Hungarian notation? Hate it, despise it, don't like it. It makes for long, clunky variable names that become cryptic instead of helpful half the time.
[via jeremy]
I didn't realize I was starting a religious discussion with my post about multiple return points from the same method. I suppose I could have been clearer (one sentence is pithy even for me, but it was posted in a state of relative upset) and specified that I meant Java. Maybe an example of why this upset me so would have been nice as well, but little late now. Let's just say it involved, reflection, setting a debug level and execution ending before debug code was reached.
In my mind (but go ahead, disagree, keeps things interesting, I'd hate for everyone to agree with me), there's really no excuse for using multiple return points in a language like Java. Number one argument to my proposition appears to be "code readability".. this provides me with an impression that not enough programmers realize Java supports this wonderful thing called code blocks. That you can name! If you wish to avoid convoluted code, they're your best friend.
It's really quite simple, and even more so with my easy to follow example:
private boolean testSomething(Object this)
{
boolean rval = false;DONE:
{
this = doSomething();
if(this.isThat())
{
rval = false;
// Exits the code block completely
//
break DONE;
}
// more code..
//
// some more code that will only execute if you didn't
// call 'break' or 'continue' above'
//
rval = true;} // end of code block.
return rval;
}
This is incredibly handy in keeping code clean and easy to read. In a gist, each code block has to have one label and one entry point, may have multiple exits.
This is probably obvious to everyone, but it took me looking at javadocs to figure out how to make tomcat give me more information than just a generic "ServletException" with no context, no message and a useless (in this case) stack trace.
Thread-45[1] dump e.getRootCause().printStackTrace();
Where e is the exception, RootCause is a java.lang.Throwable
java.lang.NoClassDefFoundError
at xxx._jspService(_xxx_0.java:262)
Much better than
javax.servlet.ServletException
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:508)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
Together at last using Inline::Java
Here's how.
Not sure what I'd use it for but it's cool regardless. Perl, it's what's for dinner.
I've decided.. I just dont' like CVS.. I really don't. Sure, it's a great tool and I'm certain it works wonderful for something like say, open source projects -- unfortunately I'm finding out that in real life it's just a pain, pain, pain.
Real life? Well.. something like a development team where you really don't want the headaches of merging in code every time you make a change. Unfortunately, CVS isn't very kind to those who like exclusive checkouts (yes, I know.. C is for concurrent). Configurable but still a pain in the ass.
My main problem is that I am essentially addicted to refactoring code... I'm anal about formatting (well, really we all should be but that's another rant) and I simply cannot stand duplicated code and 1000 line-long methods. So I refactor.. a lot. You try and merge that in!
And no.. RCS is not an option for various factors, not the least of it being developers on windows machines (eek).
So now I have CVS that is built on top of RCS that I want to act as RCS and the one project I found that makes it do that has not been updated since 2001.. Subversion is also not an option, cool as it looks.
Rant over.
Philip Greenspun apparently forgot that there is such a thing as an appropriate tool for the job.
Java an SUV? Perhaps.. but then php is a Mini - admittedly a very cool car that will get you to your destination, but do not attempt to haul a heavy boat behind it.
I'm not exactly a JSP veteran so this may sound like a very stupid question.. but how do other, more experienced developers deal with common JavaScript methods?
Now with JavaScript being object oriented it makes it relatively simple to write common functions.. and so far my solution has been to simply put them in includes files that get included in the JSPs themselves.. There has to be a better solution..
I searched and searched and searched and nothing jumped out at me that would solve this in a more elegant manner.. so I pose this question to the Java folks in the blog land out there.. how do you do it?
And uh.. thanks for reading this completely useless blog post :)
To quote from an eloquent entry:
I've said it before, and I'll say it 'till I loose my voice: I fucking hate Java I/O. All I want to do is get all the contents of whatever's in a stream, a reader, buffer, or whatever the hell else I have a handle on. Can I just call something like the below:
String contents = new File("somefile.txt").getAllMyShit();
Of course the fuck not! I have to keep track of byte arrays, char arrays, or some stupid ass shit in a while block. I just want the God damned content, I don't care how the JDK gets it out of there.
I always thought there should be a method on StringBuffer, perhaps called loadFromFile(), that takes a File object.
John Mitchell writes:
As I've been walking around, sitting in sessions, and generally being a nuisance, I've been struck by the fact that there seems to be a noticeably larger percentage of female developers at the show than in previous years.Yes, this could be explained by the fact that there are fewer total people here this year so perhaps it's just more striking to my less saturated brain but.... What about in the overall technology world? Given the relatively small percentage of female developers floating around, are they getting laid off less than male developers?
No, John, there is no gender bias.. it's all very logical. See, women typically have to work a lot harder and be a lot smarter to get where men are in IT.. that means they're less likely to be laid off when times hit hard. I know only a few female programmers but all but one I know are simply very good or excellent.
I would have posted this as a comment in your weblog but you have a requirement for registration just to post a comment. That's cumbersome and silly... particularly for someone like me who is not a regular reader There are enough useless accounts of mine floating around the web as is.
This one is sneaky.. most programmers when writing debug code tend to call the toString() method on an object to retrieve human-readable information and present it to the user in some shape or form (logs, system out, etc). That's good programming.. when debugging a problem we want to be able to read and view all information possible..
Here is the sneaky part.. you should never *never* call toString() on a Java object unless you're pretty damn sure that object will never be null. Why? It's simple.. calling toString() on a null object will generate our good old friend -- the null pointer exception. (What? Java has no pointers! -- wrong!). This is a huge problem.. Think about it.. where do we usually put most of our debugging code? That's right.. error handling.. Something like this, perhaps:
try
{
myObject = doSomething();
}
catch (HorribleException e)
{
String msg = "Dude, we got us a problem: " + e.getMessage();
msg += "The object looks like this" + myObject.toString();
// do logging and stuff..
//
}
If myObject happens to be null, which may very well be the case considering we have an exception while trying to create, modify or reference it it will throw a null pointer exception at which point this becomes a debugging nightmare as the original exception is now lost. Maybe not a huge nightmare in a development environment.. but try to debug issues with code like this in a production environment where all you have to go on is logs and system output. Right.. nightmare.
What should you do instead? Forget toString()! There is a better way of doing it and that's String.valueOf(object) which is implicitly called on calls that convert objects to strings. String.valueOf(object) internally calls toString() on the object -- but it checks for nulls! This is the behaviour you want in your debugging code.. if the object is null you do not want an exception.. just a "null" ought to suffice and the toString() output otherwise..
try
{
myObject = doSomething();
}
catch (HorribleException e)
{
String msg = "Dude, we got us a problem: " + e.getMessage();
msg += "The object looks like this" + myObject;
// do logging and stuff..
//
}
Will generate exactly the same output as the first example when object is fine.. but only the string "null" when object is null. Safer and even less typing! The scary part is how many experienced programmers have no clue about this little gotcha.. go spread the word. Thanks.
Those of you that did.. did you see a guy with really long hair and a patch on one eye? That's my boss who got to go instead of me..
At least he brought me back a MySQL tshirt.. the back says "transactions" with a checkmark.. too funny :)
Pretty good article on Java performance "urban legends".
In summary...
- Urban performance legend #1: Synchronization is really slow
- Urban performance legend #2: Declaring classes or methods final makes them faster
- Urban performance legend #3: Immutable objects are bad for performance
Thanks to Demitrious for the link.
I've been involved in a couple of discussions about exception handling in Java recently.. and while the discussions were sparked by unrelated topics I came out with one conclusion from both.. People just don't seem to grasp some very basic design ideas when doing error handling..
Number one mistake I see everyone do is..
try
{
....do something here...
}
catch(Exception e)
{
.. handle error
}
Unless you're working on a one-file CS project this is probably not a good idea.. The generic Exception object should only be caught when you *know* what to do with every different type of exception that could occur.. this includes something as basic as a NullPointerException.
In other words.. just catch the exception you can handle and throw everything else up to the calling class.. more often than not it's much more useful information at a higher rather than lower level.
Another mistake.. wrapping an exception inside a new exception and throwing it up the food chain that way.. This may seem like a good idea from the standpoint of clear, easy to understand design.. but by wrapping that exception you're throwing away vital information that the front end could use to handle the error.. It's often appropriate.. but more often not.
In a jist: Only bother with errors you know exactly how to handle.. throw everything else up. Well, of course, unless you're working on front end code.. then that's a whole different story.
Phew.. Java pet peeve #4908983439 :)
(or learn from my screw-ups)
Refactoring code is somewhat of a hobby, I suppose, since I do it as much as I possibly can (or have time for).. so seeing something like this..
String result = (someString.trim() + anotherString.trim()).toLowerCase();
Boils my blood and of course I have to rewrite it..
String result = "";
if(someString != null)
result += someString.trim();
if(anotherString != null)
result += anotherString.trim().toLowerCase();
.. and of course I completly missed the part where the entire string was set to lower case.. not just the second portion.
Stupid me (this caused real problems too).. but I say at least 20% of the blame is on the hard-to-read chained code.. (20% more on me being in a hurry and rest on me for not paying attention, but who's counting..)
I was writing some test classes at work today using JUnit.. nothing out of the ordinary.. just your typical..
result = doSomething();
assert(expected == result);
I'm sure someone's already spotted my problem.. but wait :)
Code compiled.. that's nice.. then a co-worker cannot compile it in her work area. Hm. Problem. Apparently assert(boolean) is not a valid JUnit method call.. What? Checked my libraries.. sure enough mine's horribly out of date, hers is newer.
Now I'm mad. You don't just remove a call.. you deprecate it! My compiler didn't give me a deprecation warning.. (as you can imagine I was already salivating at the prospect of having a good rant at JUnit's expense). Checked their website.. read documentation (yah, I do that sometimes, but only when absolutely necessary) and found out that since assert has been assimilated by Sun as a Java keyword, the method call was deprecated and since removed.. A long-ass time ago.
My jar file was *really* out of date. (This is where I slap my forehead and you laugh at my expense).
.. and I have found it!
You know that part of the project when you're busy doing bug fixes? Tedious.. little, annoying bug fixes? Fixes that only take about half hour to an hour each but because of the qa/testing process really take 2 hours each as you tear your hair out between server restarts and QA deployments? That part..
Now imagine it stretched into two weeks of tedious, annoying bug fixes that require all kinds of hacking around and tweaking to even reproduce (but they're still bugs, need to be fixed!)....
That my friends is programmer's hell. And I'm the newest resident, pray for me.
For years now I've wanted to go to JavaOne but unfortunately I cannot afford to pay the $1700 conference fee on my own.. well, that plus travel expenses. It adds up.
So, naturally, I approached my boss with the idea..
"hey, can the company send me to Java one?" - It is work related, I program Java for a living.
He said he'd ask higher up.. which he did...
The result? Not exactly what I expected.. apparently people higher up thought it's a great idea! Wonderful, our engineers want to learn more Java.. that's great.. Let's send two of them! Yep, two *other* ones including my direct boss.. the one I asked if I could go..
Strike one -- time for plan B.
"I'll stay with friends, pay for my own plane tickets and mooch off of others for meals.. Can I go? Pleaaassseee.. ?"
Yah, we have budget for training for each employee.. but.. *nope*.. It will cost too much to send the other two.
Sigh, I can't win.
Many of us coders have a hard time deciding just what to use for a job title.. there are so many different terms that essentially describe the same job.. developer, engineer, programmer, coder, hacker.. In theory, anyway, they describe the same job. I'm sure many would argue against such simplification. but before you fire off an angry comment bear with me, please, I will explain.
What matters is how I introduce myself to people. It really varies vastly from situation to situation. Most of the time it's a simple "I write computer software".. which usually elicists a response of "aaah..." and a vaguely blank stare... When I introduce myself to one of my mom's friends I make sure to throw in a term "engineer" in there somewhere so my mom can stick her nose up in the air "see? My daughter is an *engineer*" even though she has very little clue about what I really do.. and frankly the idea of an engineer her friends probably have is about as close to my job as Moscow is to Bundtown, Tennessee.
"Why do you sit in front of the computer all they long like this? "
"uh.. mom.. " sigh.
The problem of what to call my job arrives when I talk to someone in my field. Another geek.. because everyone has their own pre-conceptions about what a programmer is and what (s)he isn't.
So after careful consideration of this problem.. well, okay, the reality is closer to "after having nothing better to think about during a boring meeting.." I've decided to define my terminology a little better. I write code for a living, but while I may have the same official job title as some other coders I know I don't really think I should be classified the same way some of them are because there are so many different types of programmers that one general term of "programmer" is just not descriptive enough to be useful.
So there is the term "programmer" -- easiest definition, of course, "one who programs". That is what I do, it's what we all (the general code-writing "we") do.. So this one's easy.. a programmer is someone who writes code.
Then there's "software engineer" -- "one who engineers software". Not every programmer is a software engineer.. in fact I would dare say that vast majority of programmers are not. We all know the type.. they write their code, they do a really good job, code is functional, it does what it should.. but that's where it ends. The finer points of design and esthetics escape them... they just don't think about writing software in those terms.. it's just a job to them. Those people who go the mile above and take time to think through design and would not be caught dead copy-pasting code without at least giving the thought to how it functions as part of the overall design are software engineers. They engineer, not just code.
Lastly, but not leastly.. there are "hackers" -- not in the definition made notorious by media (for whom geeks behind keyboards are not exciting enough.. they had to make them into dangerous masterminds) but in the original term of well.. hacking stuff together. I'm sure we all hack code every now and then.. In a hurry.. need to patch a bug in production version.. a hack is sometimes the only way.. but then there are programmers who never do anything *but* hack. Often solving some of the most complex problems and producing some of the most brilliant solutions that neither of the types listed above could ever come up with.. Unfortunately more often than not.. they're the only ones who can even understand the flow of the code.. so if such a coder gets hit by a steam train.. people left over to maintain their code are essentially screwed. I once attempted to work with such code.. it would have been easier to convert a catholic priest to judaism than to understand how this particular project worked. But it did work and well.
So going by above definitions.. I would have to say I'm a software engineer. Of course next time I introduce myself to someone and give them this entire spiel about how I define my job title they will be asleep by the time I reach the term "software". Maybe I should just say "I'm a professional geek". It's quicker.
Load testing aside, it's nearly impossible to account for real live usage when writing test plans and some users have incredible talent for coming up with creative ways of using (or rather misusing) a program in a way it was never intended to function.
We just went through some of that with our new project at work and I think the common conclusion was that we really need to do regular code reviews. Three major issues we just fixed were of the "holy crap, who wrote that" and "why the hell is this doing that?" variety.. Something that would have been immediately spotted if someone bothered to look at the code (someone other than the author anyway). It's so easy to make dumbass mistakes when working under pressure and having a second set of eyeballs verifying your code can be more than just helpful.. it could save your sanity and embarrassment later.
One of the principles of extreme programming is to do something like this - pair programming. Having two people work on the same code at the same time. I've been subjected to that at work for about a week.. and it nearly ended in a homicide as I slowly learned to hate the guts of the poor co-worker stuck coding with me. I'm not really good at working in tandem with another programmer.. especially one that argues about my bracing style while sprinkling the code with tons of unnecessary empty lines and indentation that would make groucho marx go ballistic.. (and he wasn't even a coder.. )
So what's the solution? Code reviews.. weekly session, couple hours long (longer and we'll all fall asleep probably) reviewing randomly picked source from project du-jour..
I think this could really work -- we all get to spot our mistakes before they enter production and can lock ourselves up in blissful, headphone-induced isolation in the meantime. Perfect.
I suppose a statement "useless online polls" is a tad redundant.. but there it is anyway. Someone pointed out a poll to me today on hotscripts.com.. it's right there on the right hand side, just scroll down a tad. See it? That one..
What is your scripting language/platform of choice?
Doesn't appear all that useless, right? Until you see the options..
ASP
C/C++
CFML
Flash
Java
JavaScript
Perl
PHP
Python
XML
Other
XML? Java? C/C++? In a poll about web page scripting? (I assume they mean web page scripting considering their content). Is it not bad enough that half the newbies to web design claim they know Java after writing a 10 line JavaScript.. now websites that claim to be some sort of authority on scripting create a poll with this combination of uh, scripting languages? Get a clue.
Welcome to the misinformation super-highway.
Gratuitous casting to get around bad design.
I refactored code today that did something like this:
// Imagine this method returns an interface
// iStuff which is implemented by an object called Stuff.
//
public static iStuff getStuff(int key) {
iStuff rval = new Stuff(key);
return rval;
}
public void doSomeStuff(int key) {
// Note, this was just cast to an object!
//
Stuff stuff = (Stuff) getStuff(key);
stuff.doSomeChange();
}
Sorry, this is the best way I could duplicate what the code did without actually copying the code. Point is: Instead of changing the design to reflect the fact that the interface did not have a method needed.. someone went and cast an interface to an object. How horrible! Yet legal. Also very dangerous as it will break if someone changes the underlying implementation of the getStuff() method.
Data validation is particularly important when dealing with web development. Especially when passing user input to the database it should be checked not only for validity but also for malicious content.
Something that really bothers me recently (don't ask, project at work) is the level at which the validation is often done when using servlets. Mainly, in the servlet itself. I don't like that. It adds a layer of complexity that is really unecessary and makes reuse and architecture of code more difficult than it has to be.
Java is an object oriented language.. why not use that aspect of it to its fullest ability? Mainly: an object ought to validate itself. So, if you have a user object, instead of using servlet code to validate its attributes (for instance: email address) make the object know what the valid value is.. and return that to the servlet. "Hey object, are you valid? Sure thing! Okie dokie!" .. or.. "Hell no, here's your problem, make them fix it".
Easier, no? Seems obvious.. but apparently not to everyone.
Those advertising folks at Micro$oft must think these things through quite well.. coincidence or not? You be the judge..
Pay attention to article subject.. and that's a damn big ad too!
Catching up on my reading this morning and ran across this on slashdot.
- Generics (I still think that's a horrible term)
- Autoboxing
- Enhanced for-loops
- Enumerations
- Static Imports
Boxing will be incredibly handy.. I use that all the time (as I imagine most Java programmers do).. Generics (yucky term) will save me headaches from necessary-bad-design to sidestep the lack of this feature in current versions of Java. Big thumbs up for static imports as well!
This will be great.. I can hardly wait!
I should start one.. really.
Today's gem:
public class Stupid {
private int _value = 0;
public void setValue(int value) {
if (value == _value) {
_value = value;
}
}
}
Duh..huh.. huh.. why are we always seeing the same value?
I really like the concept behind JavaBlogs... and for a while it really worked well for me. I've read many excellent entries on Java I may have (actually very likely would have) missed otherwise. Unfortunately, as is true with any growing website, the signal to noise ratio is becoming worse and worse.. and not in a good way.
When I first discovered JavaBlogs I read nearly every entry posted and most were great.. agreed with some, disagreed with others.. typical blog-reading experience. These days I find myself skipping more and more entries.. why? They're not about Java.. and many of the ones that are simply reiterate or link to previously posted entries.
I realize it's nearly impossible to run a site like this without some noise, but perhaps the idea of human-driven moderation system isn't a bad one for this particular application?
Of course, this brings up many, many issues.. main one:
- who determines what is acceptable and why are they qualified to do so..
I don't really have answer to that. My two experiences with human-driven moderation systems are dslreports.com and slashdot. The karma-like system on slashdot is obviously failing -- who reads the comments there anymore? The dslreports system is working quite well, I think -- but not sure this is a valid comparison, different type of website.
Is it necessarily a bad thing that a website about Java is listing entries that are not on-topic? Probably not for everyone. It may give some a better feeling of community.. but I already have that elsewhere.. I'd like Java please.
The obvious thing to point out here, of course, I'm posting this in my java-category and it will get posted on JavaBlogs. Guilty myself.
Spent some time today debugging an issue that turned out to be a very simple error which could be easily avoided.
Can you spot the bug in this code?
public class Buggy {
private String value = null;
public Buggy(String value) {
value = value;
}
public String getValue() {
String rval = value;
return rval;
}
}
When getValue() is called it returns a null object.. why?
value = value;
Should be:
this.value = value;
Easy to miss.. pain to debug.
Better yet.. Instead of using this.whatever just name the variables differently.. it makes for easier to read, less confusing code.
I've been thinking lately about good software design. It occurred to me that good design might contradict one of the XP principles: do the simplest thing possible. The problem is that good design is rarely the simplest thing that will work.
I disagree. More often than not (at least in Java, at least in my experience) the simple design is the better one. If you leave room for versatility and growth.. it benefits you more to have a simple design rather than a complex one.
I can think of countless times when I scrapped a complex code structure to replace it with something much more simple.. but much, much better. The problem is that simple and good isn't easy...
I am so behind times on documentation that it's not even funny. Recently I found out that javadoc in SDK 1.4 finally has a recursive option and today I found out that there do exist searchable Java docs. I'll probably still just grep through my local copy though :)
Thanks to Damon who posted this information in Jeremy's rant about the lack of searchable Java docs.
To go with my previous entery about pointers "The Fishbowl" has his/hers own entry on the same topic.. both inspired by Jeremy's adventures with Java.
The part I really want to reference is this section:
- Before you start writing a method, decide whether it will ever return null. Document this decision in the @return section of the method's Javadoc.
- Never have a method return null unless there's a really good reason for it.
- If your method returns an array or a collection, there's no reason to ever return null. Return an empty array or collection instead.
- If you have a situation where null is a valid value for a variable, you can make use of the Introduce Null Object refactoring, to make the behaviour explicit.
That's very good advice.
Jeremy discovered the ever popular, friendly and loveable NullPointerException. Hey, now you can call yourself a Java programmer! (Okay, so it doesn't take much).
It's a common misconception that Java has no pointers. It's not exactly true. Java has pointers, they're just not explicit. Every object is a reference to a location making it a pointer... you just can't manipulate the pointers directly.
Which approach is better.. explicit or not? Well, that very much depends on the context and scope of the application. I'm sure everyone who ever went through learning C will however agree that non-explicit pointers are sure as hell easier to comprehend for someone who is just learning programming.
Here's why it's a pointer.. say you have two Strings s and t
String s = "hi"; String t = "hello";
These are two separate objects in two different locations.
t = s;
Now t and s both reference the same location hence referencing the same object. That is a behavior of a pointer. Now for the purists (hi Steve) that will argue that this is still not a pointer.. oh well.. it's all based on how you define it.
There is a reason I really do not like chaining calls together when writing Java code. Here's why.
This statement:
object.setValue(rs.getString("value"), otherObject.geCode());
Becomes this nightmare when trying to step into the setValue method:
step Step completed: thread="ExecuteThread: '494' for queue: 'default'", weblogic.jdbc.pool.ResultSet.getString(), line=267, bci=0step up
Step completed: thread="ExecuteThread: '494' for queue: 'default'", weblogic.jdbc.pool.ResultSet.getString(), line=269, bci=24step
Step completed: thread="ExecuteThread: '494' for queue: 'default'", class.method(), line=561, bci=366step
Step completed: thread="ExecuteThread: '494' for queue: 'default'", otherClass.getCode(), line=316, bci=0step up
Step completed: thread="ExecuteThread: '494' for queue: 'default'", class.method(), line=561, bci=373step
Step completed: thread="ExecuteThread: '494' for queue: 'default'", class.setValue(), line=782, bci=0
If the code was written this way:
String value = rs.getString("value");
String code = otherObject.getCode();
object.setValue(value, code);
The debugging process would have consisted of:
step Step completed: thread="ExecuteThread: '494' for queue: 'default'", class.setValue(), line=782, bci=0
That saves quite a few steps, typing and aggrevatioin time during debugging. Chaining is sometimes appropriate, often not... while this example may seem innocuous (it wasn't, but I can't publish code from work!) it illustrates just why chaining may become a pain really quickly when debugging.
It's easy to deprecate classes in Java.. a little too easy. All you have to do is add a Javadoc-style comment with the @deprecated tag. That leads to problems... Something I see over and over again.. example:
/** * @deprecated */ public String getSomeValue(int id);
The problem here? This method is now deprecated, but no reason stated as to why, no date or version provided as of when and no alternative call. In other words zero useful information but it will generate compiler warnings when called.
I see that as a big problem... I think Java should require *more* information before allowing for this to compile and generate compile errors otherwise.
When I deprecate a method I like to provide either a "as of" version or date and an alternative to use. Really, the most important part is the alternative method. Otherwise any programmer who is going to attempt using this code will either have to leave compile warnings (something I really don't like as it can lead to bugs) or do (possibly extensive) detective work to figure out what he/she should be using instead.
This is all really easily fixed by proper commenting -- but we all know how many programmers really utilize proper commenting.
I think Java should at the very least require the use of the @see tag with the @deprecated tag.
/** * @deprecated as of version 1.1 * @see getSomeOtherValue */ public String getSomeValue(int id);
Javadoc documentation recommends this usage but it is not enforced by the compiler.
More info about Javadocs here.
Some good tips from Blogging Roller:
- Don't store too much in each session
- Don't create sessions at all if you can avoid it
- Use database connection pooling
- Avoid string concatenation
- Minimize thread synchronization
- Don't use SingleThreadedModel
Couple more:
- Cache frequently used information
- Keep the number of database hits to the bare minimum
- Avoid unnecessary string comparisons
Today was a kind of a milestone for a project I'm currently working on along with some of my co-workers. As part of our many-a-day trips to refill our coffee mugs, my boss and I were unofficially (in other words, just a conversation, not policy making) discussing how the project flow could have been improved..
There was the obvious..
Good lord people, haven't you ever heard of unit test files!
and the ever popular, yet often ignored..
Proper test data setup before you attempt to test code
What was more interesting is the discussion how improvements to Java would have made our lives easier.. mainly couple things..
1. (this one's mine) Templates.. not just interfaces (which Java has, duh) but templates ala C++.
2. Common error handling. What a drag it is to have to write try-catch blocks.. Certainly, you can combine and streamline much of that code, but cannot avoid those try-catches.
That's my Java wish list for the day.
I ask, no, I beg if you do nothing else with your code, please, please, please format it properly.
I don't care if it works.
I don't care if there is error handling.
I don't care if it compiles.
I care if it's formatted properly.
Why?
Because re-formatting code just so I can read it takes me more time than fixing bugs in it.
That's why.
Indentation, spacing, break up long lines, logical variable names, avoid global variables, avoid duplication of code, avoid excessively long methods.
Thank you.
There is nothing more frustrating than attempting to do a teeny little code change in the back-end and discovering your teeny little code change actually requires changes in 50 different classes all accross the board because someone failed to utilize an interface when they wrote the original code.
Interfaces are your friend. It's good to use them, really.
One thing they do quite well is hide the implementation from the calling classes. Why is that good? Well, when you want to change the implementation you don't have to change the calling classes.. Saves time, saves work, saves QA resources, code is more readable, more versatile and easier to maintain.
Perfect example of when you really should use an interface...
ArrayList (java.util package).. it's a nifty class.. handy, useful, used a lot and it implements the List interface (same package). Imagine you wrote a class at one point that retrieves some data from the database and returns it in the form of an ArrayList. Like so..
public ArrayList getStuff(int id) {
ArrayList rval = new ArrayList();
// magical code that gets the stuff
return rval;
}
Simple, easy, dependable.. but there is a better way! Have you guessed yet? That's right.. an interface!
public List getStuff(int id) {
List rval = new ArrayList()
// magical code that gets the stuff
return rval;
}
What was accomplished here? If at some point you decide you want to use, say, a LinkedList instead of an ArrayList because it happens to be more efficient for the particular purpose you use the results for, the only place you need to change the code is in this little method. Neat, no?
How do you know when a class implements an interface you could use? Javadocs!
Interfaces have many other benefits, but this is the particular one that I somehow wanted to write about today.. no reason, really..
The blogging roller says so and I completely agree.
In fact I said something pretty similar a while ago.
Nice little walk through at the blogging roller.
I'm an old fashioned gal and tend towards using JDBC's ability to retrieve metadata and build persistence framework on the fly.. Performance degredation is negligent for my purposes.
This is of course for my own little projects.. at work, well, we use something other.
Jeremy has been blogging from the OSXCon. Today James Gosling talked about Java.
Gosling said.. Java has been successful everywhere but the desktop. Or at least that's what people hear. It's big on the server and that drowns out the desktop news.
This is something I just don't understand. Why push Java on the desktop? It has not done well in that market and I don't really think it will in the future no matter how many swing libraries materialize. Don't get me wrong, Java is a great language. It's versatile, powerful and manages to keep simplicity despite being a powerhouse of tools.
The main thing about Java is "write once, run anywhere".. which is fantastic, but it turned out to be better for servers than clients. There are a lot of problems with developing Java GUIs, swing not-withstanding. They're slow, quirky and look and feel isn't quite standardized (that's a bigger problem than people might think) . Unless ran in a browser... and who the heck really wants applets besides Yahoo games?
Webstart is a cool project, but since a user needs to have Java already installed on their computer to use it, it's relatively useless in saving Java on the desktop. I just don't think this will happen unless Microsoft starts to distirbute Java as part of the operating system and I don't see that happening anytime soon. Not yet anyway.
- If you have a block of code that appears more than once, don't make it a method!
finally {
if(rs != null) {
try {
rs.close();
} catch (Exception e) {
// Ignore
}
}
if(ps != null) {
try {
ps.close();
} catch (Exception e) {
// Ignore
}
}
}Sprinkled into every single method in a database access class creates more lines of code and makes you look like a busy little coding bee.
- When you have to reuse the same string more than once in a class, forget about declaring static variables.. only sissies do that. Adventurous people get joy out of discovering typos. Think of how many hours you can spend debugging and looking busy!
- Don't oversimplify SQL.. sure you can use..
"SELECT MAX(COLUMN) +1 FROM TABLE"
.. but this is much more exciting and it'll impress all the chicks in the office:
"SELECT MAX(NVL(COLUMN_NAME,0)) + 1 NEW_VAR FROM TABLE_NAME"
- Don't forget to make sure all SQL syntax is as database-specific as you can get it. If they ask for compatibility with another database, more hours of billable time!
- Even if you are using triggers for setting update time on tables, use "update_time=sysdate" just in case that trigger doesn't fire.. you can't be too careful!
- Make sure your SQL code is nicely formatted..
"SELECT Column_One, Column_Two, Column_Three FROM Table_Name WHERE Id=?"
looks so much prettier than..
"SELECT column_one, column_two, column_three FROM table_name where id=?" - When throwing exceptions, throw away that silly old SQL exception.. throw something new and exciting. The database was probably just complaining about something silly anyway. For simplicity, keep all your exception messages the same. "Operation failed" works just fine and to the point.
- Don't use Interfaces! They're a part of a communist plot to hide information. Be nice to the caller, let them know exacly how you implement things..
ArrayList list = new ArrayList(); :-)
List list = new ArrayList(); :-( - Import statements are a waste of space. See how many more lines the second variation takes?
java.util.List list = new java.util.ArrayList();-----------------
import java.util.ArrayList;
import java.util.List;.
.
.List list = new ArrayList();
- Ordering and alphabetizing import statements is a waste of time. It's not like they get included in compiled code anyway.
- Don't break up long lines, it's what the wrap function in a text editor is for. Why use up more lines?
- Comment your code heavily! "return rval;" may mean something different than what it looks like! Some programmers are sneaky that way. Don't be one of them.
- Declare all variables globally. Keeping variables local just because you only use them once is silly.. what if you decide to use it again? huh? What then?
- Chain your calls!
Object o = new Object(b.getVal(), c.getMoreVal(d.getAnotherVal()), (g == f ? (y.getBah() == z.getBleah() ? duh : new f())y.getVal() : x.getObject(new g())));You can do all this on just one line! Why waste space?
(Continuing with cleaning up old backups..) I found my very first Java program... written for CSII course (CSI was in Pascal). It produces an octal dump of a given file.. essentially poor man's od.
Boy did I ever suck as a programmer back then!
About a year and a half ago, I was playing around with Tomcat source trying to customize some things (work, don't ask). Well, I merrily forgot all about that, until today...
I attempted to get a newer version of tomcat running on that same machine.. it kept giving me really odd errors.. Couldn't figure it out, until I ran a trace on what it was doing.. Low and behold.. It's using the old hacked-up source I haven't touched in over a year instead of its nice, shiny new jar files.
rm -rf and problem fixed.. but in the meantime, several hours of debugging nightmare..
(Think John Lennon)
Imagine there's no classes,
It isn't hard to do.
No objects to send messages
No references too
Imagine all the methods
Static and you've got C.
O-ho you might say that that's a nightmare
And you're not the only one
But the language has its uses
And like Java can be fun.
by David Arnow (arnow@sci.brooklyn.cuny.edu) (I think, that's the only reference I found)
I wrote this up once in a forum post on dslreports and recently someone asked me about that again... I've been working on a *better* and more encompassing (ie: not just tomcat) write up to post somewhere on my web page, but for now, to preserve it for posterity, here's what I posted on dslr a long time ago..
JDB is the debugger that comes with Sun's JDK.
It's very important to use at least version 1.3.0 of JDK, otherwise the debugger is rather flaky and tends to core dump.
1. Start tomcat with these options:
-Xdebug -Xnoagent -Djava.compiler=NONE
-Xrunjdwp:server=y,
transport=dt_socket,address=8000,suspend=y
8000 can be replaced by any other numerical value.. it basicaly tells jvm to listen on that port for a debugger.
What will happen now, is tomcat will start but suspend itself and wait for a debugger to attach before proceeding.
2. start JDB and attach:
jdb -attach localhost:8000
in here, localhost can be replaced by where tomcat is running if it's running on a different machine and 8000 can be replaced with whatever port you set jvm in tomcat.
Voila! You can now debug servlets.
Linux Magazine in this article writes:
The disadvantage of Java Servlets is that they don't provide, by default, a good separation of program logic and presentation, since statements that output HTML are intermixed with the application logic, making maintenance difficult. One solution to that problem is the Velocity template engine, a Jakarta project (http://jakarta.apache.org/velocity).
What baloney.. I've done this for a living for a while now and there is absolutely nothing in the servlet design that prevents an easy separation of the application/logic layer from presentation. It's all about programming style.. I wish some authors would do more research and less whining.
Just fired them off an e-mail about that.. and that means I'm really annoyed!