Yearly Archives: 2016

16 posts

Writing RPM files … in plain Java … on Maven Central

A few weeks back I wrote a blog post about writing RPM files in plain Java.

What was left over was the fact that the library was not available outside of Package Drone itself. Although it was created as a stand alone functionality you would need to fetch the JAR and somehow integrate it into your build.

With the recent release of Package Drone 0.13.0 I was finally able to officially push the module to Maven Central.

[code language=”xml”]
<dependency>
<groupId>org.eclipse.packagedrone</groupId>
<artifactId>org.eclipse.packagedrone.utils.rpm</artifactId>
<version>0.13.0</version>
</dependency>
[/code]

In the meanwhile I did work on a Maven RPM builder plugin, which allows creating RPM files on any platform. The newest version (0.5.0) has been released today as well, which already uses the new library.

So working with RPM files just got a bit easier ;-)

Building RPMs on any platform with Maven

In several occasions I had to build RPM packages for installing software. In the past I mostly did it with a Maven build using the RPM Maven Plugin.

The process is simple: At the end of your build you gather up all resources, try to understand the mapping configuration, bang your head a few times in order to figure out way to work with -SNAPSHOT versions and that’s it. In the end you have a few RPM files.

The only problem is, that the plugin actually creates a spec file and runs the rpmbuild command line tool. Which is, of course, only available on an RPM like system. Fortunately Debian/Ubuntu based distributions, although they use something different, provide at least the rpmbuild tool.

On Windows or Mac OS the situation looks different. Adding rpmbuild to Windows can be quite a task. Still the question remains, why this is necessary since Java can run on all platforms.

So time to write a Maven plugin which does not the rpmbuild tool, but create RPM packages native in Java:

de.dentrassi.maven:rpm is a Maven Plugin which does create RPM packages using plain Java as a Maven Plugin. The process is simply and fast and does not require additional command line tool. The plugin is open source and the source code is available on GitHub ctron/rpm-builder.

Writing RPM files … in plain Java

Now creating an RPM file is easy. There are a lot of tutorials out there on how write a SPEC file and build your RPM. Even when you are using Maven … with the exception that when you are on Windows or Mac OS X, the Maven RPM plugin will still try to invoke rpmbuild in order to actually build the RPM file. The maven bundle simply creates a SPEC file, layout out the payload data and lets rpmbuild do the processing.

My task now was to make it possible for Eclipse NeoSCADA to create configuration RPMs directly from inside the Eclipse IDE (running in Java), without the need to have rpmbuild on a Windows platform. Since I did write an RPM reader for Package Drone before, I did know a bit about the RPM file format. So this shouldn’t be a big deal?! … How naive ;-)

Continue reading

Eclipse Mattermost – What’s the state?!

A few weeks ago we started to test Mattermost as a communication channel for Eclipse Foundation projects. So, how is it going?

First of all Cédric Brun wrote a bunch of Java tasks which create Mattermost events based on various other Eclipse systems (like Gerrit, Bugzilla, Twitter, Forum, …) which integrate nicely with the Mattermost channels and allow each project to aggregate all these events in a single location. So you actually can get a notification about a new Forum entry for your Eclipse project in Mattermost now. Cool stuff! Many thanks!

From the usage side we are currently approaching the 100 user mark. At the moment of writing there are 94 registered users, 24 public and 8 private channels. About 150 posts per day and between 10 to 20 active users. You can have a look at the statistics below.

So is it a success? Well I goes into the right direction. Please don’t forget that this is just a test, but on the other hand there are people which are using it on a day by day basis for their Eclipse process. The usage of one big team with many channels (even multiple per project) seem to work fine. Single-sign-on will be a topic, right now Mattermost does have its user management. Also is the setup for projects still a manual process, which could be automated somehow. So there are a few topic left to solve.

But for me it is really amazing to see how quickly a new communication platform was established if all people work together. And it seems that people accept the new system quite well. I really hope we can establish this as a permanent solution.

Mattermost Statistics 2016-01-29

Java 8 magic with method references

When you start learning a new programming language you often encounter snippets of code which you have no idea why they work. The more you learn about that programming language to more you understand and these moments become rare.

Today, after programming many years in Java, I ran into such a situation with Java 8 and was really fascinated about it.

It all started with the problem of having a Stream<T> and wanting to “for-each” iterate over its content. The for-each construct in Java requires to have an array or Iterable<T>. However Stream<T> does only provide an Iterator<T>, which is not the same.

Now there are many solutions (good and bad) out there for this problem. However one solution really fascinated me:

[code language=”java”]
Stream<String> s = …;

for (String v : (Iterable<String>) s::iterator) {

}
[/code]

Now wait … Stream<T> does have a method iterator which returns an Iterator<T>. But Iterator<T> cannot be cast to Iterable<T>! And also is “s::iterator” not calling the method, but referencing the method.

Screenshot of Eclipse Quick Fix for Lambda expressions

Pasting this code fragment into the Eclipse IDE helps to understand what actually happens. Pressing Ctrl+1 on a code fragment allows to convert method references to lambda expressions and lambda expressions to anonymous classes. Quite fantastic ;-)

So, lets see how this code fragment get expanded to a lambda expression:

[code language=”java”]
for ( final String v : (Iterable<String>)() -> s.iterator () ) {

}
[/code]

And this lambda expression is equivalent to:

[code language=”java”]
for ( final String v : new Iterable<String> () {
public Iterator<String> iterator () {
return s.iterator ();
}} ) {

}
[/code]

The last snippet is rather bloated, as inner classes have always been in Java.

The magic which is happening is done by Java 8 new features “method references” and the “functional interfaces”. A functional interface is a java interface which only has one method to implement. “default” methods don’t count. Looking at Iterable<T> this is the case. So an Iterable<T> can be implemented with a lambda expression and or method reference. But for the for-each loop, Java does not “know” what you have mind. This is where the cast comes into play. By casting the method reference to Iterable<T>, Java infers that an Iterable<T> is requires, which can be provided by the method reference to Iterator<T>.

But looking at Iterable<T> there is no @FunctionalInterface present?!

That is right. But @FunctionalInterface is not a requirement for actually being a functional interface. It only tells the compiler to fail if the interface is not. So the downside of this example is, that there is no guarantee that Iterable<T> will always stay a functional interface, since the authors have not committed to that using @FunctionalInterface.

In the end, I am not sure if this is a good solution for my original problem. But is still is a fascinating piece of code and a great idea indeed.