Holy on Dev
Where to Get Sample Java Webapps
I was unsuccessfuly looking for some decent, neither too simple nor to complex Java web application for Iterate hackaton "War of Web Frameworks". I want to record the demo apps and options I've found in the case I'll need it ever again. Tips are welcome. What Changes When You Deploy More Frequently and Why You Should Do It
This post is inspired by Kent Beck's excellent talk at JavaZone 2011 titled Software G Forces: The Effects of Acceleration where he describes how the development process, practices and partly the whole organization change and/or have to change as you go from annual to monthly to weekly, daily, hourly deployments. I'd like to summarize some of the points he made and use that as a ground for arguing that more frequent deployments are (in general) better.
I'd highly recommend you to watch his presentation as I will only reproduce parts of it (and as they are out of their original context, they might well not represent exactly what Kent wanted to communicate).
Kent argues that as you deploy more and more frequently, many things have to change including the business side of the software. What is a best practice for one of these speeds becomes an impediment for another one. With more frequent deployments teams have to progress towards the following practices, while leaving some other practices behind:Principles for Creating Maintainable and Evolvable Tests
Having [automated] unit/integration/functional/... tests is great but it is too easy for them to become a hindrance, making any change to the system painful and slow - up to the point where you throw them away. How to avoid this curse of rigid tests, too brittle, too intertwined, too coupled to the implementation details? Surely following the principles of clean code not only for production code but also for tests will help but is it enough? No, it is not. Based on a discussion on our recent course with Kent Beck, I think that the following three principles below are important to have decoupled, easy to evolve tests: - Tests tell a story
- True unit tests + decoupled higher-level integration tests (-> Mike Cohn's Layers of the Test Automation Pyramid)
- More functional composition of the processing
Refactoring Spikes as a Learning Tool and How a Scheduled Git Reset Can Help
To learn how complex your code base really is and how much effort a particular refactoring might require compared to the initial expectations, follow these steps: - Schedule git reset --hard; git clean -fd to run in 1 hour (e.g. via cron)
- Do the refactoring
- "WT*?! All my changes disappeared?!" - this experience indicates the end of the refactoring :-)
- Go for a walk or something and think about what you have learned about the code, its complexity, the refactoring
- Repeat regularly, f. ex. once every week or two - thus you'll improve your ability to direct the refactoring so that you learn as much as possible during the short time
How to Fail With Drools or Any Other Tool/Framework/Library
What I like most at conferences are reports of someone's failure to do or implement something for they're the best sources of learning. And How to Fail with Drools (in Norwegian) by C. Dannevig of Know IT at JavaZone 2011 is one of them. I'd like to summarize what they learned and extend it for introduction of a tool, framework, or library in general based on my own painful experiences.
They decided to switch to the Drools rule management system (a.k.a. JBoss Rules) v.4 from their homegrown rules implementation to centralize all the rules code at one place, to get something simpler and easier to understand, and to improve the time to market by not requiring a redeploy when a rule is added. However Drools turned out to be more of a burden than help for the following reasons:Tips And Resources For Creating DSLs in Groovy
Paul King had a very good presentation (last year's slides) at JavaZone about why to use Domain-Specific Languages and how to create internal DSLs in Groovy. I'd like to list here few tips that he has mentioned but before we get to that, why would you want to create a DSL? Martin Fowler answers that in his Domain-Specific Languages book (2010). Some of the reasons are to have a higher-level, more focused and conscise representation that also domain experts can read and perhaps even write. You have certainly already used a DSL such as regular expressions, CSS, SQL, Spock's BDD tests, build instructions in Gradle - these are rather technical but sometimes DSLs are also created to be used by business users, f.ex. for anti-malaria drug resistance simulation. (Want more DSLs in Groovy?).
Paul mentions one important thing - you can always make your DSL better, i.e. more fail-proof (case insensitive, support plural endings, ...) and secure and more like a natural language but it all comes at a cost and you must evaluate when the cost overweights the benefit (beware the 80:20 rule).
Some of the Groovy DSL implementation tips:What Is CDI, How Does It Relate to @EJB And Spring?
A brief overview of dependency injection in Java EE, the difference between @Resource/@EJB and @Inject, and how does that all relate to Spring - mostly in the form of links.
Context Dependency Injection (CDI, JSR 299) is a part of Java EE 6 Web Profile and itself builds on Dependency Injection for Java (JSR 330), which introduces @Inject, @Named etc. While JSR 330 is for DI only and is implemented e.g. by Guice and Spring, CDI adds various EE stuff such as @RequestScoped, interceptors/decorators, producers, eventing and a base for integration with JSF, EJBs etc. Java EE components such as EJBs have been redefined to build on top of CDI (=> @Stateless is now a CDI managed bean with additional services).
A key part of CDI aside of its DI capabilities is its awarness of bean contexts and the management of bean lifecycle and dependencies within those contexts (such as @RequestScoped or @ConversationScoped).
CDI is extensible - you can define new context scopes, drop-in interceptors and decorators, make other beans (e.g. from Spring) available for CDI,... .
Resources to check:Book Review: Agile Project Management With Scrum
A review of and extract from Agile Project Management With Scrum by Ken Schwaber, Microsoft Press 2003, ISBN 0-7356-1993-X.
The book is basically a set of case studies about Scrum that show how to implement the individual aspects of Scrum, what are the common pitfalls and how to avoid them, and help to understand its mantra of "the art of the possible" and how to adapt Scrum to various situations. It's very easy to read thanks to the case studies being brief and organized by topics (team, product owner, ...). I'd absolutely recommend it as a third book in this domain, after a general introduction into the lean thinking (Implementing Lean Software Development – From Concept to Cash by M. & T. Poppendieck is great for that) and an introduction into Scrum itself. Scrum is not just a set of practices, it requires an essential shift in thinking. Thus it is not enough to learn about the practices - you have to learn, understand, and accept the principles behind. This book will hopefully help you to refine your understanding of these principles.Extract
This extract contains the quotes and observations that I find the most interesting. It tries by no means to be objective or representative, a different person with a different experience and background would certainly pick different ones. Thus its value for others than myself is rather limited but it may perhaps serve as an inspiration to read the book. My all favourite quotes are in italics.Groovy: Creating an Interface Stub and Intercepting All Calls to It
It's sometimes useful for unit testing to be able to create a simple no-op stub of an interface the class under test depends upon and to intercept all calls to the stub, for example to remember all the calls and parameters so that you can later verify that they've been invoked as expected. Often you'd use something like Mockito and its verify method but if you're writing unit tests in Groovy as I recommend then there is a simpler and in a way a more powerful alternative. Groovy: Use @Canonical to Get Compiler-generated Equals, HashCode and ToString
Groovy makes it extremely easy to create Java beans with getters, setters, equals, hashCode, and toString: Most interesting links of October
Recommended Readings
- Steve Yegge's Execution in the Kingdom of Nouns - I guess you've already read this one but if not - it is a well-written and amusing post about why not having functions as first class citizens in Java causes developers to suffer. Highly recommended.
- Reply to Comparing Java Web Frameworks - a very nice and objective response to a recent blog summarizing a JavaOne presentation about the "top 4" web frameworks. The author argues that based on number of resources such as job trends, StackOverflow questions etc. (however data from each of them on its own is biased in a way) JSF is a very popular framework - and rightly so for even though JSF 1 sucked, JSF 2 is really good (and still improving). Interesting links too (such as What's new in JSF 2.2?). Corresponds to my belief that GWT and JSF are some of the best frameworks available.
- Using @Nullable - use javax.annotation.Nullable with Guava's checkNotNull to fail fast when an unexpected null appeares in method arguments
- JavaOne 2011: Migrating Spring Applications to Java EE 6 (slides) - nice (and visually attractive) comparison of JavaEE and Spring and proposal of a migration path. It's fun and worthy to see.
- xUnitPatterns - one of the elementary sources that anybody interested in testing should read through. Not only it explains all the basic concepts (mocks, stubs, fakes,...) but also many pitfalls to avoid (various test smells such as fragile tests due to Data Sensitivity, Behavior Sensitivity, Overspecified Software [due to mocks] etc.), various strategies (such as for fixture setup), and general testing principles. The materials on the site were turned into the book xUnit Test Patterns: Refactoring Test Code (2007), which is more up-to-date and thus a better source.
- Eclipse tip: Automatically insert at correct position: Semicolon, Braces - in "while(|)" type "true {" to get "while(true) {|" i.e. the '{' is moved to the end where it belongs, the same works for ';'
- Google Test Analytics - Now in Open Source - introduces Google's Attributes-Components-Capabilities (ACC) application intended to replace laborous and write&forget test plans with something much more usable and quicker to set up, it's both a methodology for determining what needs to be tested and a tool for doing so and tracking the progress and high-risk areas (based not just on estimates but also actual data such as test coverage and bug count). The article is a good and brief introduction, you may also want to check a live hosted version and a little more detailed explanation on the project's wiki.
- JSF and Facelets: build-time vs. render-time (component) tags (2007) - avoid mixing them incorrectly
- StackOverflow: What are the main disadvantages of Java Server Faces 2.0? Answer: The negative image of JSF comes from 1.x, JSF 2 is very good (and 2.2 is expected to be just perfect :-)). Nice summary and JSF history review.
- Ola Bini: JavaScript in the small - best practices for projects using partly JavaScript - the module pattern (code in the body of an immediately executed function not to polute the global var namespace), handling module dependencies with st. like RequireJS, keeping JS out of HTML, functions generating functions for more readable code, use of many anonymous functions e.g. as a kind of named parameters, testing, open questions.
Talks
- Kent Beck's JavaZone talk Software G Forces: The Effects of Acceleration is absolutely worth the 1h time. Kent describes how the development process, practices and partly the whole organization have to change as you go from annual to monthly to weekly, daily, hourly deployments. What is a best practice for one of these speeds becomes an impediment for another one - so know where you are. You can get an older version of the slides and there is also a detailed summary of the talk from another event.
- Rich Hickey: Simple Made Easy - Rich, the author of Clojure, argues very well that we should primarily care for our tools, constructs and artifacts to be "simple", i.e. with minimal complexity, rather than "easy" i.e. not far from our current understanding and skill set. Simple means minimal interleaving - one concept, one task, one role, minimal mixing of who, what, how, when, where, why. While easy tools may make us start faster, only simplicity will make it possible to keep going fast because (growing) comlexity is the main cause of slowness. And simplicity is a choice - we can create the same programs we do today with the tools of complexity with drastically simpler tools. Rich of course explains what, according to him, are complex tools and their simple(r) alternatives - see below. The start of the 1h talk is little slow but it is worth the time. I agree with him that we should much more thing about the simplicity/complexity of the things we use and create rather than easiness (think ORM). Read also Uncle Bob's affirmative reaction ("All too often we do what’s easy, at the expense of what’s simple. And so we make a mess. [...] doing what is simple as opposed to what is easy is one of the defining characteristics of a software craftsman.").
Random Notes from Rich's Simple Made Easy Talk:
There are also better notes by Alex Baranosky and you may want to check a follow-up discussion with some Rich's answers.JSF: Beware the Difference Between Build-Time and Render-Time Tags in Facelets
This is to remind me that I should never ever forget the cruical difference between build-time-only tags (i.e. having tag handlers only) and render-time tags that have corresponding components. The problem is that their lifespan is different and thus mixing them can easily lead to nasty surprises. Build time tags are used to modify the building of a component tree and have no effect during its rendering, where only the components participate.
A typical mistake is the nesting of ui:include (build-time) inside ui:repeat (render-time) using the var that ui:repeat declares:Never Mix Public and Private Unit Tests! (Decoupling Tests from Implementation Details)
It seems to me that developers often do not really distinguish between the various types of unit tests they should be writing and thus mix things that should not be mixed, leading to difficult to maintain and hard to evolve test code. The dimension of unit test categorization I feel especially important here is the level of coupling to the unit under test and its internals. We should be constantly aware of what kind of test we are writing, what we are trying to achieve with the test, and thus which means are justifiable or, on the contrary, not suitable for that kind of test. In other words, we should always know whether we're writing a Public Test or a Private Test and never ever mix the two. Why not and what actually are these two kinds of tests? Read on! (And if you agree or disagree, don't hesitate to share your opinion.) Hacking A Maven Dependency with Javassist to Fix It
Have you ever wondered what to do when needing "just a small change" to a third-part library your project depended on? This post describes how to use Maven and Javassist to take a dependency of your project, instrument it to modify its behavior, re-pack it, and release it as an artifact with a different name (so that you me depend on my-customized-lib instead of on lib).
The process is as follows:- Phase process-sources - maven-dependency-plugin unpacks the dependency to classes/
- Phase compile (implicit) - compile the bytecode manipulation code
- Phase process-classes - exec-maven-plugin executes the compiled Javassist instrumenter to modify the unpacked classes
- Phase test - run tests on the instrumented code
- Phase package - let maven-jar re-package the instrumented classes, excluding the instrumenter itself
Only a Masochist Would Write Unit Tests in Java. Be Smarter, Use Groovy (or Scala...).
I like writing unit tests but Java doesn't make it particularly easy. Especially if you need to create objects and object trees, transform objects for checking them etc. I miss a lot a conscise, powerful syntax, literals for regular expressions and collections, conscise, clojure-based methods for filtering and transforming collections, asserts providing more visibility into why they failed. But hey, who said I have to write tests in the same language as the production code?! I can use Groovy - with its syntax being ~ 100% Java + like thousand % more, optional usage of static/dynamic typing, closures, hundreds of utility methods added to the standard JDK classes and so on. Groovy support for example in IntelliJ IDEA (autocompletion, refactoring ...) is very good so by using it you loose nothing and gain incredibly much. So I've decided that from now on I'll only use Groovy for unit tests. And so far my experience with it was overwhelmingly positive (though few things are little more complicated by the positives more than compensate for them). Read on to find out why you should try it too.
(The arguments here focus on Groovy but I guess similar things could be said about JRuby, Scala etc. - with the exception of Java code compatibility, which you only get in Groovy.)Few examples
Some of the example below use some Groovy magic but don't be scared. You can write Groovy just as if it was Java and only learn and introduce its magic step by step as you need it.
Bean construction:def testBean = new Customer(fname: "Bob", sname: "Newt", age: 42) // Java: c = new Customer(); c.setFname("Bob"); c.setSname("Newt"); c.setAge(42);
(Of course this starts to pay of if either you don't want to create a constructor or if there are "many" properties and you need to set different subsets of them (constructor with 4+ arguments is hard to read).)
Reading a file:assert test.method() == new File("expected.txt").getText() // Java: buffered reader line by line ...; Note: == actually uses equals()
Checking the content of a collection/map:assert customerFinder.findAll().collect {it.sname}.sort() == ["Lizard","Newt"] // Java: too long to show here (extract only surnames, sort them, compare ...) assert getCapitalsMap() == ["UK" : "London", "CR" : "Prague"]
Regular expressions:assert ("dog1-and-dog2" =~ /dog\d/).getAt([0,1]) == ["dog1", "dog2"]
- Or more fail-safe regexp:
assert ("dog1-and-dog2" =~ /dog\d/).iterator().toSet() == ["dog1", "dog2"].toSet()
- With a match group:
assert ("dog11-and-dog22" =~ /dog(\d+)/).iterator().collect({it[1]}).toSet() == ["11", "22"].toSet()
- Or more fail-safe regexp:
- Previous (14)Next (10)