Releasing to Maven Central with Git on Windows

Originally I wanted to write about two problems. I think both were somehow related to interactions between Maven, Git and GPG on my Windows. But because I didn’t document it both on time, things got lost. So this will be only half of the story.

Short version? Don’t mix various gpg on your PATH. If you use Gpg4Win, prefer that one.

Switching to Git

When you start with Git, you’ll probably get lost often even when you get the basic ideas and read those intro manuals. There was no big deal about SVN coming from CSV, but Git is different beast altogether and definitely worth studying. For example, it may happen that your local master branch is ahead of remote master by hundreds of commits (the whole history really), while push is pushing just new commits… And you have no idea what you did first – and I bet there will be more surprises like this. (Little note, for me fetch didn’t work, but the second answer with rebase -p did. Don’t ask, I still have to study it. :-))

With just a few glitches like this I was reasonably afraid of my first release to Maven central with Java Simon on Git repository. But it was much smoother in the end, especially from Maven’s side. Credit to Maven this time, I remember its release plugin throwing bugs at me – and now it did its job with VCS I don’t understand yet.

GPG vs Git’s GPG

The problem I managed to write down is related to the fact, that I had Gpg4Win installed previously (for Maven Central requires signed artifacts) and Git brought another GPG with it too. So this is – obviously – kinda Windows specific.

First I needed to create my new GPG keys for signing artifacts going to Maven central, because for unknown reasons I elegantly deleted the .gnupg directory some time before. So you create the key with:

gpg --gen-key

And then you go to upload it:

gpg --keyserver hkp:// --send-keys 08XXXXXX

And there is this error:

gpg: sending key 081A513E to hkp server
gpg: system error while calling external program: No error
gpg: WARNING: unable to remove tempfile (out) `...\AppData\Local\Temp\gpg-515B3D\tempout.txt': No such file or directory
gpg: no handler for keyserver scheme `hkp'
gpg: keyserver send failed: keyserver error

It sounds like anything but the proper solution – your gpg did not find gpgkeys_* executables in the same directory. You can eventually Google it and there is some StackOverflow question too, but answers are various. This is the first strike of git-bash and my PATH settings. There is /bin/gpg, but you better use gpg from where it is installed:

/c/Program\ Files/GNU/GnuPG/gpg --keyserver hkp:// \
--send-keys 08XXXXXX

Fixing the PATH

Cleanest solution is to prefer Gpg4Win, so just put C:\Program Files\GNU\GnuPG to the first spot of your PATH – or at least anywhere before Git’s bin directory (which is also high on my list to prefer its commands before binaries from GnuWin32). If you have C:\Program Files\GNU\GnuPG\pub on the list too, bump it up as well. Or just check what Gpg4Win put onto your PATH and move that. Sorry for being a bit vague here – this happened to me with gpg.exe in GnuPG directory first, but now I have only gpg2.exe there and gpg.exe in pub sub-directory which was added to the PATH. This seems to be a change since 2.x versions of gpg or Gpg4Win.

You could – of course – just delete or rename /bin/gpg.exe. But after unplanned Git reinstall it would be there again. Proper order in PATH is important anyway, although I too feel much better when there are no colliding binaries.

GPG speaking different languages?

Is your GPG talking to you in native language and you want it English? Simply set LC_MESSAGES=C (Rapid Environment Editor recommended, use User Variables). Alternatively just delete GnuPG/share/locale directory 🙂 seems not to hurt anything.


I believe my other problem was also related to gpg, it was another twist on the PATH problem when running Maven – which uses gpg to sign those artefacts with keys you prepared. So the main advice still applies. Organize your PATH properly, preferably in Windows System Variables, as Git’s bash will translate it into UNIX format just fine. Also with proper system-wide PATH things will run properly in both cmd and bash, unless they are shell specific. For instance mvn clean release should work in both.

Git Bash strikes back? (edit 2014-10-05)

Fixing the path is nice, but not working – unless you run bash without git’s initialization. Try running just bash and check your path with echo $PATH. Then do the same with git bash (the difference is bash –login -i instead of just plain bash command). This sources not only .bashrc from your home, but also your .profile and (and here comes the blow) also c:\Program Files (x86)\Git\etc\profile (or similar depending on your installation). This is the file that does git bash from just plain bash, sets the prompt, etc. But it also adds couple of paths at the head of your original path – namely $HOME/bin, . (current dir), /usr/local/bin, /mingw/bin and /bin (three out of these 5 items don’t even exist in my case).

So yes, this actually renders my previous advice useless – but only for git bash! If you’re using cmd/bash you don’t need to change anything and you still have all your needs on your path in the proper order.

And what can you do about it in git bash? Fixing that global profile seems kinda crude, so you may prefix the PATH in your .profile with GnuPG path (again). Or delete that gpg.exe in git installation (talking about crude measures :-)).

Three years with Java Simon (4)

Today I’d like to cover the rest of my Java Simon story. In the previous posts we talked hardly about the start, but the rest was actually quite quick. With Callbacks, JMX support, JDBC proxy driver and much better design we were ready to release our 2.0 version.

June 23, 2009, Java Simon 2.0, monitoring API, released

There was one major problem with this version – we needed 2 different JDKs to build it. JDBC 3 would not compile against JDK 1.6 because Java 6 required higher version of it – which we didn’t want, so we could use it on application servers without support of newer JDBC. JMX 1.2 shipped with Java 5 – on the other hand – didn’t support features we needed, mostly around MX Beans, returning more types of objects and so on. So JMX was compiled with Java 6. You can imagine the problems we had when we started using Maven as a build (though Maven still is not exclusive build tool for us).

Well… Maven. While I like the idea of it – especially dependency management is truly great – as a build tool it is incredibly in the way unless you read tons of the stuff. Originally I hosted Java Simon on repository, but then Oracle somehow made it more complicated (and malfunction altogether for a while if I recall correctly) and I decided to switch to Maven Central. That was right decision of course, but the pain behind it was just crazy. Unless you have the process mastered it takes a lot of pain to deploy your first software there. However – our clients wanted Maven repo – and I did my best to provide. I learned a lot in the process, but no one will convince me that Maven can’t be MUCH simpler. And deployment on Maven Central is just horribly bureaucratic compared to FTP upload. Guys at Sonatype do their best in support though, they probably have to answer tons of stupid questions (at least for them). After all I complained more about it previously, so let’s just skip the rest with saying that 2.5.0 version was the first on Maven Central – and someone else had to deploy it for me. 3.0.0 was delayed a lot – Maven being 95% of the reason. Now I can release (at least from that computer where release plugin doesn’t throw infamous out of bounds exception without providing reason…) and it is a tremendous relief.

Talking about 3.0.0 – release announcement was here:

Java Simon alive and kicking with 3.0.0 available

As you can read in it the biggest theme was aligning of the Java dependency – now we can build it with JDK 6 only. Aside from that it was rather just a wrap-up of all the changes in 2.x line with some bug fixes reported for 2.5. Talking about bugs and issues – this was maybe the reason why I kept working on Java Simon and eventually made all the changes that slowly but surely shape the library. And this would not be possible without users – and especially active users. Reports were coming more in bursts, often from one reporter for some time. One thing I can say with my head straight up – I was always very prompt to answer and fix where appropriate (mostly they were indeed bugs).

To talk to our users we created Java Simon Google Group shortly after version 1, but this was mostly an announcement tool. Here and there someone new asked the question though – and again, I answered as soon as possible. Luckily, Java Simon is low-profile library, so the traffic was rather negligible. To sum it up – users who had problems were my motor in the end. The main problem probably was that later we had no project to use with Java Simon. There seems to be some chance now at my current job, so I expect more enhancements.

Here and there I still change some method names (some changed in 3.1, next changes will appear in 3.2) – not that I like doing that but I rather name it properly later than never (oh, how I hate broken promises of original Java’s @deprecated!), but otherwise the core seems to be pretty stable for now. But there is still some room for improvements – especially new features:

  1. delivering more useful tools like JDBC proxy driver – that one I particularly like for its simplicity, just add “simon:” in the JDBC URL and have it on the classpath – right now monitoring part comes to my mind, charts, logging, dumps to some history DB, etc.;
  2. providing some neat Callbacks (many things from the point 1 are actually implemented thanks to these);
  3. web console where you can easily read your Simons.

Actually – there should be web console available in our next release (3.2.0) – we acquired new committer from among our users. That’s the true open source community story. 🙂 You can’t even imagine how happy I was about it.

Of course – my life is not only about Java Simon. I have a family, regular job where they’d hardly pay me for Java Simon alone, I like doing music (soon more about it too) and then I just don’t care about Simon for a few weeks, sometimes even months. Though right now I’m just taking a short break before we wrap up that 3.2.0 version – and you’ll hear about it.

More positive take on Maven

Sometimes I start making notes on some topic and it takes me months (or even over a year!) to finish that particular post. But I should not wait with this one. Situation with my Maven expertise isn’t much better than when I wrote what I wrote the last time. I found some more around the same attitude (or even more, no problem) – but also something in defence – right from the people who should know Maven best. And yes, even they agreed with some of the issues (especially on release plugin).

Actually, talking about releasing artifact… right know I’m reading book about Continuous delivery (of software, of course), we’re still long way to get there all the way, but what strikes me is how often automation is mentioned and stressed. And here we are releasing Maven artifacts after reading dozens of points, installing external software (PGP), configuring tons of stuff and eventually failing in many cases (or just giving up). That’s definitely the biggest failure of Maven in my eyes.

But back to the title! Today it’s positive and – shame on me! – here I am spoiling it with all the reiteration of my previous concerns. So what is it that I suddenly like so much about Maven? It’s actually very simple. One thing that Maven really made right was imposing all its rules about project structure on us. Most of our current projects are not really Eclipse anymore, they are Maven projects – and Eclipse understands them, creates all is necessary files – but we don’t check in those.

While Eclipse project is not particular problem for my beloved IntelliJ IDEA (the same I cannot say about Eclipse… well talking about Idea’s project, not Eclipse’s own, of course :-)), using Maven projects in IDEA is just trivial too! And this kind of cooperation is just worth it. Because with Maven, you can go either direction. I just wish the building and all was just as pleasant as is project management.

Honestly… I hate Maven

And I don’t give a damn that I don’t know it good enough. Why “good enough” in Maven is so difficult when it was so easy with Ant? I remember how we came from “make” to Ant for our projects. I remember what we tried with Ant. Sometimes we failed when we wanted too much.

And then I remember trying Maven. The Next Big Thing (was it 2005? sooner?), revolution in builds (and dependency management, and… everything, right?), and probably the next best thing after wheel. So I tried it. Maybe I was one day from our final goal, maybe just an hour. But I eventually gave up. I failed. Maybe I was just plain stupid. Or Maven too smart.

I did my best to forget about it when I was asked to provide Java Simon in some Maven repository. It was pain again. Not just to restructure our modules, but to understand that magic. And deployment. And plugins. And dependencies, tons of documentation. Maybe Maven makes complex things simpler. But Maven also makes simple things complex. And then repository of my choice changed their configuration and I decided to move on to Maven central.

Documentation again, javadoc generation (still have to figure this out), …a lot of learning for such an obvious goal. Because people want everything in Maven repository. Understandably of course. I, too, want our library to be used – Maven is our standard, our salvation.

Yes, I don’t understand Maven. I understand the concept, but I don’t understand why it has to be so complicated when one needs something very simple. Why things just don’t work. The whole infrastructure around Maven is crazy. If something isn’t right with build most of my colleagues just try to ignore the problem because they don’t want to mess with Maven. Yet we use it.

Recently I checked Gradle. It starts where Maven ended. I switched one of my older projects from Ant to Gradle. I had to do these things to do so:

  • switch structure to Maven-like POM-compliant structure.
  • call Ant’s native2ascii target (Gradle has simple facility to do that), because my project have resource bundles in ISO Latin 2.
  • and… that was it!

It was just so much more satisfying. Second step was a bit troublesome, but I was just happy when it all worked and my build file was just a few lines long. I also noticed that Gradle offers not only declarative approach, but you can say what and how you want things done when you need it. Right now I’m not doing any further research, but I know I will carry on with Gradle later when necessary.

Right now I have some Maven work to do. And I’m biased, I know it, I’m also frustrated and it all came to me – and I know that I just hate Maven. Not because it is bad – I actually don’t care. But because it’s everywhere, like a plague, it’s too complex (is parent + six sub-modules so difficult to comprehend? yes, with Maven) and you have to live with it if you want to offer anything that looks like library to other people. And worst of all you have to follow tons of additional rules when you need the stuff hosted somewhere. Maybe it’s necessary evil – but still, evil it is. There is no beauty, there is no elegance, there is just… POM. And XML, of course.