Monthly Archives: November 2014

6 posts

Releasing “Package Drone” 0.0.1

A package repository for Maven Tycho, OSGi and all the rest.

Itch: I want to have a software repository where Maven Tycho can deploy to and P2 can read from. Also I would like to re-use this repository as an OBR or OSGi R5 repository, and possibly as Maven repository.

Scratch: Package Drone, version 0.0.1

Now there already is the Nexus Repository and the Nexus Unzip Plugin. However this essentially uploads a full P2 repository ZIP file and uses Nexus as a plain web server, hosting that zipped P2 repository.

Instead I would like to not only have a P2 repository, but also an OSGi R5 repository, based on the same OSGi bundles uploaded. I would also like to upload bundles created by the Maven Bundle Plugin, or BNDtools. Also would I like to make a full, Maven like, release using Tycho and later host this as a Maven 2 repository. Now package drone is not quite there yet, but the basic Tycho Deploy -> P2 Consume workflow already works to some degree.

Package Drone is hosted on github and there is a small readme and wiki.

Be warned, this is alpha quality software. If it works for you, fine. If not please help me fix it!

Google Play Store Forums

Dear Google,

since I did not find a better play to post this idea, I just did it right here ;-)

For openSCADA, the open source project I am working on, we use Google Groups as a communication channel with end users. This works quite fine actually, and I think that Google Groups are a fine instrument for that.

Sadly, when I browse through the Play Store, reading comments on apps, very often I find comments like “How can I…”. The comments, and also the possible replies are misused a form of forum, or back and forth communication channel. The next this is that the original comment gets updated to reflect a reply. All this is quite irrelevant, when I want to check if the app is worth a download or not.

On the other hand, my experience with Google Groups is, that very often users already help each other, and only when the question remains open for some time, or the question is rather specific we answer it ourselves.

I why don’t you just allow an automatic “per-app” Google Group, integrated into the Play Store App (but also accessible using the normal Google Group Website), to let users write about the app, provide self support, and provide a support forum for the application developer.

Well, I hope you read it some time.

You know were to find me ;-)

Spring WebMVC – Bad request for most pages

Today I stumbled over an easy configuration mistake you can make, which will cause “400 Bad request” for most static resources. It took me a little bit of time to figure out what went wrong.

I had a classic Spring WebMVC setup, DispatcherServlet, resource mapping for static resources (CSS mostly).

After making a few changes all CSS files started to have “400 Bad request”. Which was strange, since these were only static resources. Bad request sounded like something went wrong in the Jetty that I used. So I started debugging into this issue.

It turned out that all requests were directed to my newly added @Controller class that already was active in the Spring context. It’s handler method was causing the “400” error. By why for all CSS files?

It was a missing “value” property in the @RequestMapping annotation. I had:

[code language=”Java”]
@Controller
public class ArtifactController {
@RequestMapping ( name = "/artifact/{artifactId}/get", method = RequestMethod.GET )
public void get ( HttpServletResponse response,
@PathVariable ( "artifactId" ) String artifactId ) {
final StorageService service = Activator.getTracker ().getStorageService ();
}
}
[/code]

Where it should have been:

[code language=”Java”]
@Controller
public class ArtifactController {
@RequestMapping ( value = "/artifact/{artifactId}/get", method = RequestMethod.GET )
public void get ( HttpServletResponse response,
@PathVariable ( "artifactId" ) String artifactId ) {
final StorageService service = Activator.getTracker ().getStorageService ();
}
}
[/code]

Note: the @RequestMapping attribute should have been “value” instead of “name”.

OSGi EE – Modular Web Applications

Creating a modular web application in Java still is a tricky task. While there has been some improvement with web fragments, this still is far away from what you actually want.

But what is it that you (or better I) want:

  • Modularity – Make the application extensible using plugins. Not just one big block. Install additional functionality with a few clicks
  • Easy setup – Setting up a JEE server like JBoss can be a pain in the ass. First you have to configure your datasource with some obscure XML file. It would be way better to be directed to some sort of setup screen, asking for all database (etc.) information first. Guiding you through a setup process. With JEE your web application won’t even start if your JPA data source cannot be loaded since the driver is not specified.

Now there are a lot of applications which provide this flexibility. Atlassian, Jenkins, and a few more, all do a great job. Most PHP web applications guide you through a web setup when you first install the software. So why can’t Java do this out of the box?

When you think of modularity and services, OSGi immediately comes into my mind. However “the Web” still is a strange place for OSGi setups. Yes you can register a servlet with OSGi and access it through “http”. But that is just the start. You want JSP, Form Validation, maybe even Spring WebMVC.

There are a few setups I stumbled over, pax runner with pax web. However they bring in a pretty old jetty 7, when there is jetty 9.2.x with Servlet 3.1 support. There are some Apache Karaf tutorials, however there is also no JSP support, just a custom Vaadin bridge.

Jetty 9.2.x claims to have OSGi support out of the box. In combination with Eclipse Equinox this should be an easy setup. And although it really works, you know what you have to do. I got it working in the Eclipse IDE, but it still provides most things you really want.

In order to be able to reproduce it myself, I made a few ant script and sample projects out of what I learned and decided to put them up on github.

So if you want to build modular web applications with Jetty, Equinox, Eclipse, Hibernate Validation, Spring WebMV and more (with a recent version of all components) you can have a look at https://github.com/ctron/osgiee.

If you have more examples working or find a bug, please let me know ;-)

Identify GSM modem devices using udev

Again an interesting problem, I do have a Linux box and it has two GSM modems and a RS-232 FTDI USB device built in. Each GSM modem brings three USB serial devices. Now I do want to dial up using the first of these modems and therefore I do need the device name, e.g. /dev/ttyUSB2.

However, each time the box boots up, either the RS-232 device or the modems are first in the order or devices found by the kernel. This results in the modem to be either /dev/ttyUSB2 or /dev/ttyUSB3. Since this definitely is an issue when dialing up, I would like to keep these device names persistent.

udev can help here. It allows one to influence the way devices are created in userland. Depending on your distribution, the rules files are located at /etc/udev/rules.d/ (at least for Ubuntu).

Now my modems can be identified by vendor and product id (12d1, 1404) so a simply udev rule should be fine:

[code]SUBSYSTEM=="tty", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="1404", SYMLINK+="gsm%s{bInterfaceNumber}"[/code]

In theory this should create additional entries under “/dev/” with map to the kernel assigned device names. For example /dev/gsm00 -> /dev/ttyUSBXX. So I could just access /dev/gsm01, whatever the boot order was.

The problem is that the device attribute bInterfaceNumber is not on the tty device, but on the usb device in the parent hierarchy.

Still it is possible to record the interface number of a first rule, and use it in a second one:

SUBSYSTEMS=="usb", ENV{.LOCAL_ifNum}="$attr{bInterfaceNumber}"
SUBSYSTEM=="tty", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="1404", SYMLINK+="gsm%E{.LOCAL_ifNum}"

This stores the attribute “bInterfaceNumber” into the environment variable .LOCAL_ifNum (the prefixed dot is a notation for temporary or hidden variables). In the second rule the same variable is pulled on using the %E syntax. Newer udev versions also support $env instead of %E.

Thanks to [1] for mentioning this trick!

[1] https://unix.stackexchange.com/questions/60154/udev-rule-file-for-modem-not-working