Faster way to java opensource

and the story of how it starts

Vyacheslav Rusakov
9 min readAug 21, 2014

I’m sure many of you have some awesome code to share, but something always stops you. If your problem is how? (no time to learn ***) or why? (motivation) then read on: we will try to fix it! (And even try to go further)

For the most impatient here is a link for a tool.

The story behind

Good frameworks are extractions, not inventions.
DHH — Railsconf 2013 Keynote

It was just another playground project (you know, the one you start to play with something new). Usually such projects live for a few days and dies, but not this one. For some reason, I was very passionate about it, trying more and more of new things, doing more integrations.

At some point it became obvious that codebase is too big for this project and I’m loosing control over it’s parts: integrations developed too fast and in too hacky way (not surprisingly, initially I’m not going to finish it.. it was just a study). The best solution was to stabilize everything with tests.. But I don’t like the idea of working in large unstable codebase (because of possible side effects), so.. I start to open sourcing parts as small libraries with implicit goal to get more experience, before final project publication.

First one

The first one was guice-validator. It came out of simple need to use contracts: I like guava’s Preconditions, but it’s much simpler to annotate method arguments, rather than manually do validation, especially if argument is an object itself and requires validation too.

The entire project consists of only 3 classes (which are mostly adoption of hibernate-validator’s cdi integration module), so it was natural to expect to finish it fast.

But it took more than a week, just because of quality: the main idea of extraction was to have smaller and stable projects I could completely rely on. Why so long? Let’s see:

  • refactoring (no one want to be ashamed of his code right? moreover, beautiful code is always stable code and easy to debug)
  • complete javadocs (with sane assumptions)
  • test everything (required 19 classes, have to read manual completely)
  • gradle build file, which I could use for next libraries (writing a good one means searching for examples, assimilating best practices etc)
  • bintray integration, including adopting build for publishing, fixing artifacts to pass maven central validations, generating certificates (another long story)

As a result:

  • Level up! (many new things known, many things tried!)
  • Start writing (by the way, medium was chosen, because it was the first google result for “hipster blog platform” ☺)
  • Feel satisfaction and library I want and can rely on
  • Have everything to go much faster with the next lib

And here is the first observation:
Would I put the same efforts if it will exist just on my hard drive?
Of course, no!
Would I know so many things (even about hibernate-validator)?
Maybe, not so much.. not so fast..

So, by open sourcing something: you make yourself better and it force you to write better code.

Next steps

The next library was guice-ext-annotations. It came out of need for @Log annotation and jsr-250 @PostConstruct and @PreDestroy annotations (I know it’s spring way and not guice one, but in some rare cases they can be helpful.. any rule has an exception).

This one was hard to start. There are already many libraries for doing the same thing, just to name a few:

  • GuiceyFruit — looks abandoned (since 2009)
  • Lifegycle — incompatible with guice 4 and most likely abandoned (since 2012). But ideas were great and was used for my implementation.
  • Mycila guice extensions — very good library, but contains some additional dependencies I want to avoid.
  • Governator — too complicated for my needs (especially start with two injectors)

At the end, I want something lightweight and need to put somewhere logs injection support, so decided new library deserve to appear.

The nice thing about resulted code was spring-like post processor abstractions. Again, there were no any clue for them in originally extracted code. It appears just because of refactorings before publication. Thanks to opensource for forcing me to pay more attention and care to code.

You may ask:
Why so many details?
To tell the story and to note one important thing:
do not write something already written without real need.

source: xkcd

The final one (for now) was guice-persist-orient.

I’m tired of hibernate. It’s a very good framework, but it exists only because of paradigm mismatch, so why not use something more natural, like object databases.
OrientDB is the best opensource object database I know and it can be used as document and graph db (always want to write something with graphs). There is jdbc driver, but it’s not what I want from object db — native api’s are much more interesting. Besides, I want to get benefits from all three kinds of db at the same time, so…

source

Guice-persist was obvious choice for integration. Dynamic finders was really interesting finding: they are not mentioned in docs, and I found them only when looked sources.
Implementing dynamic finders was also very interesting task.

Overall work on this library took more than a month, but it let me knew many new things about orient. The hardest thing was uncertainty: I wasn't sure the main idea will work: the more I learned orient, the more I think about potential mismatches. Tests come to rescue: it‘s’ so easy to write a test to check assumption rather than thinking about possibilities. Few of such experimental tests even survive to final tests suit.

You see, open sourcing of library always bring the same benefits over and over again. Moreover, it changes completely initial shy attempt to do something into mature feature rich library (or at least stable one).

Hmm.. something can be better

Writing libraries is fun, but starting new one includes boring step of copying project files from previous project with slight modifications (project name, version, description, tags etc). There are always chance to forget something. What is worse, when, during development, you improve build, you have to copy-paste these changes to previous projects.. not fun at all.

What programmers did when they face boring repeating tasks?
Correct! They automate it.

So I did a generator to quickly setup new projects and update old one.
Obvious way was to use maven archetype.. but writing maven archetype is more trouble than it should be (not complex at all, but boring). Also, archetype usage is not very comfortable and “why maven if I’m using gradle?”.. Besides, growing popularity of yeoman whispering “try me!”.

In spite of the fact, that yeoman is good, i want something simpler, so I choose slushgulp based yeoman alternative. All you need to know there is gulp (which is just a few commands).

And again, the power of open source: initial generator was written in few hours and it did exactly what i want — prepare new project in seconds. But I know that both gradle build and generator itself could be better! It’s hard to know that about opensource project and this drive development further. I can say that I very like the result. All libraries where updated with the new generator and now any improvement to build script could be propagated to other libraries in minutes!
Kowabunga!

The generator.. and thoughts

Generator usage aspects described on project page, so I’d better describe motivation aspects behind it.

Motivation

It will fit your needs if you:

  • Want to start java lib on github, but never did it before.
  • Don’t want to spent time learning how to best configure project build
  • Don’t want to search how and configure project for external services integration (bintray, travis, coveralls).
  • Believe in quality and want to spent time doing things right.

Quality

Quality mean a lot. First of all you need a good design. It’s not what will appear in the first iteration — it’s more like a growing tree: first prototype checks assumptions, then you can improve it here and there, add features and improve again. Eventually design will find it’s place and will be beautiful, just don’t stop until that.
Opensource project is ideal playground for learning design: not so big, but enough to train yourself. At the end, you should be proud of your code.

Another important step to quality is tests. Tests influence design a lot (you should look this great video about testability by Misko Hevery (angularjs author).. very insightful). Moreover, tests make you feel better, gives you certainty. When you write tests you check your code logic assumptions (and some of them will fail!). My own libraries evolve a lot during increase of test coverage (even places I thought were absolutely correct). It’s often hard to write tests, but it worth it, it drive you much further!

Generator creates a very simple spock test to show you how easy is to write tests in “spock” way. Spock tests are more expressive, easy to read, require less code. Definitely worth trying.

Checkstyle is also very helpful for maintaining quality. Sometimes it will drive you mad, but eventually you will understand that every single complain was for a reason and fixing it makes your code much more better.
Included checkstyle config will force you to use final keyword as much as possible (especially with method arguments). It may seem weird or crazy, but try to follow it and you will see that code become better. With final variables you can be sure that it is not changed somewhere. If you can’t mark variable as final it’s a signal that something may be refactored here to get more readable code (usually move part of logic into separate method). Overall, finals force you to write in more functional-like style.

While tests drive your objects design, finals guide your methods design.

Pmd will also help you catch errors and critical design mistakes. Think of it: machine checks code for you! Why not to use it?

In generated readme file you can see predefined badges for travis and coveralls. Just enable your repo on these services and you (and your users) will be much more sure in quality.
Moreover, badges will motivate you to do things better: failed build — fix it fast!, low coverage — increase it! it’s quite exciting to always keep them green — you should try it!

Bintray

Why bintray?
Because it’s jcenter repository is supplement to maven central. More and more packages published there. Bintray users can watch for libraries to be notified about new releases and can post reviews for your library.

Bintray maven central publication is fantastic. You may not use it, but if you do, you can forget about certificates — it will always do signing and publishing for you.

And not so obvious aspect: bintray will publish a notice about your release on root page and this will give you some traffic! (you can see your traffic analysis on github repositry graphs page in traffic section). I never thought about it until I saw my github statistics.

Docs

Write good readme file. At least for yourself: believe me, after some time you will forget about project details and good readme is the best option to recall you all important aspects. Users will appreciate good readme too.

Maintain changelog history — good recall for you and great thing for users.

Use semantic versioning: x.y.z
x — changed in case of incompatable changes (remember recent git 2 release?)
y — changed for new features
z — changed for bugfixes

Semantic version tells you a lot: suppose i’m using 1.1.2
if 1.1.3 released — some bugs fixed
if 1.2.0 released — new features added (looking changelog)
if 2.0.0 released — api changed, I will be careful updating

Summary

Of course, generator is not a silver bullet. It will not make your code great, but should help you do better things faster.
At least, if you still reading, I hope you will think about opensource project quality more and there will be much less projects without tests, without any readme or without homepage link on bintray page (this really makes me angry, because sometimes it’s so hard to search origin).

P.S. if you wondering what about original project? What was it?
I will publish all details when it will be ready.

--

--