Quantcast
Channel: Michael Vorburger's Blog v2
Viewing all 64 articles
Browse latest View live

How to upgrade to latest node.js & npm on Ubuntu Linux

$
0
0
Tonight I hit https://github.com/livedata/grunt-devcode/issues/8 again, and figured it was because I was on outdated versions of node.js& npm. Here's how to upgrade to latest, following https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager, may be this is useful to some:

$ node --version
v0.10.15
$ npm -version
1.2.18


$ sudo apt-get autoremove

$ sudo apt-get remove nodejs-dev
$ sudo apt-get remove node-gyp
$ sudo apt-get remove nodejs-legacy

$ sudo add-apt-repository ppa:chris-lea/node.js
$ sudo apt-get update
$ sudo apt-get install nodejs

$ node --version
v0.10.28
$ npm -version
1.4.9

How to renew an expired self-signed SSL certificate

$
0
0
Tonight I struggled a little longer than one should have to with using Postman in Chrome to access some Mifos X REST API on localhost. The Mifos X localhost server for dev fires up a Tomcat with a self-signed SSL certificate (and forces you to use that, the non-SSL port redirects to it). Be that a bright idea as it may, it's regularly causing issues for folks. When it turned out that this blog outlining how to do the usual handstand to import a cert. didn't suffice, things got a little bit more interesting.. ;-) Ah, cert expired! OK, I can fix that and contribute a PR. Still NOK.. Chrome's end-user import certificate UI isn't actually doing anything on (Ubuntu?) Linux?! One must use certutil from libnss3-tools as described here.

I'll try to get a free wildcard SSL cert from GlobalSign for Mifos localhost dev to make this a bit more painless for others...

Swift

$
0
0

So, Swift, huh? Few first reaction quick thoughts:

Very first link to get DOC (!) is into some proprietary :-( app store thing I hear some people use...

Language seems nice; managed memory of course (yeah, it's 2014), strongly statically typed, but optional explicit type declaration thanks to type inference - way to go (like Xtend, TypeScript, etc. etc.), val vs. var - sure, named parameters - sweet, multiple return values (à la Go's result parameters), ..

But "safe patterns tuned for the (some single platform UI framework) APIs" - uh, in the lang? K, if you say so. Loving the "built to be fast... transformed into optimized native code, tuned to get the most out of..." marketing blurb - seriously, having to hit so obviously at those other VM-based langs? ;-)

That Interactive Playground (the "REPL of the 21st century" ?), in the line of Bret Victor's work (you HAVE watched his must see demo video, haven't you?), as acknowledged here, looks NICE... I'm wondering how much one would use this in practice in daily coding.. for live visualisation of UI work, only? For non-UI - write a test case and "debug visually"  by "sliding" back and for through some loop? Interesting

How to install Ubuntu 14.04 (64bit) alongside pre-bundled Windows 8 for dual boot with UEFI/GPT *AND* encrypt

$
0
0
We got a new laptop, and I was thinking that I might as well go Dual Boot on this one and keep that Win 'round, so that Junior could finally play games like Cube World or Species which he had been eyeing but couldn't play on his own (pure) Linux laptop (and which we couldn't get to run in a VM, as XNA& VirtualBox don't appear to mingle well).

You would think that should be 1-Click®© and no big deal in 2014, but hélas, no... thanks to UEFI, as well as the minor added complexity (where's the fun otherwise..) that I wanted disk encryption this was a minor PITA. (FYI the Ubuntu installer does now offer a simple 1-Click full disk encryption installation option for simple wipe-everything-and-install Linux scenarios; this post is specifically about how I got it working in a Dual Boot with UEFI scenario.) Here's how to do it:

We'll start, as always, by grabbing the currently latest Ubuntu 14.04 64-bit image (it has to be the 64-bit; UEFI support isn't available on 32-bit, it seems). Put that on a USB stick, pop that in and boot from it...

First step, and this is super important, you have to make sure that it has booted up from UEFI mode, by checking if /sys/firmware/efi exists. In the case of my laptop, I had made the mistake of having manually disabled secure boot and enabled some BIOS setting allowing mixed UEFI / Legacy / CSM start-up, which ultimately ended up making things MORE complicated; after playing with this a little bit back and forth, I gathered that only by leaving that BIOS setting to "UEFI Boot only" did the Ubuntu installer image from the USB stick come up with /sys/firmware/efi.

Backups are generally never a bad idea, so I did a dd if=/dev/sdX conv=sync,noerror bs=64K | gzip -c > /mnt/myexthdd/hda.img.gz before touching anything, to make a restore-able copy of the entire internal drive (not just the Windows partition); see e.g. Disk Cloning on ArchiWiki for more about this.

OK, onwards; now using GParted to resize the Windows partition to make some free space for Linux. BTW, that seemed to handle resizing NTFS just fine - better than Windows' own Disk Management actually, which does have a Resize command, but even on an almost fresh factory install (after just latest Windows and firmware/BIOS upgrades etc.), it would only let me re-size to about half the original, not more, due to some "fixed position" file problem.

BTW, it's probably interesting and a Good Idea at this stage to have a closer look around at what existing partitions your laptop currently has from the factory - understand what is what, and maybe write that down somewhere - it could be handy later here. In my case, there were 6 (!) partitions BEFORE I started fiddling with Linux installation... thank you very much UEFI and Windows 8.

Right, now finally start the "Install Ubuntu 14.04". It may say "has no detected operating systems" (despite the pre-installed Window) - if it does, ignore that. Or it might notice the Win, but you'll find that you cannot use the "Encrypt the new Ubuntu installation for security" option in that case (it's "greyed out" / disabled), so -either way- we'll have to choose the "Something else" option instead, and:

In the "free space", Create Partition, say 300 MB ext4 /boot - the installer may make that say /dev/sda7. We DO want to Format this one; that NON ENCRYPTED bootstrap partition is where our Kernel image etc. will go. (What I'm curious about is how this holds up security wise - isn't that a huge backdoor for a possible attack vector? I vaguely understand that UEFI Secure Boot is supposed to address that, but digging more into this will have to be for some other night/s...)

In the remaining "free space", Create Partition using all remaining space, and "Use as: physical volume for encryption". As soon as you do that, new options will be added to the window; one lets you add a password for the encryption for the partition. This time, you will notice that, at the top of the list, the newly created, encrypted partition is listed under /dev/mapper/sdaX_crypt. Select that newly created partition, click "Change..." button, and ext4 for /.

Note that, at least in Ubuntu v14.04, you should NOT have to change the EXISTING (from Windows) small e.g. /dev/sda2 partition (it's the one with the 'boot' flag in GParted) to have a Mount point: /boot/efi manually yourself - that partition should already automatically show up as type "efi" by itself, and NOT as a "fat32"- if it does (incl. offering check/uncheck to Format it), then for some reason you have clearly NOT booted the installer in EFI mode!!

As Device for boot loader installation we'll want to choose our EFI partition (e.g. /dev/sda2).

OK, go - Continue. Confirm the next Q from the installer - we do want to continue, without having selected any partition for use as swap space (or create one inside /dev/mapper/sdaX_crypt if you need swap).

Now let it do the install, wait... and Restart. Now you'll get a GRUB 2 Boot Selector (not the one from Windows that was factory installed anymore, that's just been wiped). Try Linux.. it should work - great!

Normally GRUB2 menu will also have a Windows entry, try it - works? It did not for me... but, All Hail Boot-Repair comes to the rescue, and fixes things up. If your Boot-Repair says "EFI | /boot detected. Please check the options.", but then in Advanced options everything on GRUB location, GRUB options, MBR options is  grayed out, then double check that you are running it as sudo and that your initial Ubuntu installation WAS done with UEFI support; remember /sys/firmware/efi, you need to see that when you boot from the intial USB, not just now when you're set-up. (And DO REMEMBER to disable UEFI Secure Boot in the BIOS, like boot-repair recommends in a message at the end...)

K, done! I learnt a few things, and it was lot's of fun & maybe this post is useful to someone out there.

PS: Other tutorial's recommend using NeoSmart's EasyBCD instead; I had tried that before doing above, and somehow it didn't work, on my laptop. The idea in that approach is that instead of GRUB you use the Windows Boot Manager and hope that it can boot into Linux via a new Boot Configuration Data (BCD) entry for Ubuntu you add - but somehow I could not get that to work.

Build your own JDK at home

$
0
0
I was curious to learn how hard it may be to build your own Java Development Kit (JDK) "at home", purely from OpenJDK source code, and it turns out that -on (Ubuntu) Linux at least- this actually very easy! As described here, it goes like this:

sudo apt-get install git mercurial zip bzip2 unzip tar curl
sudo apt-get install ccache make gcc g++ ca-certificates ca-certificates-java
sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev  
sudo apt-get install libasound2-dev libcups2-dev libfreetype6-dev
sudo apt-get install build-essential 
sudo apt-get install openjdk-7-jdk

Note that you need a "Bootstrap JDK" - e.g. we have to first grab the binary OpenJDK v7 to build our own Java8 SDK from scratch. Also, you can skip the ruby-dev & fpm gem, unless you are interested in actually building a *.deb or *.rpm package (and not just a dist *.tar.gz). Now you can:

mkdir ~/dev/openjdkathome
cd ~/dev/openjdkathome
git clone https://github.com/hgomez/obuildfactory.git

XUSE_NEW_BUILD_SYSTEM=true XBUILD=true ./obuildfactory/openjdk8/linux/standalone-job.sh
(...)
## Finished images (build time 00:00:29)
----- Build times -------
Start 2014-06-09 15:38:31
End   2014-06-09 16:00:23
00:00:36 corba
00:00:28 demos
00:13:39 hotspot
00:00:29 images
00:00:21 jaxp
00:00:28 jaxws
00:04:51 jdk
00:00:43 langtools
00:00:17 nashorn
00:21:52 TOTAL

Now you could git rid of the previously installed binary "Bootstrap JDK" again, which had to be used to build your own version, like this:

sudo apt-get remove openjdk-7-jdk
sudo apt-get remove openjdk-7-jre
sudo apt-get remove openjdk-7-jre-headless 

and you've got yourself your very own home made JDK:

$ sources/openjdk8/build/linux-x86_64-normal-server-release/images/j2sdk-image/bin/java -versionopenjdk version "1.8.0-jdk8-b132"
OpenJDK Runtime Environment (build 1.8.0-jdk8-b132-20140609)
OpenJDK 64-Bit Server VM (build 25.0-b70, mixed mode)

This README-builds.html has some more details on the OpenJDK build.

Java 8 null type annotations in Eclipse Luna (v4.4) - your last NullPointerException ever, The End of the World as we know it? ;-)

$
0
0
The other night I hopped on the train to attend an Eclipse DemoCamp, and hearing again about the Java 8 null type annotations for advanced null analysis new in Eclipse Luna (v4.4) motivated me to finally try this out myself a little to gain some first experiences.

The idea is basically that the Java compiler can do a much better job helping you while you code than what you may be used to today to prevent the infamous NullPointerException at run-time (AKA the "billion-dollar mistake"). Static code quality analysis tools such as FindBugs, other IDEs, and earlier versions of Eclipse had a simpler incarnation offering some of this before, but Java 8 type annotations (AKA JEP 104) and the new annotation-based null analysis in Eclipse Luna can take this further now. (Type annotations enable @SomeAnnotation to be also inside generics parameter, or to distinguish Array types vs. array itself in Java 8.)

To get started, use an Eclipse 4.4 (Luna), with a Java SE v8 JDK, and a project configured like this:


You'll also need the org.eclipse.jdt.annotation-2.0.0.*.jar (NOT the v1!) on your project's classpath, e.g. like this in your pom.xml if you use Maven for dependency management (similar for others) :

<dependencies>
<dependency>
<groupId>org.eclipse.jdt</groupId>
<artifactId>org.eclipse.jdt.annotation</artifactId>
<version>2.0.0.v20140415-1436</version>
</dependency>    
</dependencies>

<repositories>
<repository>
<id>eclipse-staging</id>
<name>Eclipse.org Staging</name>
<url>https://repo.eclipse.org/content/repositories/eclipse-staging/</url>
</repository>
</repositories>

Now, if you had a code going something like this:

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;


public class Example {

public void foo(@NonNull String s) {
System.out.println("hello " + s);
}

public void bar(String arg) {
foo(arg);
}
}

you'd get a warning "Null type safety (type annotations): The expression of type 'String' needs unchecked conversion to conform to '@NonNull String'" in the foo(arg) line - because you told it with an explicit @NonNull annotation that foo's String s arg shall never be null - but its not sure it is. 

If you you declared bar(@Nullable String arg), you'd even get an error, not just a warning, plainly stating "Null type mismatch (type annotations): required '@NonNull String' but this expression has type '@Nullable String'". This works, to a point, through more indirect nested call chains as well, not just for trivial examples like above.

Now, instead of peppering your code with loads of @NonNull everywhere, you might opt for the sane a simpler choice that, normally, you really do NOT ever want to accept null arguments or return null - unless you have a very good reason to, and explicitly say so. This can be declared by putting a file name package-info.java into each of your Java packages (each meaning.. well really each - not only one single package-info.java at your root package, unfortunately), containing:

@NonNullByDefault
package your.package;

import org.eclipse.jdt.annotation.NonNullByDefault;

For new code, this seems like a code idea. For moving existing code to this, you could migrate in 2 steps: first enable the project configuration shown above and work through anything it flags, then (later) add (some) @NonNullByDefault, and work through impacts. If you enable the “Missing @NonNullByDefault annotation on package” preference as Warning or even Error you'll get a “A default nullness annotation has not been specified for the package ...” reminder if you create new packages and forget to copy the package-info.java. 

I've found that there are limits to how smart it can be, in many cases easy to address; for example: assertThat(something, not(nullValue())); isn't understood, only Assert.assertNotNull(something); is.

If you were previously in the habit of doing return null; in some not-quite-implemented-work-in-progress-class, you'll now have to use e.g. throw new UnsupportedOperationException(); // TODO FIXME.

This is also a great opportunity to convert some of your existing to or start writing new code with the Null Object pattern, and learn how to use the (new Java 8) java.util.Optional wrapper (“monad”). Basically every time you find yourself adding @Nullable somewhere (after having enabled @NonNullByDefault on the packages), ask yourself if an Optional wouldn’t be a better fit? -- BTW, if you cannot move to Java 8 in your project just yet for whatever reason, maybe this is an inspiration to use Google Guava's Optional, which doesn't require Java 8?

One “Aha!” moments I had when doing a conversion on a toy project was when the compiler was able to telling me that e.g. com.google.common.base.Preconditions.checkNotNull() kind of parameter checks, or simple if (arg == null) throw new IllegalArgumentException() are now no longer needed - guaranteed(“Contradictory null annotations: method was inferred as '@NonNull T checkNotNull(@NonNull @Nullable T)', but only one of '@NonNull' and '@Nullable' can be effective at any location”) - nice! Cleaner more readable code less cluttered with non-null precondition checks - AND enforced by the compiler instead of at run-time - you can have your cake AND eat it, too?

It's not all an entirely smooth and easy ride though. For example, I've found funky generics can be quite a bit of fun; you quickly hit “Null type mismatch (type annotations): 'null' is not compatible to the free type variable 'T'” from this kind of code:

public class SomeClass<T> {
public T foo() {
return null;
}
}

This happens even WITHOUT (yet) using @NonNullByDefault - generics are orthogonal to that. The technical reason for this is explained in the doc. The solution, if null T’s are valid, is to either use:

public class SomeClass<T> {
public @Nullable T foo() {
return null;
}
}

or

public class SomeClass<@Nullable T> {
public T foo() {
return null;
}
}

Another and IMHO ultimately probably better alternative may be to just switch foo() to return an Optional<T> as explained above - if it’s new code or existing code you can still change.

Apart from generics, based on my short experience in applying this to a toy project, is when you start interfacing with existing Java code available to you only in binary and not source form. Until this takes off more, if ever, most such external code of course won't be null annotated yet. (There is also the problem of the non-standardization of these null annotations & JSR 305 non-adoption - but that's beyond this post.) So in packages where you extend or heavily interface with code from external binary libraries @NonNullByDefault may not be feasible in the short term. But there is a hope - Enhancement 331651 might come up with a solution for this.

Lastly, while toying with this and preparing this article, I've come across a few more points than mentioned above, and opened issues incl. #438785, #438469, #438467 as bugs and/or for clarification (may just be misunderstandings on my part).

Will you convert your code to be null safe, and never ever get a NullPointerException anymore? The End of the World as we know it? ;-)



How to connect to PITA secured corporate enterprise WiFi from Ubuntu Linux 14.04

$
0
0
On a laptop that can connect to a corporate enterprise WiFi in Windows using Security type: WPA2-Enterprise, Encryption type: AES, Network authentication method: Microsoft Protected EAP (PEAP), Authentication method: Secure password (EAP-MSCHAP v2), here's how to access the same WiFi using Ubuntu 14.04:

Use Protected EAP (PEAP), not LEAP or FAST or Tunneled TLS. Now leave "Anonymous identity" (huh?) empty, PEAP version: Automatic, Inner authentication: MSCHAPv2. In the Username you’ll need you give your Window’s DOMAIN\user. Then Chose no CA Certificate Authority certificate.... and confirm the subsequent warning with Ignore. (Even if a friendly soul from your IT provides you a *.cer file, try without it first; the trouble is that if it’s self-signed or it’s Verified By root isn't known to your Linux, this causes more trouble than it helps you.)

BTW: WiFi configurations are stored in /etc/NetworkManager/system-connections/* .. relevant logging via tail -f /var/log/syslog and dmesg; search engines, please hit this by spidering the infamous "wlan0: deauthenticating from ... by local choice (reason=3)".

$ sudo wpa_cli and type "help"... looks like loads of fun stuff to play with - some other night.

Java 8 Swing related JVM crash on Linux identified

$
0
0
I have identified a Swing related JVM crash on Linux which appears to be a regression in Java 8:

Launching my isolated standalone pseudo (non) "app" example https://github.com/vorburger/CrashTestDummy a few times using either OpenJDK or Oracle Java version 8 (but not on v7...), on two different independently installed Ubuntu 14.04 Linux of mine at least, where UIManager.getSystemLookAndFeelClassName() = com.sun.java.swing.plaf.gtk.GTKLookAndFeel causes:

The program 'java' received an X Window System error.
This probably reflects a bug in the program.
The error was 'RenderBadPicture (invalid Picture parameter)'.
  (Details: serial 251 error_code 143 request_code 139 minor_code 6)
  (Note to programmers: normally, X errors are reported asynchronously;
   that is, you will receive the error a while after causing it.
   To debug your program, run it with the --sync command line
   option to change this behavior. You can then get a meaningful
   backtrace from your debugger if you break on the gdk_x_error() function.)

As a regression from an earlier major Java version, this is a Fairly Bad Thing for Java on the (Linux) desktop. It's possible to "work around" the problem (but most users will not, unless reading this...) using:

-Dswing.systemlaf=javax.swing.plaf.nimbus.NimbusLookAndFeel or -Dswing.systemlaf=javax.swing.plaf.metal.MetalLookAndFeel

As it doesn't seem to be possible to easily get an account by one-click to file issues in the JIRA on https://bugs.openjdk.java.net (which makes OpenJDK an interesting kind of "open source" project IMHO...), I've just reported this on http://bugreport.java.com; re: "We are evaluating this report and have stored this with an Review ID: JI-9014491. In the event this report is determined as a defect or enhancement request, it will be referenced with a new Bug ID and will be listed on Bugs.java.com." - thank you very much...

PS: If I had the time, I'd love to dig more into this and maybe even help with contributing a patch to OpenJDK, but I'm afraid the effort required for getting to the bottom of this one may be beyond what I have bandwidth for... how do you even "run 'java' with the --sync command line option" for X11 debugging?? And even if you could, then what? It's been a VERY long time since I last used gdb - so.. this kind of thing: gdb java, break gdk_x_error, start -jar my.jar ?? Now what? How do you correlate the Java call stack with the JVM C bt from gdb to make any sense and pinpoint to something actionable? Help! ;-)

How-to clean up and enforce open-source license headers in Maven-based build

$
0
0
The other day I had to make sure that anopen source project had clean and proper copyright and license headers in all its files. For Apache Maven-based builds, here is a quick write up illustrating how you can automate doing this. The main steps are:

1. strip existing old license headers (if needed), as the automated tool requires a particular format
2. automatically apply new standard header to all files
3. ensure that new files added in the future which don't include the new standard header fail your build
4. using your source control tool to compare before/after, and manually fix-up any lost names etc.

For some probably historical reason there appear to be two very similar Maven plug-in for this, namely the Mycila Maven License Plug-in and the Codehouse Mojo License Maven Plugin (confusingly both named "license-maven-plugin", but with a different groupId). We'll be using Mycila's for the stripping (as Codehouse' doesn't seem to include that feature), and Codehouse for the re-adding and future enforcement.

So to strip existing old license headers, add this to your (parent) pom.xml:

<plugin>
   <groupId>com.mycila</groupId>
   <artifactId>license-maven-plugin</artifactId>
   <version>2.6</version>
   <configuration>
       <header>com/mycila/maven/plugin/license/templates/APACHE-2.txt</header>
   </configuration>
   <executions>
       <execution>
           <goals>
               <goal>check</goal>
           </goals>
       </execution>
   </executions>
</plugin>

Then run this:

$ mvn com.mycila:license-maven-plugin:remove

Doing e.g. a git diff now will show you that existing license headers have been removed. As this was a one-time operation, you can now remove the com.mycila:license-maven-plugin from your pom.xml again, and add this instead:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>1.7</version>
                <configuration>
                    <licenseName>apache_v2</licenseName>
                   <addJavaLicenseAfterPackage>false</addJavaLicenseAfterPackage>
                    <failOnMissingHeader>true</failOnMissingHeader>
                    <failOnNotUptodateHeader>true</failOnNotUptodateHeader>
                    <roots>
                        <root>src/main/java</root>
                        <root>src/test/java</root>
                    </roots>
                </configuration>
<executions>
   <execution>
       <phase>validate</phase>
       <goals>
           <goal>check-file-header</goal>
       </goals>
   </execution>
</executions>
</plugin>

You can change the licenseName to any of those listed by mvn license:license-list. Now run:

$ mvn license:update-file-header

and do e.g. a git diff now to see that you that new license headers, in the format suitable for automate tooling. If you've previously removed old license headers, then at this point you might want to do a before/after comparison, and manually fix-up any lost names etc.

Note how the pom.xml configuration above binds mvn license:check-file-header to the Maven lifecycle validate phase. This means that your build (incl. e.g. your TravisCI or Jenkins-based GitHub pull request) now automatically enforces presence of these headers. A new file added missing them will cause any future mvn verify / test / package etc. to fail with:

[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.mojo:license-maven-plugin:1.7:check-file-header (default-cli) on project org.eclipse.emf.eson: There are .. file(s) with no header :
[ERROR] /home/vorburger/dev/ngMUI/com.temenos.ds.op/SUBS/eson/org.eclipse.emf.eson/src/org/eclipse/emf/eson/EFactoryRuntimeModule.java

If using Eclipse, you may also would like to set up  menu Project > Properties (or Window > Preferences) > Java > Code Style > Code Templates, Comments > Files for new Java files to get your header by default.

If your build is using Gradle instead of Maven, something very similar can be done using the license-gradle-plugin from nl.javadude.gradle.plugins; you can see how to configure it e.g. in the build.gradle of the open source microfinance platform Mifos X.

Minecraft bought by Microsoft

$
0
0
Wow - so Microsoft acquired Mojang, the Minecraft company (see Microsoft's video announcement by its head of Xbox, and Mojang's somewhat succinct official blog post, and Minecraft creator's Notch personal blog entry).

I'm sure the new owners at Microsoft understand that a significant value of Minecraft isn't just the one time 19.95 EUR one pays for the account to play the PC (or Xbox etc.) version, but the HUGE community of independents around it, fueling the "About 87,000,000 results" you get when searching YouTube for Minecraft .. lots of silly stuff, yes - but also kids learning learning from other kids online and then imitating what they've watched, and summoning up the courage to present online themselves. (And then as they get a little older, you use that how-to-learn-online experience to gently push them into watching e.g. some Khan Academy or TED Ed videos, and become engaged netizens...)

My son first learnt about what a Java class is from EntityPig by browsing the Minecraft source code following e.g. this tutorial, and about OOP IS-A inheritance from class EntityWaterPig extends EntityPig extends EntityAnimal extends EntityAgeable extends EntityCreature extends EntityLiving extends Entity, and about what a ZIP archive is by having to replace some *.class files inside Minecraft.jar for an early Mod he downloaded. He found all that much more a fun and engaging than when I first tried 'Look! System.out.println("hello, world!")' ... ;-)

Many of the online videos involve one or other of the (tens of?) thousands of available Minecraft "mods" produced by independent programmers. Mods are kind of plugins which extend Minecraft, more easily installable via the thousands of Minecraft modpacks available e.g. on the Mojang independent Technic Platform which bundle mods. These mods range from the silly (there is this one where when you slay a pig you turn into that pig..), all the way up to the one where you can learn programming by using an in-game Computer-in-the-Computer (which is easier to get started with than "real" modding).

So it will be interesting to see how the Microsoft acquisition plays out for the future of the Minecraft modding scene. From the little I understand, the reverse engineered Minecraft source code available via The Forge, which is the technical basis for the Mods, was "tolerated" by Mojang - with a tacit understanding that this decompilation could not be used to create some sort of fork of Minecraft bypassing the revenue generating Mojang account Minecraft log-in. As far as I know, that has worked out reasonably well in practice. One would assume that Microsoft will have the wisdom to continue allowing this tacit practice at the root of the thriving online phenomena that is Minecraft. We could even ponder if Microsoft has the guts to make a bold move pushing this further - maybe investing the development resource needed for offering an "official" Minecraft plug-in API? Or, let's go crazy. I'll have an orange juice - actually open source Minecraft core source (still with some account creation revenue protecting professional OSS formula - should be possible).

May be Microsoft will recognize the potential of Minecraft for education, and invest in and promote the Minecraft.EDU platform? Further development of innovative ideas such as the Minecraft Mod which can help teach young kids Quantum Physics?

BTW, you would expect that Microsoft preserves Minecraft's cross platform offering, which are technically different games, actually, as long as they are commercially viable (which I guess they all are, although I have no idea about the PC/XBox/iPad etc. break-down). Kids are probably a lot less into "platform allegiance" anyway - when my daughter and our neighbor's girl play Minecraft together, they switch back and forth between Minecraft worlds on the iPad at the neighbor's home and their main Minecraft big world accessible via PC version which the kids share on the server I've set up for them.

Ok, 'nuff said. THANK YOU for Minecraft to Notch, Carl, and Jakob (leaving Mojang) and Jens (staying on).

Mifos executable WAR with MariaDB4j & Spring Boot

$
0
0
Tonight I submitted a pull request which contributes an executable WAR based on my Java embeddedable MySQL package named MariaDB4j& Spring Boot to Mifos, the open-source microfinance platform which ends poverty one line of code at a time. (I've actually been working on this, incl. the MariaDB4j foundation, on and off for 2.5 - 3 years, and I'm very happy that this work is finally v1.0 complete now. Its based on previous work I had done in what seems like eons ago, when I contributed the Workspace 2.0 Setup, and an executable WAR plus EXE launcher (without DB then) to the previous incarnation of Mifos (before Mifos X).

The main functional goals achieved and which will be available after the PR merge are: 

A. For end-users interested in easily locally trying out Mifos, or perhaps even small production deployments, instead of the current INSTALL which requires Tomcat & MySQL set-up, one can now instead (literally) just do "java -jar mifos.war", and the Mifos back-end/platform (only, not our AngularJS UI, so far) is ready for business! Tomcat is embedded, DB is included - pure magic! ;-) The port etc. used by MariaDB4j can be configured via e.g. -DmariaDB4j.port=1234. The same Mifos package however can alternatively still ALSO be deployed like a traditional classic WAR in a web container like Tomcat with a JNDI datasource, as before!

B. The new ServerWithMariaDB4jApplication class main() with offers something very similar to above, but targets developers: Imagine e.g. a hackathon for Mifos - yesterday that started, like for end-users, with Tomcat & MySQL download & somewhat cumbersome manual set-up steps, now it's git clone; gradlew.bat eclipse, import project & right-click on ServerWithMariaDB4jApplication to Run As > Java Application - literally. And you can set breakpoints and debug without have to remember how to remote attach! ;-) The gradle tomcatRunWAR used by  everyone today is still there, but I expect nobody will have any reason to use it anymore.

C. Easy integration tests - just right-click on the new SpringBootServerLoginTest to Run As > JUnit Test - bang, green. Without setting up a database, building a WAR, launching any script outside of your IDE; whatever is required happens automatically when you extend AbstractSpringBootWithMariaDB4jIntegrationTest, with a fresh database, different from the one used by ServerWithMariaDB4jApplication.

D. ServerApplication is for anyone who doesn't quite trust ;) the MariaDB4j magic which spawns a native DB process from Java (and, tries to ensure it, takes it down on each JVM exit), and prefers to keep running a traditional DB externally as before. So ServerApplication, like ServerWithMariaDB4jApplication, fires up an embedded Tomcat via Spring Boot, but doesn't involve MariaDB4j, instead has a configurable DataSource (via -Dmifos.datasource.port=1234 etc.).

One important change affecting all developers and required by the new features described here is that all Flyway migration DB scripts are no longer in  mifosng-db/migrations/core_db/ as before, but now in mifosng-provider/src/main/resources/sql/migrations/core_db (on the classpath).

BTW: As a side effect of this work, I've fixed a few related minor bugs in Mifos X, incl. a badly wrong dependency which pulled loads of Maven normally build time only JARs along into the WAR (and screwed up logging), or an issue causing the job scheduler to only work if the WAR is expanded (which it desn't have to be for java -jar mifos.war, as everything can be nicely loaded from the classpath), as well as cleaner / non-hanging WAR shut down by resolving a stuck non-daemon thread issue (thank you Nikhil Khatwani!), as well as raised a bug which got fixed upstream in Spring Boot core itself. More importantly, related required improvements include automatic on-the-fly reconfiguration of the DB port in the tenants table

PS: A very small technical problem which I trust someone with more Gradle-ese expertise than I have can easily fix is that the executable WAR only works if built by "gradlew build", but not "gradlew war" which the Mifos build uses for some reason (incl. in its "gradlew dist" task that builds the final product ZIP) - any pull requests fixing build.gradle most welcome! ;-) 

Eclipse Public License enforcement in builds (and bug in org.codehaus.mojo:license-maven-plugin)

$
0
0
A month ago I blogged about "How-to clean up and enforce open-source license headers in Maven-based build". When Sharon from the Eclipse Foundation's legal review team pointed out that ESON erroneously had EPL + EDL instead of only EPL license headers during the CQ for bringing ESON into eclipse.org, I realized that the org.codehaus.mojo:license-maven-plugin actually has a EPL / EDL mix up bug that was at the origin of this, so I submitted a patch to fix this (via attached SVN patch instead of Git PR, unfortunately).

If org.codehaus.mojo:license-maven-plugin is still actively maintained - I don't know if it is? In the mean time, I've forked the org.codehaus.mojo:license-maven-plugin on my GitHub account here. Perhaps using the org.codehaus.mojo:license-maven-plugin would be useful to other projects on Eclipse.org as well?

Mobile SMS-based basic e.g. math & language education (AKA mSara prototype v0.1)

$
0
0
Recently we were travelling on a vacation through India, and while driving for hours between cities, I did some math with my children. We occasionally use Khan Academy at home, so I gave them similar exercises on paper. Later on the ride while looking out of the window and letting my mind flow freely, I started thinking: Why do my children have the opportunity to learn like sponges as much as they like, while others that we were driving past lack access?

So I had an idea, and used a few nights at the hotels while travelling to change the world one line of a code at a time by hacking a v0.1 prototype of a mobile SMS-based basic math education platform which I'll tentatively call "mSara" - as in "Mobile Saraswathi" - think mPesa for Education. It's already running online up in the cloud/s (thank you Heroku) , and you can try it out yourself by sending an SMS text message to +1 646 791 3552 (thank you Twilio), and it will respond something like this:

You> MATH
mSara> Hi!  2 + 3 = ?
You> 5
mSara> YES! 2 + 3 = 5.  4 + 2 = ?
You> 7
mSara> No.. 4 + 2 = ?
You> 5
mSara> No.. 4 + 2 = ?
You> 1
mSara> No.. 4 + 2 = 6!  1 + 1 = ?

The idea is that system will track per user progress, which is easy as the sender number can be used as ID, gently ramp up difficulty, help with hinted solution suggestions if it detects one does not know the correct answer yet, and keep track of achievements, so one can learn more as you keep using it. Extreme simplicity in usage is paramount - no "menus" to "choose lessons" or anything like that.

For math learning, full literacy isn't needed, as basic number recognition should be sufficient (and reading a few keywords like "Hi", "Yes", "No" in English or a local language may be generally available; if not the exercises are probably self explanatory enough). If that is not a given, perhaps it could even teach basic numbers, using a dialog like this:

mSara> o o o = ?
You> huh?
mSara> o = 1.  o o = ?
You> 2
mSara> YES! o o = 2.  o o o = ?
You> 3

Similarly one could imagine some basic language vocabulary learning, initially certainly using multiple choice answers and not actually T9-style typing words, sending questions like "(local unicode script lang's word for 'house') = 1. mother,  2. house,  3. tree" - to which "2" has to replied as correct answer.

Assuming some of above is completed, the next and actually more interesting part is how to get millions to use such a platform... you would certainly have to go through local field partner organizations of various kinds which can reach into the target audiences. But even with that, what's the incentive for someone to use this? I reminded myself what got my young son interested in programming, and I'm sad ;) to report that it wasn't passion for OOP, "class" keywords and such; instead this young child's initial driving force was refreshingly openly monetary: "But papa, could I SELL the game we're making, you know like Minecraft?" ;-) So that then gave me a wild idea: What if this platform, which can easily track each participant's progress actually rewarded learning achieved through persistent trying not only with regular "WELL DONE" responses (which ARE important and can mean more than you may think), but actual... money? What if some donor funds, instead of leaking through gov programs or well meaning but perhaps inefficient NGOs, were to directly reach the top performing most able children per region on this platform? Mobile Airtel Money or Vodafone mPesa virtual currency bitcoins in exchange for making an effort to learn with an old phone? Tag line: "Earn a modern Android smart phone / tablet which we'll ship to get to you (with which you can access the next level of knowledge à la Khan Academy..) by successfully completing the SMS-based math course on your parent's old phone!" Perhaps this is completely crazy.

The "target audience" for such a platform of course isn't necessarily constrained to "children" of course, there is really no reason to artificially age limit, or say "time bomb" any of the exercises. If I can help someone learn, at whatever pace that they can afford (perhaps in parallel to working), that's great.

So what next? I'd really be very curious to try out how well this crazy idea actually works in practice in real world field test(s). It certainly needs a little bit more development; notably incl. more country local SMS gateway bindings. For example from India, using my first POC's US number isn't really viable, because its much more expensive to SMS an international number, and because incoming SMS From: phone numbers get screwed up with a prefix to track "telemarketers" due to TRAI government regulations - well meant spam protection, but in practice making a two way service such as this one not viable easily. So I'd need an Indian local short code for sending “non-commercial” messages without that prefix, but in the limited time I had to investigate this found out that set-up is somewhat bureaucratic (as in it's certainly feasible, but a little more time consuming for me than just "one click away" as offered internationally by e.g. Twilio). I'm also unclear if and how a SMS short number that is free to text to could be set up e.g. India - as traffic will likely be high, cost of even just Rs 1.00 for each answer may be an issue for the target audience? Incoming SMS are free in India, BTW.

I'll see how much of next steps I can do when myself; but alternatively, someone's philanthropic funding money to pay for other people's time would certainly help me.. ;) In parallel, reliable local field partner(s) to reach out to possible target audiences to see if this really creates value would be needed. If you have (access to), are or can support me in any of this with your time, money or connections, please do contact me!

PS: See the Ignite talk presentation about this I gave about this at Devoxx Belgium 2014, and see the open source code of this project on GitHub.

Swisscom Internet Box DNS server bug

$
0
0
Originally published 2014.12.03, amended 2014.12.17: Three days after I published the post below and spread it via social media, I got a very friendly personal call on a Saturday afternoon from Swisscom's Head of Home Network, informing me that an internal task force had analysed this particular problem, and asked whether I'd be interested in receive their upgraded firmware v05.01.14/05.01.18/689 image, while it was still running through last internal QA tests. I was indeed interested - and haven't had the problem with DNS relay on the Swisscom box described hereafter ever since. Thank you Swisscom - great customer service! ;-)

Grüezi Swisscom (FYI world, it's the local ISP),

Merci vielmool for your new fiber optic internet connection. Residential 1 GB sounds cool - although the price you're asking for probably isn't worth it today for most people, but that's not the point of this post (if you'd like me to beta test the top speed for you and provide feedback, feel free to give me a free upgrade).

I'm afraid however that your proprietary router, the very stylishly designed "Swisscom Box" (Swisscom branded, but seems to actually be produced in partnership with Siligence, SoftAthome and vestiacom) is a lot less cool - it breaks down regularly, roughly every 48h for me! :-( [Firmware v05.01.12/05.01.18/689]

Luckily for you I've been able to debug the issue and diagnose the underlying software bug for you. We note that you have made every effort to dumb the box down, surely to be "consumer friendly", which in principle is laudable, but in practice you might have gone a bit too far here? Not offering, even in Expert mode for advanced users ANY way to see any internal logs (I'm not even asking for a syslogd; we're talking basic just SEEING log..) is... really quite ridiculous? As is not allowing to set a custom DNS server on the built-in DHCP server.

The bug is that your internal DNS (cache) server daemon process which you run on what is surely to be some sort of embedded Linux appears to very regularly crash, or get blocked (non responding). You see, when my family says that "the Internet is down AGAIN, bloody Linux all over the house" what they actually mean is that while your Swisscom Box router IS up, and I CAN access its web interface, and you guys most likely cannot diagnose anything wrong from your end through remote analysis, and I can reach any IP outside, if I nslookup any DNS name not previously cached on the requesting host then your pretty little box often simply does not answer. If I directly ask your public DNS server, then it works. Hope you agree that this fairly clearly pinpoints the problem - see the commands below.

Please do kindly fix this at your earliest convenience - yesterday kind of time frame would be nice. Should you need any assistance, give me a ring we can further pair debug this with a less locked down custom firmware image you may kindly provide.

Your sincerely,
M. - a loyal customer who would like to stay with you if you fix this (and who will switch otherwise)


vorburger@yoko:~$ nslookup www.vorburger.ch 195.186.1.162
Server:195.186.1.162
Address:195.186.1.162#53

Non-authoritative answer:
www.vorburger.chcanonical name = vorburger.github.com.
vorburger.github.comcanonical name = github.map.fastly.net.

vorburger@yoko:~$ nslookup www.vorburger.ch 192.168.1.1
;; connection timed out; no servers could be reached

vorburger@yoko:~$ nslookup www.swisscom.ch 195.186.1.162
Server:195.186.1.162
Address:195.186.1.162#53

Non-authoritative answer:
Name:www.swisscom.ch
Address: 193.222.73.227

vorburger@yoko:~$ wget http://www.swisscom.ch/de/privatkunden.html
^C (No response)

vorburger@yoko:~$ wget http://193.222.73.227/de/privatkunden.html
--2014-11-30 19:42:20--  http://193.222.73.227/de/privatkunden.html
Connecting to 193.222.73.227:80... connected.
HTTP request sent, awaiting response... 200 OK
Cookie coming from 193.222.73.227 attempted to set domain to 73.227
Length: unspecified [text/html]
Saving to: ‘privatkunden.html’

    [ <=>                                   ] 55,072      --.-K/s   in 0.03s   

2014-11-30 19:42:20 (1.74 MB/s) - ‘privatkunden.html’ saved [55072]

udev for Google Android Wear LG G Smart Watch

$
0
0
I'm toying with a Google Android Wear LG G Smart Watch, and had some minor trouble setting it up for development on Ubuntu Linux 14.04 - for too long, adb devices would just keep say "????????????    no permissions", and that "Allow Wear Debugging" pop-up on the Android Wear companion app on the phone would NEVER show. Then finally I it figured out, by doing an lsusb:

Bus 002 Device 023: ID 18d1:4ee7 Google Inc. 

that as the android.com doc says, an entry /etc/udev/rules.d/51-android.rules entry like so: 

SUBSYSTEM=="usb",ATTR{idVendor}=="18d1",MODE="0666", GROUP="plugdev"

is needed (even though I didn't have to do this for a non-Wear HTC phone; perhaps this is defaulted in Ubuntu somewhere?) - the trick was "just" that the Android Wear LG G Smart Watch needs the USB Vendor ID 18d1, which is Google's, and NOT LG's (1004) .. duh!



How to bulk install 1000 3rd party JARs to Maven local & deploy to remote repo

$
0
0
So for work @ day job, I wanted to make some code available in 1000 3rd-party (non-Mavenized) JARs available in a flat directory easily consumable from first a local and later remote Maven Nexus repository. As they would rebuild that directory daily, some sort of automated tool seemed like a good idea. (I'm not making this up; for historical reasons, a large internal product really was built as 1000 individual small JARs, each of a few 100 KBs, totalling ca. 200 MB. For typical organizational reasons, as this had been around for a little while already, write such a tool to post process instead of changing the actual build which produced them was easier). 

I started out with a throw away tool which produced a *.sh / *.bat with 1000x mvn install:install-file lines, but it turned out that running that script was REALLY slow - bloody JVM start-up time! :-( However, generating and running a pom.xml with 1000 <goal>install-file <executions> takes just few seconds, so that was the way to go. (There is probably some way to achieve the same using some Maven pure Java API too, or perhaps something based on Maven Polyglot - but the night wasn't long enough to figure out that route.)

To simplify depending on these JARs, the pom.xml generator in addition to the pom.xml which installs and deploys also generates another pom.xml, which lists all 1000 artifacts as <dependencies>. Also, because downloading 1000 small JARs from a Maven repo. e.g. for an integration test, can be slow, there is an alternative single JAR artifact, which contains them all-in-one. It turns out that the maven-assembly-plugin does the unzip-each-and-rezip-the-overlay thing out of the box. The maven-shade-plugin could have been used as an alternative to maven-assembly-plugin, but assembly seemed simpler. 

As a "side effect" of this effort, the duplicate-finder-maven-plugin can easily to be used to detect any duplicate classes within those 1000 JARs, including among other JARs from other internal projects, which were already available on Maven. (Actually detecting such errors which were biting us was the original motivation, and being able to use these JARs in integration tests was the side effect.)

Now to make this pom.xml generator tool easy to use for others, I've made it into a Maven plug-in wrapper itself. This just makes it easier to consume it, instead of having a separate JAR main(). More specifically, the plug-in actually generates two pom.xml files - one to install/deploy, and one to depend on them, do the duplicate check, and build the über-JAR. So together with the base one which generates the other two that's three pom.xml, which I just call in sequence via 3x mvn from a *.sh / *.bat. This is required due to the way Maven works - in a single Reactor, AFAIK, you cannot depend in a second module on a JAR which a first module will install. Likewise AFAIK Maven cannot somehow be told to "hot-reload" its current POM - thus the split like this.

I used the opportunity to have to write two (trivial, yes) pom.xml template-based generators to build this using Xtend Template Expressions, incl. gen. the Java for the Template Generator using the Xtend Maven plug (thanks) during the build of the Maven pom.xml Generator Plug-In. It's OK to have a little bit of fun and doing things properly! ;-) An alternative to all this may have been to use this as the opportunity to finally learn some more Gradlese .. which may allow some of this to be more dynamically scripted, but (re)learning Groovy more in-depth will have to wait for another time now. And I really like Xtend! :)

In case such a a pom.xml generator for bulk install and deploy of 3rd-party JARs could ever useful to anyone else, I've made the source code of this tiny little tool available as open source on https://github.com/vorburger/MavenBulkInstallDeploy.

Fixed Linux Ericsson H5321gw 3G/GPS/HSPA+ (e.g. in Lenovo ThinkPad X1 Carbon)

$
0
0
It's nice to have a 3G/GPS/HSPA+ card in your laptop for a working data connection on the go (without WiFi). For the ex-IBM/now Lenovo ThinkPad X1 Carbon, this is the Ericsson H5321gw. Here is how to get it working with Linux (here Ubuntu 14.04.2, others likely similar):

$ lsusb | grep Ericsson
Bus 002 Device 002: ID 0bdb:193e Ericsson Business Mobile Networks BV

$ sudo nano /etc/modprobe.d/avoid-mbib.conf
options cdc_ncm prefer_mbim=N

$ sudo cp /lib/udev/rules.d/77-mm-ericsson-mbm.rules /etc/udev/rules.d/ $ sudo nano /etc/udev/rules.d/77-mm-ericsson-mbm.rules

Now find a line with the comment "H5321gw", and copy one of the (two, in my case) existing rules and replace idVendor with 0bdb and idProduct with 193e, as per lsusb’s output above; so it will be:

ATTRS{idVendor}=="0bdb", ATTRS{idProduct}=="193e", ENV{ID_MM_ERICSSON_MBM}="1

The latter is very important as it avoids USB disconnects (Google, index this!) - curiously, it does work without this - for about 10s or so. So the USB device is found and then something disconnects it. If someone reading this can enlighten me more about the inner workings of USB / udev on Linux and can can explain this, I'd love to learn.

Reboot (for the modprobe.d thing; the udev is hot reloaded). Now use Modem Manager (tray icon), which shows “Mobile Broadband” (new), with the name of your provider greyed out. You create a New Connection, choose country Switzerland, provider... I had to change to APN, e.g. for Orange in Switzerland its "internet" - you can find this e.g. on your Android settings for your phone's SIM card.

I've opened this LP bug so that perhaps this can be set by default so that it works out of the box.

BTW: modem-manager-gui is a neat companion to standard Network Manager in this context.

PS: ACK tx to this post (hard to find, thus replicated here) and this site, and you're welcome there.

PPS: Yeah, I do know you also can tether the phone via cable (cumbersome every morning in transit..), or via Bluetooth (can't get that to work on Linux :), or via WiFi Hotspot sharing (sucks battery, hate having to fumble out the phone and open Settings etc. 'just' to get online - its one click with this solution).

Mifos standalone package how-to

$
0
0
A few months ago I blogged about the basic new Mifos executable WAR (based on MariaDB4j and Spring Boot). This post shows step by step how to use this simple standalone package deployment option, from scratch, if you would like to easily get the Mifos X platform incl. UI (MIFOSX-1756) running, on Windows, Linux or Mac OS X. (For more elaborate custom deployments, you or your Mifos X deployment partner probably want to learn about how to do the slightly more complicated "classic" WAR deployment using an EE Web Servlet container such as Tomcat, Jetty, WebLogic, WebSphere and an external database; this article outlines how to use a simpler self contained all-in-one route which incl. the database etc. Also, note the Mifos X Debian package, and its video.)

To build the Mifos X package from scratch yourself is easy:

1. Obtain the source code of the Mifos X API Java-based back-end platform (non-UI) from https://github.com/openMF/mifosx. You can "git clone" it from there, or alternatively you may simply download it from https://github.com/openMF/mifosx/archive/develop.zip.

2. Unzip, cd mifosx/mifosng-provider, and run gradlew -Penv=dev dist (this will download some stuff)

3. copy mifosx/mifosng-provider/build/distributions/mifosplatform-*.RELEASE.zip SOMEWHERE

To now use such a Mifos X package with a UI is equally easy:

1. unzip mifosplatform-*.RELEASE.zip
2. cd mifosplatform-*
3. cd apps
4. Obtain the source code of the Mifos X AngularJS-based UI from https://github.com/openMF/community-app. You can "git clone" it from there, or alternatively you may simply download it from https://github.com/openMF/community-app/archive/develop.zip, and unzip it into the apps/ directory (so you'll have a mifosplatform-*/apps/community-app/app/ ... folder).

5. java -jar mifosng-provider.war

Hackathon at the Mifos Summit 2015 in Sharjah, UAE

$
0
0
On the last day of the Mifos Summit 2015 in Sharjah, UAE, about 10 of the attendees got together for a 1 day "Hackathon". Several new developers incl. Kevin Kimani from  Resilient Business Systems Ltd. in Nairobi Kenya and Tsegaye Tamiru from Ethiopia were set up with a Mifos X Java development workspace and got introduced to Git 101 basics (fork, clone, branch, commit, push, pull requests etc.). Channa Gayan sent a pull request to fix the missing Java license header, and Gaurav Saini fixed a test failure in the AngularJS UI, both leading to green builds for everyone!

Tengiz from FINA in Georgia with help from Rishabh Shukla and support from Markus Geiss built an extension to the Mifos X Batch API so cover approving & activating savings accounts. Otar also from FINA together with Ishan Khanna, supported by Michael Vorburger fixed a long standing major pain point in our Android App which will allow its user to connect to servers with self signed SSL certificates. We also refactored the Android App to use less static methods.

Terence Monteiro from SanJose Solutions in Bangalore, India moved hard coded Mifos version number and release date to a JSON configuration file, and Michael Vorburger completed some shell scripts for the release distribution, which now includes both API back-end with embedded database as well as the UI front-end. All of this contributes to automated continuous integration release process of Mifos X, and benefits the simple standalone package, the Debian package, and future VM images.

The biggest feature that was worked on is the beginnings of geographic information system (GIS) support in Mifos. Ishan Khanna had already started with an extension to the Mifos X Android client which records the route a user has taken throughout the day. Anuruddha kindly offered to build the API back-end to store route coordinates for staff records. Gaurav Saini got started on integrating a Google Maps view into the community app.

Thanks to everyone - it was great to see you pooling in your energies to End Poverty 1 line of code at a time together!


Java 7 WatchService-based DirectoryWatcher implementation

$
0
0
When as part of my HoTea framework (otherwise unrelated to this post) I was looking for a simple Java utility to watch for and be notified about file changes in a given directory, I found that Java 7+ comes with a native / OS level file change notification WatchService API. Unfortunately it’s very “low level” and one cannot easily do something like this with it (using a Java 8 lambda expression instead of classic anonymous inner class for the listener):

new DirectoryWatcherBuilder().dir(dir).listener(
 (directory, changeKind) -> System.out.println(
      changeKind.toString() + "" + directory.toString()));

So I wrote it, see my DirectoryWatcher (created by DirectoryWatcherBuilder, implemented by DirectoryWatcherImpl, tested by DirectoryWatcherTest), currently part of HoTea - perhaps this is useful to others as well. Leave a comment here if it is, or better send a pull request against the project if you find anything worth enhancing or fixing (directory rename handling probably needs a bit more work).

PS: Apache Commons IO FileMonitor is something similar, but it uses a less effective approach of polling files from a background thread, instead of the Java 7 JDK's WatchService. (And Apache Commons VFS also seems to have another implementation of something very similar.) Google Guava does not yet seem to have such a utility. Larger frameworks like Spring integration, Apache Camel & Co. probably have similar utilities.
Viewing all 64 articles
Browse latest View live