Stuff that should just work…

Had one of those Maven/Eclipse experiences that was so infuriating, I need to record it here to make sure I can fix it easily next time.

Using STS 2.9.1 I created a “Dynamic Web Module” project. For the runtime I targeted tc Server / Tomcat 6. Then I proceeded to do some rudimentary JSP stuff, only to find that the JSTL taglibs were not resolving. It seems the expectation is that these would be provided by the container. Under JBoss they probably would be, but not under Tomcat. (I guess it makes sense… if you have multiple apps in the container, just let each one bundle the version desired – fewer container dependencies).

Fine; so I added the maven nature and the jstl.jar dependency. At some point I did Maven > Update project configuration. Suddenly the class that I had defined to back a form is not found. Also I’m getting this really annoying project error:

Dynamic Web Module 3.0 requires Java 1.6 or newer. [...] Maven WTP Configuration Problem
One or more constraints have not been satisfied.

WTF? Of course STS/Eclipse are configured to use Java 1.6… but my project apparently isn’t. So I go change that, but it doesn’t fix that error, and any time I update project config with Maven, it’s back to using JRE 1.5 and my Java source files are no longer on the build path as source files.

Turns out (took longer to find than to tell about it) the Maven compiler plugin doesn’t use Eclipse settings and just imposes its own defaults, i.e. Java 5, unless otherwise configured by a POM. And since a “Dynamic Web Project” uses Servlet 3.0 it requires Java 6. Boom.

Easy to fix, though annoying that I have to and there isn’t some Eclipse setting for this. Just add under the top-level POM:

<build>
    <plugins>
       <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>2.1</version>
          <configuration>
             <source>1.6</source>
             <target>1.6</target>
          </configuration>
       </plugin>
    </plugins>
 </build>

(Cripes, WordPress, can I get a “code” formatting/paste option already?? “Preformatted” most certainly isn’t.)

Then have Maven update project config again and 1.6 is in play. Oh, and instead of using the “src” directory for my source, I went ahead and changed to src/main/java as Maven expects, so that future “config update” will pick that up.

Advertisements

Fiddling around with Cloud Foundry

In my spare work time the last couple days I’ve taken another good look at Cloud Foundry. I haven’t gotten to the code behind it yet, just putting it through its paces as a user. I’ve used the public cloud as well as running the virtual appliance (Micro Cloud Foundry), and the CLI as well as the STS/Eclipse plugin. It’s really a lot easier than I expected to get up and going (even the Eclipse part). I guess that’s the whole point!

When setting up the MCF appliance, I didn’t quite cotton on to what the DNS token was for (or, you know, read the docs). Cloud Foundry will apparently set up a wildcard DNS entry for you to point to your local instance.  Then you can point vmc/STS to api.{your-choice}.cloudfoundry.me and your web browser to the app URLs that come out of that, and they’ll actually resolve to the MCF VM on your local network (well, as long as you’re local too). That’s pretty cool, but I didn’t do that. I just set it up with a local domain name and added my own wildcard entry at my DD-WRT router. I had to look up how to do that – just pin the MAC address to an IP and add a line to DNSMasq config:

## wildcard for micro cloud foundry VM
address=/.mcf.sosiouxme.lan/172.31.0.140

The only trouble was that when I booted it up, I left the NIC at default config, which attaches it to a virtual network private to my workstation. I’d much prefer it available to my whole LAN, so I reconfigured it to bridge to the LAN. But then I had trouble getting MCF to accept its new address. It wasn’t clear how to do it – I don’t remember how I finally got it to work – something about offline mode. But eventually it accepted its new LAN address.

The example with the simple Ruby application is indeed simple: just install ruby and rubygems (required for the CLI anyway and even instructions for that are included!) and the Sinatra gem, and follow the instructions.

Rails proved to be a little more complicated, but mainly due to my setup. Rails 3.0 and 3.1 are supported. I had gem install Rails and got the latest: 3.2. It seems like this might work, except the simple app that you get with “rails new” uses coffeescript, which pulls in a native gem for the JS library, which can’t be bundled into the cloud app. The discussion at that link left me unclear how to remedy – remove the coffeescript gem? Wouldn’t that break stuff? Configure it to use a different JS lib via ExecJS? I wasn’t clear which, if any, of the options there wouldn’t have the same problem. Taking the path of least resistance here, I removed that rails gem and explicitly installed the most recent 3.0 instead.

This highlights one of the difficulties with a cloud platform… native code. If your code requires something that isn’t abstracted away into the platform and framework, you’re out of luck. Theoretically, you know nothing about the native host under the platform, so you can’t count on it. Just one of the prices you pay for flexibility.

Everything worked fine… except not quite? When I clicked the link to get application environment info, I didn’t get it:

Doesn’t seem to be routing that request, for some reason. It works fine if run with “rails server” naturally. Not sure what happened there, and didn’t want to mess with it just now.

Moving on to Grails and Spring MVC, I quickly set up sample apps in STS and tried them out on both the private and public instance. No problems.

The cool thing about having a local foundry, though, aside from being master of your domain, is that you can debug into your running app, which is vital if it is having a weird problem specific to the cloud environment. You just have to start the app in debug mode. The only hitch here, is that the Cloud Foundry servers don’t show up in the “Debug As… > Debug on Server” dialog:

And the “Connect to Debugger” button didn’t show up after starting the app in debug:

So, how to actually debug in? Well, it turns out it’s simple. The debugger *is* already connected to the app. I’m just not looking at the debug perspective because I couldn’t go the “Debug as…” route. I can explicitly open it (Window > Open perspective) or just set a breakpoint in the code and hit it with the browser (which automatically requests opening that perspective). Then I’m debugging as usual:

The “Connect to Debugger” button only shows up for the app when I disconnect the debugger and need to reconnect.

As far as I can tell, the Eclipse plugin has the same capabilities as the CLI, although the path may not be obvious, being a GUI. I did notice one little glitch that someone should fix (maybe me! in my copious spare time…) – if I open the foundry pane and there are no services, the services subpane is, of course, empty:

The glitch is that if I add a service (say, a MongoDB) it still doesn’t show up in the list, and I can’t then bind it to the application. I have to close the tab and re-open it by clicking on the server in the “Servers” pane (and go to the “Applications” tab… many levels of tab/pane here!):

You might have noticed the “caldecott” app sticking out above. That’s actually a bridge app for accessing services from the cloud directly. With the caldecott rubygem, you can open a tunnel between the foundry service (say a MySQL DB) and a port on your local host, such that clients (such as mysqldump) can directly access that service at that port (e.g. to make a backup or restore one). That will come in handy.

Also, just recently Cloud Foundry enabled running arbitrary workloads on the cloud (as long as they’re on supported platforms). It’s not just about webapps anymore! Another sweet development.

Fiddling around on Apr. 3rd

The “New Post” link at the top of WordPress goes to a new post form devoid of useful options. Now why would WordPress want to make that the standard?

Discovered today that some versions of Spring Insight (even developer version) wouldn’t deploy if the hostname it’s on doesn’t resolve properly in DNS. Doesn’t that describe most developer workstations? Version 1.5.1 doesn’t seem to have this problem though.

Discovered Eclipse/STS Window->Customize Perspective today. It lets me choose which things go on the top toolbar and the top menubars. It doesn’t let me re-order them, and it doesn’t seem to change the right-click context menus, but this does help clear up a lot of clutter. I don’t really use the toolbar – I should probably either remove it (can I do that?) or put really useful stuff on there. And now I kind of want to go through the list of items and find out what they all do…

I also got seriously derailed trying to change system appearance settings in Fedora. It really needs an “undo” button.

And I spent a bit of time fiddling with STS trying to bend the tc Server instances to my will. There doesn’t seem to be a guide anywhere to what all the terms mean. I think I’ll write one up tomorrow or sometime.

Checking out Hibernate with STS

I have cause to revisit my post about importing a git checkout into Eclipse. I need to take a look at the Hibernate code, which is on github at git://github.com/hibernate/hibernate-orm.git, and given the somewhat convoluted nature of this code, I need an IDE to help navigate it.

Now, I hear that with Eclipse Indigo (3.7), which is included with the latest STS 2.9 (which is what I use), the EGit plugin is included out of the box (which, for the purposes of this post, is what I’m doing – completely stock install). That’s helpful. See, previously, if you wanted to do something with git, you would find no evidence within Eclipse that it could. If you figured “there must be an extension for that” and searched for “git” from the extensions wizard, there would be no hits. Because what you needed to look for was “JGit” or “EGit” – you big dummy. An example of what I consider low discoverability that’s pervasive in Eclipse/STS. But I digress.

At least EGit has had a couple years to bake since my post. I went to File->Import->Git->Projects from Git and put in the URI above. This seems pretty straightforward:

Image

I’m not sure why it parses the URI into Host and Repository path here. Is there some reason you’d want to customize these?

In the next step, I pick the branches from the repo I want and proceed to the “local destination” dialog.

Image

These steps might be somewhat confusing to those who don’t know git and just want to take a look at some code. Since git is distributed, you don’t just get a point-in-time checkout from a repo, you get your own copy of the repo – or as much of it as you want. Basically it’s asking where I want my copy of the repository and checkout to go. The checkout (“initial branch” here) will go in the directory, and the repo will go in a .git subdirectory. “origin” is the name given to the repository I cloned this from, in case I want to sync with that later. That might be kind of obvious to someone familiar with git, but how about some tips for those who aren’t?

My question: why doesn’t this all simply default to being inside the workspace? What’s a workspace for, if not the project contents? As you can see, the default is to create a ~/git directory and checkout/clone the repo there.

Next step, three inscrutable options for how to deal with the resulting project(s) that have been checked out:

Image

OK. These seriously need some explanation. What do these do?

“Import existing projects” gets me nowhere in this case, as it requires Eclipse project descriptors to be included in the checkout, and they’re not. Arguably, they probably shouldn’t be. I just get the error “no projects found” if I try this. But that means I need to figure out myself how to get Eclipse/STS to interpret this checkout properly.

“Use the New Project wizard” is an option I don’t really understand. It just dumps you into the new project wizard you would get by clicking the new project button (generally the first button in the toolbar). This is also where you end up if you click “Finish” instead of “Next” anywhere along the way. I guess I could make use of the directory just created. I  also can’t go “back” and choose another option from here; cancel, and I’m back to square one. In general, I find the “New Project wizard” one of the most confusing things about Eclipse/STS, because there are so many options, many sounding similar yet meaning something completely different, and no explanations of what you can expect to get. Do I really have to go looking for doc that should be a click away? I digress.

“Import as general project” basically just creates a project with the given content and no organization. STS recognizes the different file types, of course, but there’s no concept of where the classpaths begin, how to build and test the project, anything like that – just plain directories with content. This won’t get me to my goal, which is to be able to look up class hierarchies, implementors of interfaces, etc. However, having done this, I can try to configure the project to get it to where STS understands these things.

I’m interested in the 3.6 branch of Hibernate, which is a Maven project (you can tell from the pom.xml – woe betide you in the Java world if you don’t recognize Maven when you see it. The “master” branch seems to be using Gradle). So I can right-click the project and Configure -> Convert to Maven Project.

By the way, let me point out something that didn’t work at all: creating a new project with the wizard “Maven -> Checkout Maven Projects from SCM”.

Image

This is apparently not aware of the EGit plugin, because there’s no SCM protocol listed here (the first box  is greyed out). If I click “Finish” here nothing happens except the dialog exits. I think it would probably work if I added a m2e SCM connector like the link suggests, but how would I know to do that?

Alright, so now I have a Maven project. Right away in the top-level pom.xml I get a “Project build error: Unresolveable build extension: Plugin org.jboss.maven.plugins:maven-jdocbook-style-plugin:2.0.0 or one of its dependencies could not be resolved: Could not find artifact org.jboss.maven.plugins:maven-jdocbook-style-plugin:jar:2.0.0 in central (http://repo1.maven.org/maven2)”. I happen to know what this is about because I know there are a bunch of JBoss dependencies not in Maven Central. How would I know that if I didn’t know? Google, I guess. Fortunately searching for that exact error message gets me right to a StackOverflow question about exactly the same thing, which someone has helpfully solved. I love SO, I just hate that it has to exist. Documentation is always about how to use something the right way, not what to do when something goes wrong. SO fills that gap.

So, add the repository information to the pom.xml – or, better, to my Maven settings.xml (which I had to create since STS is providing Maven in this setup) and on to the next problem. Two, actually (always seems to be the way of it – removing a build problem just uncovers more). These are related to “Missing artifact commons-logging”. A little Google sauce on that turns up this blog post (like the name, kinda like my blog!) about the death of the commons-logging dependency. Gotta love trying to support these old builds from a public ever-changing repo. Problem is, the Hibernate pom (actually the parent pom, which is in a subdirectory! huh?) uses the hack from that article, but the repo supplying the dummy dependencies seems to be down. So perhaps I should try the exclusions suggested by commentors in that blog? I found something that looks handy: in the pom dependency hierarchy, right-click and choose “Exclude Maven artifact”:

Image

Sadly, this doesn’t work:

Image

But here’s another StackOverflow suggestion. This seems to work, after removing the existing commons-logging dependencies and adding those ones in the parent pom, and (finally) right-clicking on the project, Maven -> Update project configuration. The errors are gone, and (I suspect) so is all the Maven-fu I can expect today.

Unfortunately I’m still not at my goal – I just have the Maven nature working now.

Turns out, this wasn’t quite the right path. What I’m looking at here are multiple Maven projects, with interdependencies. There’s no way I’m ever going to get anything useful from this in a single STS project. What I need to do is import these as multiple projects. In the meantime, delete the existing project (but leave the checkout) so it doesn’t get in the way.

So here’s what I do: File -> Import -> Existing Maven Projects and enter the path to my local checkout as the “Root Directory”:

If I select all the projects, they’ll all be created as interdependent workspace projects, each with build path and so forth configured according to Maven.

With lots of errors, of course… thousands, in fact. But let me start with the Maven problems, which are probably the source of the rest. Looks like all of the Maven errors are of the form “Plugin execution not covered by lifecycle configuration: org.jboss.maven.plugins:maven-injection-plugin:1.0.2:bytecode (execution: default, phase: compile)” – with a different plugin each time. I remember the import screen warned about some problems that would need to be resolved later – this seems to be what it was talking about.

Well, much later now, I think the Maven errors were mostly irrelevant. Those were due to the change to the m2eclipse plugin which broke the world for a lot of Maven users in Eclipse. Most of them were things that looked like it was safe to have m2eclipse “ignore” as recommended there. I went ahead and ran some of the goals that looked important (antrun:run and injection:bytecode in hibernate-entitymanager, the latter in hibernate-core) from the command line. Not sure they made much difference. I did Maven -> Update Project Configuration on everything changed and most of the red X’s went away.

I also ran into this problem and crashed a few times just by mousing over the “Window->Browser” menu before adding “-Dorg.eclipse.swt.browser.DefaultType=mozilla” to my STS.ini to avoid it.

At this point, the only problem seems to be that hibernate-entity has a ton of tests with imports like this:

import org.hibernate.ejb.metamodel.Customer_;
import org.hibernate.ejb.metamodel.Order;
import org.hibernate.ejb.metamodel.Order_;

… and then goes on to use these classes with underscores, which aren’t there. Evidently they’re supposed to be generated at some point, but I’m not sure how. I don’t really care about running these tests, just wanted to look at the framework code, so although STS reports 14382 Java problems, I can consider my work done here. Boy, that was easy!

One more note: I went back and added the git SCM connector for m2eclipse to try it out. It worked… but poorly. The way that worked was to select “git” for the scheme, then put in the git:// URI for the project, then wait for a popup to select the projects to import. If I reversed order or didn’t wait, I got either an error or nothing after hitting “Finish”. Hmm… hope that’s better in the next update. And, interestingly… the checkout/repo went into the workspace.

Android packaging and publishing

I’m giving a lightning talk on LogMyLife and other Android-y stuff this Friday at SplatSpace. I thought it’d be nice to allow people to download the app and try it out if they so desire, even though it’s still pre-release at this point. So I looked around on github and found where I could create downloads (in addition to the source download that’s automatic).

On a different machine from what I usually develop on, I created a new LogMyLife package. Actually, it wasn’t quite that simple, because I discovered my SDK debug keystore cert had expired. Which wasn’t quite that simple either, as I had to track down the error message (which I forget at this point). But, congrats me, I’ve been at this for a year now! Or not congrats so much, as I still don’t have a complete app on the market to show for it. But I have my excuses.

Anyway, I deleted the existing keystore and the Eclipse ADT plugin kindly made another one behind the scenes, and I carried on. I uploaded the package and got an error, but it seemed to have succeeded. The cool thing was when I found github automatically pulls a QRcode from a Google service for the uploaded APK:

So I can just include that in my slide and people can use their Android device’s barcode reader to scan it and download if they so desire. So can you while you’re looking at this.

Of course I tried this, and I tried it on my phone, where I already had LogMyLife installed. It downloaded and nicely showed me the permissions it needed and notified me it would replace the current app. Then it proceeded to fail to install. There wasn’t really an informative message, but I think I know what happened.

That key I was talking about earlier? Well, it was of course different on my two dev machines. I’m pretty sure the phone refused to install the app because the key had changed from what was previously installed. I would have to un-install the app in order to install the version signed with a different key. Which leads me to wonder whether I’ll have the same problem once I sign it with my official market signing key for release? I don’t want to lose what data I already have been collecting on my phone, so if that’s the way it will be, I’m gonna be prioritizing the “Export/import data” feature way up.

I went ahead and signed up for an Android Market account finally. I’ll probably post something for beginners about the process on my neglected “Android from scratch” blog at some point. It’s pretty simple, but you don’t know what your $25 gets you to start with. Strangely enough, there doesn’t seem to be anything about signing your app on the market site. There is on the dev site, of course. It seems somewhat complicated to do by hand, but pretty simple from the Eclipse plugin. Nothing seems to mention what happens when you change keys – what the practical consequences of doing that would be. I’ll find out soon enough. Just for fun I tried uploading my dev LogMyLife.apk, and received only the error message “Upload a valid APK.” I guess if you don’t know about this stuff they’re not gonna help you find it!

#Androiddev fiddling – package deploy error and using preferences

Hit an error this morning when deploying an Android project:

WARN/ResourceType(586): Bad XML block: header size 28024 or total size 1702240364 is larger than data size 776
WARN/PackageParser(586): Unable to read AndroidManifest.xml of /data/app/vmdl39451.tmp
WARN/PackageParser(586): java.io.FileNotFoundException: Corrupt XML binary file
WARN/PackageParser(586):     at android.content.res.AssetManager.openXmlAssetNative(Native Method)
[…]

ERROR/PackageManager(586): Couldn’t find a package name in : /data/app/vmdl39451.tmp

Eclipse had also given me some kind of error about being unable to parse the output of aapk and to check console output. I’ve deleted console output so I don’t remember what was there, but I’m not sure it was illuminating. This was pretty confusing. I played around with cleaning the project in Eclipse; I tried creating the apk myself to see if I got any interesting errors:

[luke@7of9 Listviews]$ apkbuilder bin/Listviews.apk -rf .
Using keystore: /home/luke/.android/debug.keystore
[luke@7of9 Listviews]$ ls -l bin
total 40
-rw-rw-r–. 1 luke luke  5060 Sep  5 07:54 classes.dex
-rw-rw-r–. 1 luke luke 18925 Sep  5 08:49 Listviews.apk
drwxrwxr-x. 3 luke luke  4096 Sep  5 07:52 net
-rw-rw-r–. 1 luke luke  6995 Sep  5 07:54 resources.ap_
[luke@7of9 Listviews]$ adb install -r bin/Listviews.apk
250 KB/s (18925 bytes in 0.073s)
Can’t dispatch DDM chunk 46454154: no handler defined
Can’t dispatch DDM chunk 4d505251: no handler defined
pkg: /data/local/tmp/Listviews.apk
Failure [INSTALL_FAILED_INVALID_APK]

Alas; not very helpful. But somewhere along the way, I did get something useful:

Parser exception for /Listviews/AndroidManifest.xml: The element type “activity” must be terminated by the matching end-tag “</activity>”.
org.xml.sax.SAXParseException: The element type “activity” must be terminated by the matching end-tag “</activity>”.

Ah – now that I can understand and do something about. Not sure why Eclipse didn’t give me a heads up on that. Adding that extra slash fixed everything :-)

Preferences

For some reason there’s virtually no documentation I can find in the developers guide about the handy Preferences activity and resource type. What I know I get from Ed Burnette’s book Hello, Android; and frankly that’s not too detailed about what’s going on.(OK; I found some very general stuff here and more specifics about using the activity and resource in the PreferenceActivity reference docs.)

This was a problem when I tried to set up my Preferences activity and got a runtime exception after choosing a setting from a list.

ERROR/AndroidRuntime(931): java.lang.NullPointerException
ERROR/AndroidRuntime(931):     at android.preference.ListPreference.onDialogClosed(ListPreference.java:218)
ERROR/AndroidRuntime(931):     at android.preference.DialogPreference.onDismiss(DialogPreference.java:359)
ERROR/AndroidRuntime(931):     at android.app.Dialog$DismissCancelHandler.handleMessage(Dialog.java:946)

[…]

Those are all Android classes – none of mine are in the mix. The pref I tried to change comes from this specification:

<ListPreference
android:key=”layout”
android:entries=”@array/layout”
android:entryValues=”@array/values”
android:title=”Layout”
android:summary=”Which layout do you want?”
/>

Nothing obviously wrong. It occurred to me, though, that the values array there is an integer array, while the entries are, naturally, strings (for the user to see).  I tried changing the values to strings (and then parsing the prefs into integers when they come out) and this seemed to work fine. So evidently you can’t use integer arrays directly as entryValues on a ListPreference.