DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Curious about the future of data-driven systems? Join our Data Engineering roundtable and learn how to build scalable data platforms.

Data Engineering: The industry has come a long way from organizing unstructured data to adopting today's modern data pipelines. See how.

Threat Detection: Learn core practices for managing security risks and vulnerabilities in your organization — don't regret those threats!

Managing API integrations: Assess your use case and needs — plus learn patterns for the design, build, and maintenance of your integrations.

Avatar

Andrew Spencer

Software Engineer at ISO

Geneva, CH

Joined Aug 2010

About

Andrew trained as a biologist before transmuting into a software engineer. He's been coding in Java since 1997, and has done a bit of scientific software, a bit of mobile gaming and lots of enterprise software. He's particularly interested in humane and sustainable development. Professionally, that means code maintainability and agile methods. Outside the professional sphere: permaculture, gardening, cooking, green transport and raising children (not by order of importance). He also loves ensemble singing, but that’s on hold for now.

Stats

Reputation: 6
Pageviews: 190.5K
Articles: 2
Comments: 101
  • Articles
  • Comments

Articles

article thumbnail
Solve Foreign-key Problems in DBUnit Test Data
If you create small per-test datasets, as DBUnit advises, you’ll get intermittent build failures due to foreign-key violations. This post explains (1) why this happens, (2) why small per-test datasets are still a good idea, and (3) one simple way to get around the problem. NB When I searched for solutions to this problem, I discovered that other kinds of foreign-key problem come up with DBUnit. Some people have circular dependencies in their relational database schemas, which stops DBUnit from loading the test data. If such is your case, I’m sorry to say that this post won’t help you with it, and your best option is probably to just take yourself outside and shoot yourself now. (Although some people seem to chosen instead to disable foreign key checking during test runs.) What causes the foreign-key violations The cause of the problem is simple, and illustrated by a trivial example. Suppose you have two entity classes, HitchHiker and SpaceShip. The HitchHiker table has a foreign key that references SpaceShip. The test data for HitchHikerDaoTest contains lines from both tables, whereas the test data for SpaceShipDaoTest contains only lines from SpaceShip. DBUnit’s default setup operation, CLEAN_INSERT, wipes data from every table occurring in the test dataset and then inserts the lines listed in that dataset. When SpaceShipDaoTest runs, DBUnit will start by deleting everything in the SpaceShip table. If any HitchHikers are currently riding in the SpaceShips that are about to be deleted, the database will object to their untimely eviction (I’m not sure whether the error message will read like Vogon poetry, though). If you start from an empty database, and execute SpaceShipDaoTest and then HitchHikerDaoTest, you’ll be fine; but if you do it in the other order, your build will fail. It’s that second-worst kind of bug, the unpredictable kind, since you don’t (usually) specify the order in which tests run. After all, they’re supposed to be independent! So you may well find that you have no problems for months on end, until one day you get an error running individual tests in a particular sequence, or Maven changes the order in which it runs your tests on the CI server, and BOOM! Why you should still use small independent datasets It’s tempting to circumvent the problem by using a single monolithic dataset for all your integration tests. I’ve tried this, and I advise against it. A big data file is hard to work with: you waste a lot of time scrolling around looking for the line you need, and it’s very hard to follow and understand foreign-key relations. Worse still: by modifying the data to make one test pass, you can easily accidentally break another one. The larger the dataset and the test suite become, the more fragile they get, and the more painstaking it becomes to modify them. How to avoid the foreign-key problem with small independent datasets One working but unsatisfactory solution would be to pad out every XML dataset with the list of all tables touched in the test suite. It’s unsatisfactory because the only way to add a table into a FlatXmlDataSet is to list a line of that table — a FlatXmlDataSet can’t contain empty tables — and there’s no justification for polluting the test data with lines from tables that are not part of the test. The solution I found was to use a DTD to clean tables before tests. Every XML file has different contents, but they all reference a single DTD which lists all the tables involved in the test suite. The DTD is easy to generate from the database schema, and useful for auto-complete and catching typos in column names, so you should probably already be using one. The code to exploit its contents is very simple: private IDataSet loadTestDataWithDtdTableList(String dtdFilename) throws IOException, DataSetException, SQLException { Reader dtdReader = new FileReader(new ClassPathResource(dtdFilename).getFile()); IDataSet dtdDataset = new FlatDtdDataSet(dtdReader); FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder(); builder.setMetaDataSet(new DatabaseDataSet(dbUnitConnection, false)); IDataSet xmlDataset = builder.build(asFile(xmlFilename)); return new CompositeDataSet(dtdDataset, xmlDataset);} How it works: DBUnit provides a facility to load a dataset from a DTD. This dataset contains all the tables listed in the DTD, but of course empty of data. The DTD dataset is then combined with a FlatXmlDataSet representing your test data. The graphic below illustrates the composite dataset that would be produced for the SpaceShip example. If you have dictionary tables whose contents never change, you can and should leave them out of the DTD as well as out of the XML datasets, to improve test performance a little. One further detail: you should close the FileReader after test setup. I couldn’t find a hook into the end of the test setup operation (short of writing my own DatabaseOperation), so I saved the reference as a member variable and hooked the close() call into the tear-down phase of the test. NB For a more complete code example, see this Gist snippet of a base class for TestNG+Spring+DBUnit tests that adds the above-described DBUnit setup operation to Spring’s TestNG helper class. Happy database testing! From http://www.andrewspencer.net/2011/solve-foreign-key-problems-in-dbunit-test-data/
February 16, 2011
· 27,186 Views
article thumbnail
Maven Profile Best Practices
Maven profiles, like chainsaws, are a valuable tool, with whose power you can easily get carried away, wielding them upon problems to which they are unsuited. Whilst you're unlikely to sever a leg misusing Maven profiles, I thought it worthwhile to share some suggestions about when and when not to use them. These three best practices are all born from real-world mishaps: The build must pass when no profile has been activated Never use Use profiles to manage build-time variables, not run-time variables and not (with rare exceptions) alternative versions of your artifact I'll expand upon these recommendations in a moment. First, though, let's have a brief round-up of what Maven profiles are and do. Maven Profiles 101 A Maven profile is a sub-set of POM declarations that you can activate or disactivate according to some condition. When activated, they override the definitions in the corresponding standard tags of the POM. One way to activate a profile is to simply launch Maven with a -P flag followed by the desired profile name(s), but they can also be activated automatically according to a range of contextual conditions: JDK version, OS name and version, presence or absence of a specific file or property. The standard example is when you want certain declarations to take effect automatically under Windows and others under Linux. Almost all the tags that can be placed directly in a POM can also be enclosed within a tag. The easiest place to read up further about the basics is the Build Profiles chapter of Sonatype's Maven book. It's freely available, readable, and explains the motivation behind profiles: making the build portable across different environments. The build must pass when no profile has been activated (Thanks to for this observation.) Why? Good practice is to minimise the effort required to make a successful build. This isn't hard to achieve with Maven, and there's no excuse for a simple mvn clean package not to work. A maintainer coming to the project will not immediately know that profile wibblewibble has to be activated for the build to succeed. Don't make her waste time finding it out. How to achieve it It can be achieved simply by providing sensible defaults in the main POM sections, which will be overridden if a profile is activated. Never use Why not? This flag activates the profile if no other profile is activated. Consequently, it will fail to activate the profile if any other profile is activated. This seems like a simple rule which would be hard to misunderstand, but in fact it's surprisingly easy to be fooled by its behaviour. When you run a multimodule build, the activeByDefault flag will fail to operate when any profile is activated, even if the profile is not defined in the module where the activeByDefault flag occurs. (So if you've got a default profile in your persistence module, and a skinny war profile in your web module... when you build the whole project, activating the skinny war profile because you don't want JARs duplicated between WAR and EAR, you'll find your persistence layer is missing something.) activeByDefault automates profile activation, which is a good thing; activates implicitly, which is less good; and has unexpected behaviour, which is thoroughly bad. By all means activate your profiles automatically, but do it explicitly and automatically, with a clearly defined rule. How to avoid it There's another, less documented way to achieve what aims to achieve. You can activate a profile in the absence of some property: !foo.bar This will activate the profile "nofoobar" whenever the property foo.bar is not defined. Define that same property in some other profile: nofoobar will automatically become active whenever the other is not. This is admittedly more verbose than , but it's more powerful and, most importantly, surprise-free. Use profiles to adapt to build-time context, not run-time context, and not (with rare exceptions) to produce alternative versions of your artifact Profiles, in a nutshell, allow you to have multiple builds with a single POM. You can use this ability in two ways: Adapt the build to variable circumstances (developer's machine or CI server; with or without integration tests) whilst still producing the same final artifact, or Produce variant artifacts. We can further divide the second option into: structural variants, where the executable code in the variants is different, and variants which vary only in the value taken by some variable (such as a database connection parameter). If you need to vary the value of some variable at run-time, profiles are typically not the best way to achieve this. Producing structural variants is a rarer requirement -- it can happen if you need to target multiple platforms, such as JDK 1.4 and JDK 1.5 -- but it, too, is not recommended by the Maven people, and profiles are not the best way of achieving it. The most common case where profiles seem like a good solution is when you need different database connection parameters for development, test and production environments. It is tempting to meet this requirement by combining profiles with Maven's resource filtering capability to set variables in the deliverable artifact's configuration files (e.g. Spring context). This is a bad idea. Why? It's indirect: the point at which a variable's value is determined is far upstream from the point at which it takes effect. It makes work for the software's maintainers, who will need to retrace the chain of events in reverse It's error prone: when there are multiple variants of the same artifact floating around, it's easy to generate or use the wrong one by accident. You can only generate one of the variants per build, since the profiles are mutually exclusive. Therefore you will not be able to use the Maven release plugin if you need release versions of each variant (which you typically will). It's against Maven convention, which is to produce a single artifact per project (plus secondary artifacts such as documentation). It slows down feedback: changing the variable's value requires a rebuild. If you configured at run-time you would only need to restart the application (and perhaps not even that). One should always aim for rapid feedback. Profiles are there to help you ensure your project will build in a variety of environments: a Windows developer's machine and a CI server, for instance. They weren't intended to help you build variant artifacts from the same project, nor to inject run-time configuration into your project. How to achieve it If you need to get variable runtime configuration into your project, there are alternatives: Use JNDI for your database connections. Your project only contains the resource name of the datasource, which never changes. You configure the appropriate database parameters in the JNDI resource on the server. Use system properties: Spring, for example, will pick these up when attempting to resolve variables in its configuration. Define a standard mechanism for reading values from a configuration file that resides outside the project. For example, you could specify the path to a properties file in a system property. Structural variants are harder to achieve, and I confess I have no first-hand experience with them. I recommend you read this explanation of how to do them and why they're a bad idea, and if you still want to do them, take the option of multiple JAR plugin or assembly plugin executions, rather than profiles. At least that way, you'll be able to use the release plugin to generate all your artifacts in one build, rather than a single one at a time. Further reading Profiles chapter from the Sonatype Maven book. Deploying to multiple environments (prod, test, dev): Stackoverflow.com discussion; see the first and top-rated answer. Short of creating a specific project for the run-time configuration, you could simply use run-time parameters such as system properties. Creating multiple artifacts from one project: How to Create Two JARs from One Project (…and why you shouldn’t) by Tim O'Brien of Sonatype (the Maven people) Blog post explaining the same technique Maven best practices (not specifically about profiles): http://mindthegab.com/2010/10/21/boost-your-maven-build-with-best-practices/ http://blog.tallan.com/2010/09/16/maven-best-practices/ This article is a completely reworked version of a post from my blog.
November 27, 2010
· 139,739 Views · 4 Likes

Comments

Adobe Flex: Styling the DataGrid header separators

May 02, 2012 · Jon Baker

It's worth knowing all the refactoring shortcuts.

For Java:

Alt+Ctrl+R rename Alt+Ctrl+V move Alt+Ctrl+I inline (a variable or a method) Alt+Ctrl+L local variable - makes a variable from the selected expression; the opposite of variable inlining Alt+Ctrl+Tbrings up the refactoring menu which you need for things like Extract Interface, Pull Up/Down etc that don't have keyboard shortcuts

10 Best Eclipse Shortcuts

May 02, 2012 · James Sugrue

It's worth knowing all the refactoring shortcuts.

For Java:

Alt+Ctrl+R rename Alt+Ctrl+V move Alt+Ctrl+I inline (a variable or a method) Alt+Ctrl+L local variable - makes a variable from the selected expression; the opposite of variable inlining Alt+Ctrl+Tbrings up the refactoring menu which you need for things like Extract Interface, Pull Up/Down etc that don't have keyboard shortcuts

Acid3: ECMAScript and the DOM

Mar 10, 2012 · Mr B Loid

Number 13 is an excellent suggestion - I wish teams would spend more time talking about this (actually no, that's not enough - they also need to come to agreement, and then put it into practice).

I don't entirely agree with number 11 - it depends, and I wrote a counter argument a while back, here: http://www.andrewspencer.net/2011/which-language-should-you-code-in/

Best Practices for Variable and Method Naming

Mar 10, 2012 · James Sugrue

Number 13 is an excellent suggestion - I wish teams would spend more time talking about this (actually no, that's not enough - they also need to come to agreement, and then put it into practice).

I don't entirely agree with number 11 - it depends, and I wrote a counter argument a while back, here: http://www.andrewspencer.net/2011/which-language-should-you-code-in/

Oracle releases technology preview of the upcoming 11g development platform

Mar 10, 2012 · Shay Shmeltzer

Yes, it's not about whether you use the command line or not (though there's definitely a correlation), it's about attitudes to risk and awareness of long-term viability issues.

I agree with most of the preceding comments, and I think that the answer to the original question is that, even in a corporate environment, youneed both types of people. The conflict that arises between the two tendencies, though frustrating to both, is a symptom of a necessary and healthy process.

Do we need third-party Flex frameworks?

Feb 16, 2012 · Gerd Storm

Question 9. Do they use Clearcase?

Retrieve images from SQL Server and store in VB.Net

Feb 09, 2012 · Tony Thomas

Very funny.

@Dapeng Liu - you're right, but read the 2nd from last paragraph again.

@Daniel Tuchtenhagen - the OP is just being facetious, but here's a serious answer: in code like that, I wouldn't trust anything that the method name tells me. I've already seen methods whose behaviour flatly contradicts their name.

Why does my Maven build suddenly fail?

Feb 06, 2012 · Ted Vinke

It was a big mistake on Maven's part letting people use plugins without specifying the version (though the kind of mistake that's a lot easier to see with hindsight). At least Maven 3 warns you, as Lieven said.

As an aside, I'd suggest putting the plugin version into the pluginManagement section of the POM, by analogy with what one does for dependency versions.

Starting cluster of Erlang nodes on EC2

Jan 23, 2012 · Mr B Loid

Hi Jilles,

OK, I was thinking "compile and package" rather than "build". Old habits die hard.

The appropriate way to do it in Maven is to define all that boilerplate in a super POM that can be inherited by every standard java webapp. Then the Maven version is: inherit from super POM, mvn clean install.

So I think your criticism is partly unfair, and partly justified. It's unfair insofar as Java webapps can be done simply with Maven (after all, using a super POM is hardly rocket science).

On the other hand, it's a justified criticism insofar as Maven leaves the developer far too much latitude to do it badly. It's also justified in that Eclipse provides all that functionality off the shelf, whereas Maven doesn't provide a useful mechanism for providing/sharing shrinkwrapped POM configurations (the inheritance mechanism is too unwieldy).

Starting cluster of Erlang nodes on EC2

Jan 23, 2012 · Mr B Loid

Hi Jilles,

OK, I was thinking "compile and package" rather than "build". Old habits die hard.

The appropriate way to do it in Maven is to define all that boilerplate in a super POM that can be inherited by every standard java webapp. Then the Maven version is: inherit from super POM, mvn clean install.

So I think your criticism is partly unfair, and partly justified. It's unfair insofar as Java webapps can be done simply with Maven (after all, using a super POM is hardly rocket science).

On the other hand, it's a justified criticism insofar as Maven leaves the developer far too much latitude to do it badly. It's also justified in that Eclipse provides all that functionality off the shelf, whereas Maven doesn't provide a useful mechanism for providing/sharing shrinkwrapped POM configurations (the inheritance mechanism is too unwieldy).

Starting cluster of Erlang nodes on EC2

Jan 23, 2012 · Mr B Loid

Hi Jilles,

OK, I was thinking "compile and package" rather than "build". Old habits die hard.

The appropriate way to do it in Maven is to define all that boilerplate in a super POM that can be inherited by every standard java webapp. Then the Maven version is: inherit from super POM, mvn clean install.

So I think your criticism is partly unfair, and partly justified. It's unfair insofar as Java webapps can be done simply with Maven (after all, using a super POM is hardly rocket science).

On the other hand, it's a justified criticism insofar as Maven leaves the developer far too much latitude to do it badly. It's also justified in that Eclipse provides all that functionality off the shelf, whereas Maven doesn't provide a useful mechanism for providing/sharing shrinkwrapped POM configurations (the inheritance mechanism is too unwieldy).

j2me emulator for nokia

Jan 10, 2012 · sunwindsurfer

Tomasz, I agree, and there is another problem with constructors, which is that parameters aren't named (as they are with setter injection). You can get round this by using a builder but then you have even more repetition (so much so that I've never yet found it worthwhile to write one).

BTW I think that shorthand for combining constructor arguments + final fields is Scala's nicest feature when used purely as an improved Java (that is, aside from the features like FP that are totally alien to Java).

Jens, nice article and I will be bookmarking it for use in future arguments debate.

j2me emulator for nokia

Jan 10, 2012 · sunwindsurfer

Tomasz, I agree, and there is another problem with constructors, which is that parameters aren't named (as they are with setter injection). You can get round this by using a builder but then you have even more repetition (so much so that I've never yet found it worthwhile to write one).

BTW I think that shorthand for combining constructor arguments + final fields is Scala's nicest feature when used purely as an improved Java (that is, aside from the features like FP that are totally alien to Java).

Jens, nice article and I will be bookmarking it for use in future arguments debate.

j2me emulator for nokia

Jan 10, 2012 · sunwindsurfer

Tomasz, I agree, and there is another problem with constructors, which is that parameters aren't named (as they are with setter injection). You can get round this by using a builder but then you have even more repetition (so much so that I've never yet found it worthwhile to write one).

BTW I think that shorthand for combining constructor arguments + final fields is Scala's nicest feature when used purely as an improved Java (that is, aside from the features like FP that are totally alien to Java).

Jens, nice article and I will be bookmarking it for use in future arguments debate.

j2me emulator for nokia

Jan 10, 2012 · sunwindsurfer

Tomasz, I agree, and there is another problem with constructors, which is that parameters aren't named (as they are with setter injection). You can get round this by using a builder but then you have even more repetition (so much so that I've never yet found it worthwhile to write one).

BTW I think that shorthand for combining constructor arguments + final fields is Scala's nicest feature when used purely as an improved Java (that is, aside from the features like FP that are totally alien to Java).

Jens, nice article and I will be bookmarking it for use in future arguments debate.

Starting cluster of Erlang nodes on EC2

Jan 09, 2012 · Mr B Loid

Jilles,

I sympathise with the problems of bad POM authorship, especially copy-paste and dodgy dependencies. This is partly laziness on the part of developers and I think it's unfair to blame it all on Maven (I mean, I've seen plenty of bad Java code, but that doesn't mean I shouldn't code in Java myself) .

The dependency mess, though, is also caused by bad practices by library providers who often don't take care declaring their own dependencies. The plugin configuration mess... well, it's mostly a lack of standardisation, but I'm not sure how it can be improved given that most of these plugins are not produced by the Maven project itself. And the verbosity, that's entirely Maven's responsibility.

What I'm interested in learning is, what would a build tool look like that kept the good points of Maven, but improved on the bad ones?

Starting cluster of Erlang nodes on EC2

Jan 09, 2012 · Mr B Loid

Jilles,

I sympathise with the problems of bad POM authorship, especially copy-paste and dodgy dependencies. This is partly laziness on the part of developers and I think it's unfair to blame it all on Maven (I mean, I've seen plenty of bad Java code, but that doesn't mean I shouldn't code in Java myself) .

The dependency mess, though, is also caused by bad practices by library providers who often don't take care declaring their own dependencies. The plugin configuration mess... well, it's mostly a lack of standardisation, but I'm not sure how it can be improved given that most of these plugins are not produced by the Maven project itself. And the verbosity, that's entirely Maven's responsibility.

What I'm interested in learning is, what would a build tool look like that kept the good points of Maven, but improved on the bad ones?

Starting cluster of Erlang nodes on EC2

Jan 09, 2012 · Mr B Loid

Jilles,

I sympathise with the problems of bad POM authorship, especially copy-paste and dodgy dependencies. This is partly laziness on the part of developers and I think it's unfair to blame it all on Maven (I mean, I've seen plenty of bad Java code, but that doesn't mean I shouldn't code in Java myself) .

The dependency mess, though, is also caused by bad practices by library providers who often don't take care declaring their own dependencies. The plugin configuration mess... well, it's mostly a lack of standardisation, but I'm not sure how it can be improved given that most of these plugins are not produced by the Maven project itself. And the verbosity, that's entirely Maven's responsibility.

What I'm interested in learning is, what would a build tool look like that kept the good points of Maven, but improved on the bad ones?

Rails getting inspiration from symfony

Jan 09, 2012 · Stefan Koopmanschap

I agree in substance with almost everything you've written in these three posts. In particular the verbosity and inflexibility. About inflexibility, I would add that it's mostly in the fixed nature of the build lifecycle; the plugin architecture gives quite a lot of flexibility, but only up to the point where you need to do something that doesn't fit well with the lifecycle model. And on Maven's good points, let's not forget that there was no standard mechanism for managing library dependencies before Maven was invented.

I do want to take issue with one detail of your criticisms. You dislike that, as soon as you need non-default configuration for a plugin, you find yourself obliged to manage its version. In truth, though, the problem is the other way round. As long as you don't need any non-default configuration for a plugin (and practically everything in Maven is a plugin), then you're leaving Maven to manage your plugin versions.

And Maven does this using a rule that you probably don't want. As I recall, it uses the version in your local repository if there is one, and if there isn't, it downloads the latest. This means you can get breaking changes when you clean your local repository, or build on a new machine, without having changed anything in your code or POM.

Now, that's fine, as long as you don't need your builds to be repeatable...

Silverlight 1.1 Development with Visual Studio 2008

Jan 03, 2012 · Tony Thomas

Nit picking mode: the quote is from Blaise Pascal. Je n'ai fait celle-ci plus longue que parce que je n'ai pas eu le loisir de la faire plus courte (I only made this [letter] longer because I had not the time to make it shorter) http://en.wikiquote.org/wiki/Blaise_Pascal

Nice quote, though, and very apposite to software development.

(Aaron Hillegass) Using "Cocoa Programming for Mac OS X" with Xcode 3.0

Dec 16, 2011 · Mr B Loid

JUnit users, be warned that the dependency on Hamcrest is broken up to JUnit 4.9 inclusive. The dependency on Hamcrest is declared in the POM - but the Hamcrest classes are also included in the junit-dep jar! So you can never get them off the classpath. This is corrected in 4.10.

An alternative to Hamcrest for writing highly readable assertions is fest-assert. It gives readability on a par with Hamcrest-based asserts, with the extra advantage of using IDE autocomplete. It also works equally well with TestNG.

Neither of fest-assert nor Hamcrest has an unarguable advantage over the other, but both are clearly better than basic JUnit or TestNG assertions, where it's never explicit which parameter is the expected value and which the observed. (And to make things worse, TestNG uses the opposite order to JUnit, just to make sure you've no chance of remembering the order.)

Comparing Web Frameworks

Dec 01, 2011 · Mr B Loid

I think the last two comments are missing the point slightly.

Yes, once you've realised that you're missing a case in your unit test, you add the missing line as the two previous commenters said. That is not the point of the article. The point of the article is that (1) human eyeballs will not catch all the missing cases in all the unit tests, and (2) test coverage will not catch them either. Therefore, what other automatable technique could we use? The article offers one approach, but I agree with another previous commenter that mutation testing is probably a less labour-intensive way to get to the same goal.

Guice Questions (with Answers)

Dec 01, 2011 · Mr B Loid

I take issue with the approach of extracting an interface and writing the stub by hand. With tools like Mockito, you can stub concrete classes. This generally involves less boilerplate than writing stubs by hand. And, it means that we no longer need to program to interfaces for reasons of testability alone.

Programming to interfaces has been promoted as a good design practice, independent of its effect on testability. I held that belief myself not so long ago. With the benefit of greater experience, I now think that it's justified only when there is a genuine need -- in the production code -- for the abstraction that the interface represents. A genuine need means either that we are going to write multiple implementations ourselves, or that we are giving client code the possibility to provide an implementation. If there's only ever going to be one real implementation, I'd stick with a concrete class.

Spring Batch is a good example of a case where programming to interfaces is appropriate: a flexible library, that client code can extend and customise almost without limitation. A service class in a business app, on the other hand, is never going to be exported outside the application, and it's very unlikely that there'll ever be multiple implementations of its API.

Props btw for going to the trouble of writing a stunt double. I've often seen dodgy classes in customers' projects that I've wished I could put in a blog post, if only for the purpose of letting off steam, but I'm too lazy to write stunt doubles. (Or maybe it is just that I can't bring myself to add to the quantity of bad code in the world, even for example purposes. Yes, that must be it.)

Efficient Use of ListView virtual mode

Nov 28, 2011 · Ben Watson

Oh, my goodness. I (and colleagues) have been burnt by so many of the things on your list. I think I shall print out a list of the headings and pin it up by my desk.

Truly excellent article. The material would also make an excellent presentation.

There's one thing I'm not convinced of, which is testing whether foreign keys / default values / constraints are working. Assuming you've put them in the schema in the first place, I'm inclined to trust the database to apply them properly. What I don't trust is my own ability to remember to put them into the schema in the first place.

Consequently, I agree that the schema definition should be checked in some way. But how do you assert the correctness of DDL? I don't mean the syntactic correctness (which can be checked by simply executing it), but the semantic correctness. Should column BLABLA.XYZ be constrained to the values 'X', 'Y' and 'Z'? Should PATIENT_ID be a foreign key to the PERSON table? Etc. These are things that no automatic test can know -- unless you tell it, in which case you're simply repeating the information that's already in the DDL. Such a test tells you whether the test and the DDL agree with each other, but it doesn't tell you whether the both of them agree with you.

The approach I favour is: have a single reference schema, which is inspected for correctness by a human. Then, as part of the automatic build, there should be a check that will fail the build if there are any differences between the target schema and the expected schema. This is the direction we're taking on my current team, though we've still got some way to go.

I'd be interested to hear others' opinions on this approach.

Oracle APEX Builder Plugin v1.7 release!

Nov 01, 2011 · Patrick Wolf

Whilst I approve of nearly all the recommendations above, if there can be only one, then it has to be The Pragmatic Programmer. It's the foundation text for the profession of programming.
Using Bitwise XOR to exchange variable values in ActionScript

Oct 21, 2011 · Gerd Storm

The DRY principle doesn't exactly state "it’s better to create a convoluted abstraction than to write different-but-very-similar code twice". Rather, the principle is that every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

Aside from that nitpick, and notwithstanding the disagreements from previous commenters, this article makes a worthwhile point, namely, that automation and removing redundancies often require abstraction, and abstraction can be deleterious.

2D Fast Wavelet Transform Library for Image Processing

Sep 25, 2011 · Gerd Storm

Your arguments are persuasive. To my mind, the key to a unit test - for whatever definition of "unit" - is that if the test fails it should fail due to an error inside and not outside the unit. Tests are a tool not only for detecting that an error exists, but also for locating it. I wrote about this (from a Java perspective) a little while ago here on DZone.

A corollary to your suggested "building-an-onion" style of testing is that, if a unit depends on another unit, its test should depend on that other unit's test. In the event of failure in a low-level class, the build would skip tests of dependent classes, which might give false positives (is a test failure a "positive" or a "negative"?).

This would avoid the distracting situation where you make 1 mistake in a low-level class and suddenly you get 5 or 10 test failures in completely different layers (not to mention in the integration tests).

On your other point, it's funny but it had never occurred to me that mock generators were an artefact of using a statically-typed language...

Master the ‘Run As’ option in Eclipse PDT with PHP

Aug 26, 2011 · Aaron Saray

Where I'm sitting, a text edit in a JSP, or a single-line change in Java source (without changes to class structure) requires a restart of Tomcat. Granted, it saves rebuilding the project in Maven every time, but it still costs close to a minute each time on my current project, which leaves plenty of room for improvement.

Anyway, that's off topic. Thanks for the article, Felipe. Something I would like to read is a balanced critique of Play!. It has made many choices that are radically different from standard JEE, and the approach is almost diametrically opposed to Vaadin (the most extreme example I know of hiding the web from developers). I wonder what are the advantages and pitfalls of Play!'s approach.

jQuery Inline Search Plugin

Aug 23, 2011 · Mr B Loid

Tom,a decade ago it would have been reasonable to argue that you can't test a class in isolation. But these days, at least in my field, developers are expected to know how avoid hardwiring dependencies.

I totally agree that testing a class in isolation isn't enough - even in the non critical systems I develop - and that you also need to test how classes interact. I call that integration testing, though the term's too broad and I'd be happy to accept a more precise taxonomy.

There's a danger here of confusion between a discussion about what kinds testing one should do, with a discussion about what one means by a term such as unit testing. This has led previous commenters to talk at cross purposes. Stating that unit testing means testing only one class at a time, is not the same as arguing that integration tests are superfluous. Are you certain you're not tilting at windmills?

Really Simple History now live at Google Code

Jul 04, 2011 · Amy Russell

I've worked on legacy code and enjoyed reading your article.

A factor that progressively slows down development, which you didn't mention, is that programmers sometimes leave and are replaced by other programmers. The author of poorly structured, non unit-tested code can anticipate side effects, far better than a programmer unfamiliar with the code can do. When code is well-structured and unit-tested, the difference in velocity between these two programmers is much smaller.

Thus, good design and unit tests mitigate the consequences of losing knowledge when programmers leave.

I think that managers underestimate how much development is slowed down when a programmer who has lived through the development of a project leaves, and somebody else needs to be brought in during the maintenance phase (the typical scenario). They may understand that we need time to learn the application, but they don't see the time that is lost elsewhere (as you described): more code/deploy cycles, increased number of bugs in QA, increased number of bugs in production... These losses are much greater than the extra time taken simply for coding.

As long as managers underestimate this phenomenon, they'll also underestimate the value of unit tests and careful design. (I am assuming programmer turnover is inevitable, and thinking about mitigating its effects. But reducing turnover in the first place should probably be an even higher management priority.)

Zend_Pdf tutorial

May 15, 2011 · Cal Evans

Ha. Good observation about comments. I didn't mention them because I'm not sure what is best; I suppose that if you expect all future developers to be Xophone, then you should comment in X. Otherwise, in English.

What I have observed in a 100% Francophone environment is that comments are almost always in French even when the code is partly or wholly in English. Though that's probably more to do with ease of writing, than with consideration for the future maintenance programmer. It's harder to write comments in a foreign language, than it is to name variables.

Zend_Pdf tutorial

May 15, 2011 · Cal Evans

Ha. Good observation about comments. I didn't mention them because I'm not sure what is best; I suppose that if you expect all future developers to be Xophone, then you should comment in X. Otherwise, in English.

What I have observed in a 100% Francophone environment is that comments are almost always in French even when the code is partly or wholly in English. Though that's probably more to do with ease of writing, than with consideration for the future maintenance programmer. It's harder to write comments in a foreign language, than it is to name variables.

Zend_Pdf tutorial

May 15, 2011 · Cal Evans

Ha. Good observation about comments. I didn't mention them because I'm not sure what is best; I suppose that if you expect all future developers to be Xophone, then you should comment in X. Otherwise, in English.

What I have observed in a 100% Francophone environment is that comments are almost always in French even when the code is partly or wholly in English. Though that's probably more to do with ease of writing, than with consideration for the future maintenance programmer. It's harder to write comments in a foreign language, than it is to name variables.

Zend_Pdf tutorial

May 15, 2011 · Cal Evans

Ha. Good observation about comments. I didn't mention them because I'm not sure what is best; I suppose that if you expect all future developers to be Xophone, then you should comment in X. Otherwise, in English.

What I have observed in a 100% Francophone environment is that comments are almost always in French even when the code is partly or wholly in English. Though that's probably more to do with ease of writing, than with consideration for the future maintenance programmer. It's harder to write comments in a foreign language, than it is to name variables.

Zend_Pdf tutorial

May 12, 2011 · Cal Evans

Thanks.

I had a comment on my blog (same article) from a guy in Germany who said he would always write in English. It got me to thinking that there might be some countries (Germany, Netherlands, Nordic countries) where most programmers' English is good enough to do that. Not in France, though, nor in French-speaking Switzerland.

I'm not sure that the article makes it clear that I'm not talking about multi-national environments, nor software aimed at the world market. I'm more thinking of custom-build enterprise software.

Zend_Pdf tutorial

May 12, 2011 · Cal Evans

Thanks.

I had a comment on my blog (same article) from a guy in Germany who said he would always write in English. It got me to thinking that there might be some countries (Germany, Netherlands, Nordic countries) where most programmers' English is good enough to do that. Not in France, though, nor in French-speaking Switzerland.

I'm not sure that the article makes it clear that I'm not talking about multi-national environments, nor software aimed at the world market. I'm more thinking of custom-build enterprise software.

Zend_Pdf tutorial

May 12, 2011 · Cal Evans

Thanks.

I had a comment on my blog (same article) from a guy in Germany who said he would always write in English. It got me to thinking that there might be some countries (Germany, Netherlands, Nordic countries) where most programmers' English is good enough to do that. Not in France, though, nor in French-speaking Switzerland.

I'm not sure that the article makes it clear that I'm not talking about multi-national environments, nor software aimed at the world market. I'm more thinking of custom-build enterprise software.

NetBeans Ruby in Review

May 10, 2011 · Mr B Loid

Yup - see also The Law of Leaky Abstractions (and bearing in mind that ORM tools are particularly leaky)
Rendering Quotes With CSS

Mar 31, 2011 · Mr B Loid

Excellent idea to use familiar OO code snippets to introduce functional concepts to OO programmers.

It's much easier to start from something we already know, generalise the concept, and give it a label, than it is to start from a label which we don't recognise, describe the concept (which forces us to begin by understanding the abstract, general case), and only then give examples.

Authenticated rss proxy (with Ruby)

Feb 28, 2011 · Gerd Storm

There is an excellent package called Dozer that does all BeanUtils does and more. It's simple to use and easy to customise. I recommend it highly.
Creating a Copy of JavaBeans

Feb 28, 2011 · James Sugrue

There is an excellent package called Dozer that does all BeanUtils does and more. It's simple to use and easy to customise. I recommend it highly.
JEuclid 3.0, MathML rendering solution, released

Feb 17, 2011 · Gerd Storm

@Fuzail Sarang

Ah... I see what you mean, but I'm not convinced that it is useful nor practical to leave the database in a clean state after each test. It is much more reliable to have a setup fixture that can get the database into the required state, no matter what state it starts off in. Keeping the post-test state is also useful for diagnosing failed tests (cf DBUnit's "Best pratice" page).

To put it another way, I think it unwise to start with step 1, and prefer to perform step 4 at the start of each test.

JEuclid 3.0, MathML rendering solution, released

Feb 17, 2011 · Gerd Storm

@Fuzail Sarang

Ah... I see what you mean, but I'm not convinced that it is useful nor practical to leave the database in a clean state after each test. It is much more reliable to have a setup fixture that can get the database into the required state, no matter what state it starts off in. Keeping the post-test state is also useful for diagnosing failed tests (cf DBUnit's "Best pratice" page).

To put it another way, I think it unwise to start with step 1, and prefer to perform step 4 at the start of each test.

JEuclid 3.0, MathML rendering solution, released

Feb 17, 2011 · Gerd Storm

@Fuzail Sarang

Ah... I see what you mean, but I'm not convinced that it is useful nor practical to leave the database in a clean state after each test. It is much more reliable to have a setup fixture that can get the database into the required state, no matter what state it starts off in. Keeping the post-test state is also useful for diagnosing failed tests (cf DBUnit's "Best pratice" page).

To put it another way, I think it unwise to start with step 1, and prefer to perform step 4 at the start of each test.

Solve Foreign-key Problems in DBUnit Test Data

Feb 17, 2011 · James Sugrue

@Fuzail Sarang

Ah... I see what you mean, but I'm not convinced that it is useful nor practical to leave the database in a clean state after each test. It is much more reliable to have a setup fixture that can get the database into the required state, no matter what state it starts off in. Keeping the post-test state is also useful for diagnosing failed tests (cf DBUnit's "Best pratice" page).

To put it another way, I think it unwise to start with step 1, and prefer to perform step 4 at the start of each test.

Solve Foreign-key Problems in DBUnit Test Data

Feb 17, 2011 · James Sugrue

@Fuzail Sarang

Ah... I see what you mean, but I'm not convinced that it is useful nor practical to leave the database in a clean state after each test. It is much more reliable to have a setup fixture that can get the database into the required state, no matter what state it starts off in. Keeping the post-test state is also useful for diagnosing failed tests (cf DBUnit's "Best pratice" page).

To put it another way, I think it unwise to start with step 1, and prefer to perform step 4 at the start of each test.

Solve Foreign-key Problems in DBUnit Test Data

Feb 17, 2011 · James Sugrue

@Fuzail Sarang

Ah... I see what you mean, but I'm not convinced that it is useful nor practical to leave the database in a clean state after each test. It is much more reliable to have a setup fixture that can get the database into the required state, no matter what state it starts off in. Keeping the post-test state is also useful for diagnosing failed tests (cf DBUnit's "Best pratice" page).

To put it another way, I think it unwise to start with step 1, and prefer to perform step 4 at the start of each test.

JEuclid 3.0, MathML rendering solution, released

Feb 17, 2011 · Gerd Storm

@Roger Lindsjö, Chad Retz

Thanks for the tips for disabling constraints in Oracle and SQL Server. I'm thinking this might be a cleaner option than my suggestion, and I'll give it a try on my next project. As long as the constraints are activated before the start of the test, and all constraints checked on reactivation, it'd be safe to do that.

JEuclid 3.0, MathML rendering solution, released

Feb 17, 2011 · Gerd Storm

@Roger Lindsjö, Chad Retz

Thanks for the tips for disabling constraints in Oracle and SQL Server. I'm thinking this might be a cleaner option than my suggestion, and I'll give it a try on my next project. As long as the constraints are activated before the start of the test, and all constraints checked on reactivation, it'd be safe to do that.

JEuclid 3.0, MathML rendering solution, released

Feb 17, 2011 · Gerd Storm

@Roger Lindsjö, Chad Retz

Thanks for the tips for disabling constraints in Oracle and SQL Server. I'm thinking this might be a cleaner option than my suggestion, and I'll give it a try on my next project. As long as the constraints are activated before the start of the test, and all constraints checked on reactivation, it'd be safe to do that.

JEuclid 3.0, MathML rendering solution, released

Feb 17, 2011 · Gerd Storm

@Roger Lindsjö, Chad Retz

Thanks for the tips for disabling constraints in Oracle and SQL Server. I'm thinking this might be a cleaner option than my suggestion, and I'll give it a try on my next project. As long as the constraints are activated before the start of the test, and all constraints checked on reactivation, it'd be safe to do that.

JEuclid 3.0, MathML rendering solution, released

Feb 17, 2011 · Gerd Storm

@Roger Lindsjö, Chad Retz

Thanks for the tips for disabling constraints in Oracle and SQL Server. I'm thinking this might be a cleaner option than my suggestion, and I'll give it a try on my next project. As long as the constraints are activated before the start of the test, and all constraints checked on reactivation, it'd be safe to do that.

JEuclid 3.0, MathML rendering solution, released

Feb 17, 2011 · Gerd Storm

@Roger Lindsjö, Chad Retz

Thanks for the tips for disabling constraints in Oracle and SQL Server. I'm thinking this might be a cleaner option than my suggestion, and I'll give it a try on my next project. As long as the constraints are activated before the start of the test, and all constraints checked on reactivation, it'd be safe to do that.

JEuclid 3.0, MathML rendering solution, released

Feb 17, 2011 · Gerd Storm

@Roger Lindsjö, Chad Retz

Thanks for the tips for disabling constraints in Oracle and SQL Server. I'm thinking this might be a cleaner option than my suggestion, and I'll give it a try on my next project. As long as the constraints are activated before the start of the test, and all constraints checked on reactivation, it'd be safe to do that.

Solve Foreign-key Problems in DBUnit Test Data

Feb 17, 2011 · James Sugrue

@Roger Lindsjö, Chad Retz

Thanks for the tips for disabling constraints in Oracle and SQL Server. I'm thinking this might be a cleaner option than my suggestion, and I'll give it a try on my next project. As long as the constraints are activated before the start of the test, and all constraints checked on reactivation, it'd be safe to do that.

Solve Foreign-key Problems in DBUnit Test Data

Feb 17, 2011 · James Sugrue

@Roger Lindsjö, Chad Retz

Thanks for the tips for disabling constraints in Oracle and SQL Server. I'm thinking this might be a cleaner option than my suggestion, and I'll give it a try on my next project. As long as the constraints are activated before the start of the test, and all constraints checked on reactivation, it'd be safe to do that.

Solve Foreign-key Problems in DBUnit Test Data

Feb 17, 2011 · James Sugrue

@Roger Lindsjö, Chad Retz

Thanks for the tips for disabling constraints in Oracle and SQL Server. I'm thinking this might be a cleaner option than my suggestion, and I'll give it a try on my next project. As long as the constraints are activated before the start of the test, and all constraints checked on reactivation, it'd be safe to do that.

Solve Foreign-key Problems in DBUnit Test Data

Feb 17, 2011 · James Sugrue

@Roger Lindsjö, Chad Retz

Thanks for the tips for disabling constraints in Oracle and SQL Server. I'm thinking this might be a cleaner option than my suggestion, and I'll give it a try on my next project. As long as the constraints are activated before the start of the test, and all constraints checked on reactivation, it'd be safe to do that.

Solve Foreign-key Problems in DBUnit Test Data

Feb 17, 2011 · James Sugrue

@Roger Lindsjö, Chad Retz

Thanks for the tips for disabling constraints in Oracle and SQL Server. I'm thinking this might be a cleaner option than my suggestion, and I'll give it a try on my next project. As long as the constraints are activated before the start of the test, and all constraints checked on reactivation, it'd be safe to do that.

Solve Foreign-key Problems in DBUnit Test Data

Feb 17, 2011 · James Sugrue

@Roger Lindsjö, Chad Retz

Thanks for the tips for disabling constraints in Oracle and SQL Server. I'm thinking this might be a cleaner option than my suggestion, and I'll give it a try on my next project. As long as the constraints are activated before the start of the test, and all constraints checked on reactivation, it'd be safe to do that.

Solve Foreign-key Problems in DBUnit Test Data

Feb 17, 2011 · James Sugrue

@Roger Lindsjö, Chad Retz

Thanks for the tips for disabling constraints in Oracle and SQL Server. I'm thinking this might be a cleaner option than my suggestion, and I'll give it a try on my next project. As long as the constraints are activated before the start of the test, and all constraints checked on reactivation, it'd be safe to do that.

JEuclid 3.0, MathML rendering solution, released

Feb 16, 2011 · Gerd Storm

@Mladen Girazovski
Thanks for the link. I like this approach, the only downside is that XML embedded in Java isn't very pretty - the ideal would be a Java-based format (DSL?). As I understand, this technique is complementary to the DTD-based clean operation.

@Kim Eeckhout
I saw that some people did that. It's more flexible because you don't have to worry either about the order of tables in your test data. The disadvantage is that it's database specific. We use Oracle and I don't think you can even do that in Oracle (though I could be wrong; I am not a DBA).

Solve Foreign-key Problems in DBUnit Test Data

Feb 16, 2011 · James Sugrue

@Mladen Girazovski
Thanks for the link. I like this approach, the only downside is that XML embedded in Java isn't very pretty - the ideal would be a Java-based format (DSL?). As I understand, this technique is complementary to the DTD-based clean operation.

@Kim Eeckhout
I saw that some people did that. It's more flexible because you don't have to worry either about the order of tables in your test data. The disadvantage is that it's database specific. We use Oracle and I don't think you can even do that in Oracle (though I could be wrong; I am not a DBA).

How easy maintenance will improve performance

Feb 14, 2011 · Tony Thomas

The main reason Java achieved those things was the control Sun had over the technology: a single language specification, a single set of standard libraries and a single spec for the runtime environment.

It'll be years before we can get anything similar for Javascript, because even if a standard is agreed tomorrow (which it won't be), we won't be able to benefit from it until most users have stopped using the non-standards-respecting browsers. You only need to look at IE 6 to realise how long that can take...

A Sequence Diagram for Scriptaculous

Feb 11, 2011 · Amy Russell

The Maven doc says (I haven't tried it myself) that you need to put "env.SETTINGS" rather than just "SETTINGS" to access an environment variable. Alternatively, you could keep your POM as it is, and supply the variable as a java system property: mvn -DSETTINGS=/path/to/file ... (though by convention, Java system properties are usually lower-case).

I can never get the code formatting right on here either.

A Sequence Diagram for Scriptaculous

Feb 11, 2011 · Amy Russell

The Maven doc says (I haven't tried it myself) that you need to put "env.SETTINGS" rather than just "SETTINGS" to access an environment variable. Alternatively, you could keep your POM as it is, and supply the variable as a java system property: mvn -DSETTINGS=/path/to/file ... (though by convention, Java system properties are usually lower-case).

I can never get the code formatting right on here either.

A Sequence Diagram for Scriptaculous

Feb 11, 2011 · Amy Russell

The Maven doc says (I haven't tried it myself) that you need to put "env.SETTINGS" rather than just "SETTINGS" to access an environment variable. Alternatively, you could keep your POM as it is, and supply the variable as a java system property: mvn -DSETTINGS=/path/to/file ... (though by convention, Java system properties are usually lower-case).

I can never get the code formatting right on here either.

A Sequence Diagram for Scriptaculous

Feb 11, 2011 · Amy Russell

The Maven doc says (I haven't tried it myself) that you need to put "env.SETTINGS" rather than just "SETTINGS" to access an environment variable. Alternatively, you could keep your POM as it is, and supply the variable as a java system property: mvn -DSETTINGS=/path/to/file ... (though by convention, Java system properties are usually lower-case).

I can never get the code formatting right on here either.

Maven Profile Best Practices

Feb 11, 2011 · Andrew Spencer

The Maven doc says (I haven't tried it myself) that you need to put "env.SETTINGS" rather than just "SETTINGS" to access an environment variable. Alternatively, you could keep your POM as it is, and supply the variable as a java system property: mvn -DSETTINGS=/path/to/file ... (though by convention, Java system properties are usually lower-case).

I can never get the code formatting right on here either.

Maven Profile Best Practices

Feb 11, 2011 · Andrew Spencer

The Maven doc says (I haven't tried it myself) that you need to put "env.SETTINGS" rather than just "SETTINGS" to access an environment variable. Alternatively, you could keep your POM as it is, and supply the variable as a java system property: mvn -DSETTINGS=/path/to/file ... (though by convention, Java system properties are usually lower-case).

I can never get the code formatting right on here either.

Maven Profile Best Practices

Feb 11, 2011 · Andrew Spencer

The Maven doc says (I haven't tried it myself) that you need to put "env.SETTINGS" rather than just "SETTINGS" to access an environment variable. Alternatively, you could keep your POM as it is, and supply the variable as a java system property: mvn -DSETTINGS=/path/to/file ... (though by convention, Java system properties are usually lower-case).

I can never get the code formatting right on here either.

Maven Profile Best Practices

Feb 11, 2011 · Andrew Spencer

The Maven doc says (I haven't tried it myself) that you need to put "env.SETTINGS" rather than just "SETTINGS" to access an environment variable. Alternatively, you could keep your POM as it is, and supply the variable as a java system property: mvn -DSETTINGS=/path/to/file ... (though by convention, Java system properties are usually lower-case).

I can never get the code formatting right on here either.

Generics in Java 5.0

Feb 08, 2011 · Krishna Srinivasan

Héctor, thanks for the link. That article chiefly describes a style of TDD where mock objects are used to drive the design of the system's classes. The authors state that mocks are useful for isolating code from external dependencies (3rd party libraries), as I described, but they see that as only a secondary use.

What they describe is a way of working, that goes beyond what I've written. I like their approach and it is complementary to my suggestions above. However, not everyone will choose to work that way, whereas I've tried to outline principles that will be valid for anyone doing unit testing.

Generics in Java 5.0

Feb 08, 2011 · Krishna Srinivasan

Héctor, thanks for the link. That article chiefly describes a style of TDD where mock objects are used to drive the design of the system's classes. The authors state that mocks are useful for isolating code from external dependencies (3rd party libraries), as I described, but they see that as only a secondary use.

What they describe is a way of working, that goes beyond what I've written. I like their approach and it is complementary to my suggestions above. However, not everyone will choose to work that way, whereas I've tried to outline principles that will be valid for anyone doing unit testing.

Generics in Java 5.0

Feb 08, 2011 · Krishna Srinivasan

Héctor, thanks for the link. That article chiefly describes a style of TDD where mock objects are used to drive the design of the system's classes. The authors state that mocks are useful for isolating code from external dependencies (3rd party libraries), as I described, but they see that as only a secondary use.

What they describe is a way of working, that goes beyond what I've written. I like their approach and it is complementary to my suggestions above. However, not everyone will choose to work that way, whereas I've tried to outline principles that will be valid for anyone doing unit testing.

Generics in Java 5.0

Feb 08, 2011 · Krishna Srinivasan

Héctor, thanks for the link. That article chiefly describes a style of TDD where mock objects are used to drive the design of the system's classes. The authors state that mocks are useful for isolating code from external dependencies (3rd party libraries), as I described, but they see that as only a secondary use.

What they describe is a way of working, that goes beyond what I've written. I like their approach and it is complementary to my suggestions above. However, not everyone will choose to work that way, whereas I've tried to outline principles that will be valid for anyone doing unit testing.

Generics in Java 5.0

Feb 08, 2011 · Krishna Srinivasan

Nicolas, I take your point but I'm still more inclined to agree with what Rogerio said. However, I do very much like the conciseness of the code in his "tourdemock" Spring mock example. (It isn't actually all that concise because he uses hand-built mocks for the non-Spring-provided mock objects, but it would have been had he used a combination of Spring Mocks and Mockito.)
Generics in Java 5.0

Feb 08, 2011 · Krishna Srinivasan

Nicolas, I take your point but I'm still more inclined to agree with what Rogerio said. However, I do very much like the conciseness of the code in his "tourdemock" Spring mock example. (It isn't actually all that concise because he uses hand-built mocks for the non-Spring-provided mock objects, but it would have been had he used a combination of Spring Mocks and Mockito.)
Generics in Java 5.0

Feb 08, 2011 · Krishna Srinivasan

Thanks for your corrections. I've redrafted several sentences to correct and/or clarify points 1-3. I can't really correct points 4 and 5 without major surgery, so I've made do with a footnote.
Generics in Java 5.0

Feb 08, 2011 · Krishna Srinivasan

Thanks for your corrections. I've redrafted several sentences to correct and/or clarify points 1-3. I can't really correct points 4 and 5 without major surgery, so I've made do with a footnote.
Generics in Java 5.0

Feb 08, 2011 · Krishna Srinivasan

Thanks for your corrections. I've redrafted several sentences to correct and/or clarify points 1-3. I can't really correct points 4 and 5 without major surgery, so I've made do with a footnote.
Generics in Java 5.0

Feb 08, 2011 · Krishna Srinivasan

Thanks for your corrections. I've redrafted several sentences to correct and/or clarify points 1-3. I can't really correct points 4 and 5 without major surgery, so I've made do with a footnote.
MySQL Optimization - A Little Tip

Jan 19, 2011 · Binny V A

I second the recommation for "Javascript: The Good Parts". A jewel of a programming book. Essential reading for any Java developer who finds themself begrudgingly writing Javascript.
Wally, the ever resourceful co-worker (Dilbert strip)

Jan 05, 2011 · Kirill Grouchnikov

silly me, thanks for the correction.
Wally, the ever resourceful co-worker (Dilbert strip)

Jan 05, 2011 · Kirill Grouchnikov

silly me, thanks for the correction.
Wally, the ever resourceful co-worker (Dilbert strip)

Jan 05, 2011 · Kirill Grouchnikov

silly me, thanks for the correction.
Wally, the ever resourceful co-worker (Dilbert strip)

Jan 05, 2011 · Kirill Grouchnikov

silly me, thanks for the correction.
Wally, the ever resourceful co-worker (Dilbert strip)

Jan 05, 2011 · Kirill Grouchnikov

silly me, thanks for the correction.
Wally, the ever resourceful co-worker (Dilbert strip)

Jan 05, 2011 · Kirill Grouchnikov

silly me, thanks for the correction.
Wally, the ever resourceful co-worker (Dilbert strip)

Jan 05, 2011 · Kirill Grouchnikov

silly me, thanks for the correction.
Wally, the ever resourceful co-worker (Dilbert strip)

Jan 05, 2011 · Kirill Grouchnikov

silly me, thanks for the correction.
Wally, the ever resourceful co-worker (Dilbert strip)

Jan 05, 2011 · Kirill Grouchnikov

silly me, thanks for the correction.
Wally, the ever resourceful co-worker (Dilbert strip)

Jan 04, 2011 · Kirill Grouchnikov

I've had that problem with entities disappearing from Sets and (because I am obtuse and looked in the wrong places) spent ages looking for the source of the bug.

The requirement that objects in a Set have unchanging values for equals() and hashCode() is little known IMO, even though it's in the Javadoc: "Note: Great care must be exercised if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set." And self-evident when you think for a second about how a hashtable works. But I'm embarrassed to admit I wasn't aware of it.

Incidentally, Effective Java doesn't seem to mention this particular pitfall.

Essentially, it means that you should only put immutable objects into a Set, since

  • if you put mutable objects into a set, someday someone who doesn't know about the issue will modify one of the objects and set off a nasty bug;
  • if you make immutable those fields used to calculate equals() and hashCode(), but not the other fields, someday someone will change the implementation of equals() or hashCode() without realising the implications and, again, set off a nasty bug.

Unfortunately you can't use immutable fields with Hibernate entities, since even if (like the application-generated UUID) they are conceptually immutable, Hibernate needs a setter method to be able to restitute them from the database.

Consequently, if you ever put Hibernate entities into a Set, there's no way to circumvent the risk of a bug. I'd be interested to know if anyone else has come to the same conclusion.

Making Eclipse Plug-ins using JRuby or Groovy

Dec 02, 2010 · Mr B Loid

It's been a pleasure reading this discussion.

I would like to add Vaadin to the list of UI frameworks, as an example of a framework that operates in terms of interfaces but provides an abstract class which virtually all components extend in practice.

I haven't the experience with framework design to know which approach least constrains framework evolution. But as a user of UI (or any other kind of) frameworks, I prefer them to define interfaces, since it is easier to mock interfaces for testing. (That goes against the principle that one shouldn't modify one's code to make it testable, but I don't really agree with that principle anyway.)

Embedding GoogleMaps into JMatter

Nov 15, 2010 · Andres Almiray

I prefer to dig into the source, when I need to understand some code: it's more reliable. That's why I place a relatively low importance on comments, and more importantly, a very high importance on intention-revealing code. The only time I look at the Javadoc before the source code is with published (i.e. library) code. Not for "public" methods that are, in reality, private to the project in which they occur.

I do agree that you need to know what the method does, which value it returns, etc.; it's just that for the type of class I illustrated, I don't think you need a comment to tell you these things. In other cases - perhaps the type of class you are thinking of - you sometimes need to comment even a private method.

Of course, if enterprise Java were done using object orientation, these classes with no behaviour but only Javabean properties wouldn't exist. But that's another subject.

My post was only intended as a complaint about something that annoyed me, but the replies have made me realise that the lesson is this:
Whether or not a method depends on the method and its context, and is a decision that needs to be made intelligently by the developer. It can't be made by any wizard or quality metric, nor (IMO) by a blanket statement such as "All public API must have Javadoc comments."

Embedding GoogleMaps into JMatter

Nov 15, 2010 · Andres Almiray

I prefer to dig into the source, when I need to understand some code: it's more reliable. That's why I place a relatively low importance on comments, and more importantly, a very high importance on intention-revealing code. The only time I look at the Javadoc before the source code is with published (i.e. library) code. Not for "public" methods that are, in reality, private to the project in which they occur.

I do agree that you need to know what the method does, which value it returns, etc.; it's just that for the type of class I illustrated, I don't think you need a comment to tell you these things. In other cases - perhaps the type of class you are thinking of - you sometimes need to comment even a private method.

Of course, if enterprise Java were done using object orientation, these classes with no behaviour but only Javabean properties wouldn't exist. But that's another subject.

My post was only intended as a complaint about something that annoyed me, but the replies have made me realise that the lesson is this:
Whether or not a method depends on the method and its context, and is a decision that needs to be made intelligently by the developer. It can't be made by any wizard or quality metric, nor (IMO) by a blanket statement such as "All public API must have Javadoc comments."

Embedding GoogleMaps into JMatter

Nov 15, 2010 · Andres Almiray

I prefer to dig into the source, when I need to understand some code: it's more reliable. That's why I place a relatively low importance on comments, and more importantly, a very high importance on intention-revealing code. The only time I look at the Javadoc before the source code is with published (i.e. library) code. Not for "public" methods that are, in reality, private to the project in which they occur.

I do agree that you need to know what the method does, which value it returns, etc.; it's just that for the type of class I illustrated, I don't think you need a comment to tell you these things. In other cases - perhaps the type of class you are thinking of - you sometimes need to comment even a private method.

Of course, if enterprise Java were done using object orientation, these classes with no behaviour but only Javabean properties wouldn't exist. But that's another subject.

My post was only intended as a complaint about something that annoyed me, but the replies have made me realise that the lesson is this:
Whether or not a method depends on the method and its context, and is a decision that needs to be made intelligently by the developer. It can't be made by any wizard or quality metric, nor (IMO) by a blanket statement such as "All public API must have Javadoc comments."

Embedding GoogleMaps into JMatter

Nov 15, 2010 · Andres Almiray

I prefer to dig into the source, when I need to understand some code: it's more reliable. That's why I place a relatively low importance on comments, and more importantly, a very high importance on intention-revealing code. The only time I look at the Javadoc before the source code is with published (i.e. library) code. Not for "public" methods that are, in reality, private to the project in which they occur.

I do agree that you need to know what the method does, which value it returns, etc.; it's just that for the type of class I illustrated, I don't think you need a comment to tell you these things. In other cases - perhaps the type of class you are thinking of - you sometimes need to comment even a private method.

Of course, if enterprise Java were done using object orientation, these classes with no behaviour but only Javabean properties wouldn't exist. But that's another subject.

My post was only intended as a complaint about something that annoyed me, but the replies have made me realise that the lesson is this:
Whether or not a method depends on the method and its context, and is a decision that needs to be made intelligently by the developer. It can't be made by any wizard or quality metric, nor (IMO) by a blanket statement such as "All public API must have Javadoc comments."

Embedding GoogleMaps into JMatter

Nov 15, 2010 · Andres Almiray

@everybody Thanks for all the comments, including -- no, especially -- the ones I don't agree with. :) You made me realise there's quite a lot that can be said about the subject.

@Carlos Hoces "All public, well constructed API must have Javadocs"
I've seen this assertion elsewhere -- including the Sonar rules at the organisation I work in -- and I'd be interested to read a justification for it. I don't adhere to it, though that partly depends on the definition of "public". (The keyword "public" doesn't itself say much about how widely disseminated the code will be.) Here's why.

In the example I quoted, we're talking about a transfer object which is only shared between the service and web layers of the same project. It contains only Javabean accessor methods, no business rules, and the only words in the method names, besides "get" and "set", are application-wide business terms. And while those terms do need defining, it's not clear that this class is the best place to do so (admittedly that depends on context, and in some contexts it might be the right place). So, in this example I don't believe that there's a clear need to provide more than what the method names have already given us.

For code intended to be re-used outside the scope of its own project, I agree that you should usually expect to see some documentation in the Javadoc comments. Even in this case, however, I maintain that a comment that only repeats information coming from the method signature adds no value, and something that adds no value should not be in your code. So: either you need more than the method signature, and you put what's needed in the API comment, or you don't need anything more, and a comment is not justified.

Btw I totally agree with you about preferring verbose to concise code.

@Adam Davis: from an accuracy point of view, you're right, and if the code maintainer uses the IDE's refactoring tool, they'll probably stay accurate even through method renaming. I'm arguing that they're bad because of the processor cycles that they waste in the developer's brain, making the effort to ignore them.

Certainly, this is much less bad than actively misleading information, and if these pointless comments only took up 10% or so of the source code, I wouldn't mind so much. But in the example I gave, there are 6 lines of genuine information (package statement, four properties, closing brace), 18 lines of accessor method (arguably redundant, but we can all agree that Java does require them, unless we use Lombok), ten lines of whitespace (very necessary IMO), for a total of 34 lines that are pulling their weight. The overall source file is 94 lines, if we ignore the sarcastic little comment I added at the bottom, so that's... wait for it... sixty four percent of noise.

OK, I'm being slightly unfair. The class comment does mention that it is not just any Coordonnee, but a coordonnée physique (good luck for guessing what that means), but in any case, it's well over half junk, which is far too much. And to make matters worse, the junk is distributed towards the top of the file.

@Mladen Girazovski and Cosmin Mutu: the language question deserves a discussion all to itself. I'm currently working for public-sector administration that governs an entirely monolingual area and that, in addition, is linguistically self-determining (so I don't have to worry that a higher authority might require it to produce translations of all administrative business into Vulcan, for instance). All development is done on-site or by French-speaking partners.

In these circumstances, I give precedence to the practice of using business vocabulary, which is in French, for all business elements in the code, but sticking to English for purely technical elements. This makes for a bastard mixture of technical words like "set", "get", "forward", with business terms like "Personne", "Adresse", "Medecin". I've tried the alternative, which is to use English translations of all the business terms referred to in the code, but this is far more problematic... I can explain in detail if you would like, but I don't want to bore anyone. :-)

If you were working with a multi-lingual team, or for a multi-lingual organisation, I agree that the code would have to be in English; but in that case, the business vocabulary would probably be in English already.

Btw I'm English myself, although I do worry that living in France might have polluted my English writing style.

XML Serialization

Aug 26, 2010 · Tony Thomas

Good to see the issues discussed without obfuscation or exaggeration. I fear you are only too correct in the final paragraph.
Sneak peeks into the new F# project system, part one

Jul 21, 2010 · Tony Thomas

In reply to the last comment, don't forget to close the input stream, otherwise you'll have a resource leak: private static String readFileAsString(String filePath) throws java.io.IOException{ byte[] buffer = new byte[(int) new File(filePath).length()]; BufferedInputStream f = null; try { f = new BufferedInputStream(new FileInputStream(filePath)); f.read(buffer); } finally { if (f != null) try { f.close(); } catch (IOException ignored) { } } return new String(buffer); }

User has been successfully modified

Failed to modify user

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: