Monday, August 18, 2008

android to the rescue!

Moving right along. The problem with this exception:
java.lang.NoClassDefFoundError: com/google/gdata/client/http/GoogleGDataRequest$GoogleCookieHandler
isn't really a problem with that class. The underlying problem is listed at the bottom of the exception stack, and is really this:
Caused by: java.lang.ClassNotFoundException: java.net.CookieHandler not found in java.lang.ClassLoader$1{urls=[file:/usr/share/java/sqlite.jar,file:/usr/share/java/jocstrap.jar,file:/usr/share/java/uicaboodle.jar,file:/usr/share/java/gdata-core.jar,file:/usr/share/java/gdata-client.jar,file:/usr/share/java/gdata-contacts.jar,file:/private/var/stash/Applications.sM60eV/dmSync/dmsync-0.1.jar], parent=null}
Which is to say, jamvm can't instantiate the GoogleCookieHandler class because it can't find the java.net.CookieHandler class. Digging around, it looks like this is not implemented in the classpath classes. I did find a copy in the android jar though:
root@thistle 15> jar tvf android-sdk-linux_x86-0.9_beta/android.jar | grep java/net/CookieHandler.class
1579 Thu Aug 14 18:56:36 GMT 2008 java/net/CookieHandler.class
I got that by downloading the android software from http://code.google.com/android/download_list.html. Happily, putting this in place gets me most of the way there. Now the java program when run on the iphone gives me this:
root@iphone 21> java -cp /usr/share/java/sqlite.jar:/usr/share/java/jocstrap.jar:/usr/share/java/uicaboodle.jar:/usr/share/java/gdata-core.jar:/usr/share/java/gdata-client.jar:/usr/share/java/gdata-contacts.jar:dmsync-0.1.jar:/tmp/android.jar net.dmsync.dmSync
foo!

ContactsService 4
setUserCredentials
createContact
creating contact
setting email 1
setting email 2
creating URL
inserting contact
stupid! you got an exception! java.lang.NullPointerException: Parser argument must not be null
I was bummed that I was still getting an exception, until I tried running it a second time, and it coughed up an error about how the record had to be unique. This clued me in to the fact the java program had actually worked! I checked my google contacts list and found the "aaaa" entry that the program had tried to add: woo hoo!

Sunday, August 17, 2008

private classes?

The problem with this exception:
com.google.gdata.util.AuthenticationException: Error connecting with login URI
turned out to be that the modified cacerts file I was using (see this post) didn't have the right certificates in it, since I had only imported a single certificate. When I imported the rest (effectively creating a gkeytool-compliant version of the certificates that were in the keytool-version), that error went away.

Now my program can successfully authenticate to Google, create the contact and ... not quite insert it. I'm up to this:
root@iphone 24> java -cp /usr/share/java/gdata-core.jar:/usr/share/java/gdata-client.jar:/usr/share/java/gdata-contacts.jar:dmsync-0.1.jar net.dmsync.dmSync
foo!

ContactsService 3
setUserCredentials
createContact
creating contact
setting email 1
setting email 2
creating URL
insertig contact
java.lang.NoClassDefFoundError: com/google/gdata/client/http/GoogleGDataRequest$GoogleCookieHandler
at com.google.gdata.client.http.GoogleGDataRequest.(Unknown Source)
I've tried some different versions of class imports, but this doesn't seem to help:
import com.google.gdata.client.http.GoogleGDataRequest;
import com.google.gdata.client.http.GoogleGDataRequest.*;
and if I make it more explicit, like so:
import com.google.gdata.client.http.GoogleGDataRequest$GoogleCookieHandler;
I get this error on compiling:
[javac] Compiling 1 source file to /usr/src/iphone/dmsync/build/classes
[javac] /usr/src/iphone/dmsync/src/java/net/dmsync/dmSync.java:24: com.google.gdata.client.http.GoogleGDataRequest.GoogleCookieHandler has private access in com.google.gdata.client.http.GoogleGDataRequest
I hate it when I don't understand java enough to parse the meaning of this. :(

gkeytool versus keytools

Hmm, I first tried working around the missing cacerts file by simply copying the file I have on linux to the iphone:
scp /etc/java-6-sun/security/cacerts iphone://tmp
However, running with that gave me this error:
java.lang.RuntimeException: java.lang.RuntimeException: error instantiating default socket factory: java.security.KeyManagementException: java.security.KeyStoreException: gnu.javax.crypto.keyring.MalformedKeyringException: incorrect magic
This smacked of some binary incompatibility, and I was worried it was some endian problem. However, after futzing around a bit, I began playing around with gkeytool, I noticed that the problem seems to be a binary incompatibility between the keystore formats used by gkeytool (the key signing tool that comes with the GNU classpath package) and keytool, which comes with Sun's Java. I can list the keys in the (working) cacerts file on linux:
root@thistle 25> keytool -list -keystore /etc/java-6-sun/security/cacerts
Enter keystore password:

***************** WARNING WARNING WARNING *****************
* The integrity of the information stored in your keystore *
* has NOT been verified! In order to verify its integrity, *
* you must provide your keystore password. *
***************** WARNING WARNING WARNING *****************

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 55 entries

aolrootca2, Mar 26, 2008, trustedCertEntry,
Certificate fingerprint (MD5): D6:ED:3C:CA:E2:66:0F:AF:10:43:0D:77:9B:04:09:BF
aolrootca1, Jan 17, 2008, trustedCertEntry,
Certificate fingerprint (MD5): 14:F1:08:AD:9D:FA:64:E2:89:E7:1C:CF:A8:AD:7D:5E
secomscrootca1, May 1, 2008, trustedCertEntry,
However, trying the same thing with gkeytool on linux fails with the same "bad magic" message I get on the iphone:
root@thistle 26> gkeytool -list -keystore /etc/java-6-sun/security/cacerts
Enter key store password:
keytool error: gnu.javax.crypto.keyring.MalformedKeyringException: incorrect magic
So I tried exporting a key from the working cacerts file on linux using keytool, and then importing to a new cacert file on linux using gkeytool:
root@thistle 6> keytool -export -keystore /etc/java-6-sun/security/cacerts -alias godaddyclass2ca > godaddyclass2ca
...
root@thistle 7> gkeytool -import -keystore hope.cert -file godaddyclass2ca -alias godaddyclass2ca
Enter key store password:
Owner: C=US,O=The Go Daddy Group, Inc.,OU=Go Daddy Class 2 Certification Authority
...
root@thistle 22> gkeytool -list -keystore hope.cert
Enter key store password:
Key store type: gkr
Key store provider: GNU-CRYPTO

Key store contains 1 entry(ies)

Alias name: godaddyclass2ca
Creation timestamp: Sunday August 17, 2008 AD - 9:03:36;754 o'clock PM GMT-04:00
Entry type: trusted-certificate
Certificate fingerprint (MD5): 91:DE:06:25:AB:DA:FD:32:17:0C:BB:25:17:2A:84:67
Which looks ok: the certificate fingerprint looks right. So, then I tried copying that certificate file to the iphone:
root@thistle 24> scp hope.cert iphone://opt/java/lib/security/cacerts
hope.cert 100% 1179 1.2KB/s 00:00
and then re-run the java program on the iphone tries to login to google:
root@iphone 15> java -cp /usr/share/java/gdata-core.jar:/usr/share/java/gdata-client.jar:/usr/share/java/gdata-contacts.jar:dmsync-0.1.jar net.dmsync.dmSync
foo!

ContactsService
setUserCredentials
com.google.gdata.util.AuthenticationException: Error connecting with login URI
Woo! Different exception, so hopefully I'm past the previous problem. Still have to figure out the new one though...

Saturday, August 16, 2008

Kyping code largely from google, I have a java program that can add a contact to google, yay! However, there's problems getting it to work on the iphone:
root@iphone 18> java -cp /usr/share/java/sqlite.jar:/usr/share/java/jocstrap.jar:/usr/share/java/uicaboodle.jar:/usr/share/java/gdata-core.jar:/usr/share/java/gdata-client.jar:/usr/share/java/gdata-contacts.jar:dmsync-0.1.jar net.dmsync.dmSync
foo!

java.lang.ExceptionInInitializerError
at com.google.gdata.client.Service.(Unknown Source)
at com.google.gdata.client.GoogleService.(Unknown Source)
at com.google.gdata.client.contacts.ContactsService.(Unknown Source)
at com.google.gdata.client.contacts.ContactsService.(Unknown Source)
at net.dmsync.dmSync.main(dmSync.java:37)
Caused by: java.util.regex.PatternSyntaxException: At position 10 in regular expression pattern:
At position 0 in regular expression pattern:
unsupported name ASCII
^[\p{ASCII}&&[^\p{Cntrl} ;/=\[\]\(\)\<\>\@\,\:\"\?\=]]+$
^
Looks like some part of the iphone java stuff (jamvm?) doesn't like {ASCII} as a character class. It's only used a couple times in the google java code, in src/com/google/gdata/util/ContentType.java and src/com/google/gdata/util/AuthenticationException.java, so I've gone through and modified those to replace the regexes with equivalents. I changed this:
[\\p{ASCII}&&[^\\p{Cntrl} \t;/=\\[\\]\\(\\)\\<\\>\\@\\,\\:\\\"\\?\\=]]+
to this:
[!#\\$%&'\\*\\+-\\.0-9A-Z_`a-z\\{\\|\\}\\~]
And hey, now it gets past that point, and fails on:
root@iphone 20> java -cp /usr/share/java/sqlite.jar:/usr/share/java/jocstrap.jar:/usr/share/java/uicaboodle.jar:/usr/share/java/gdata-core.jar:/usr/share/java/gdata-client.jar:/usr/share/java/gdata-contacts.jar:dmsync-0.1.jar net.dmsync.dmSync
foo!

java.lang.RuntimeException: java.lang.RuntimeException: error instantiating default socket factory: java.security.KeyManagementException: java.security.KeyStoreException: java.io.FileNotFoundException: /opt/java/lib/security/cacerts

Thursday, August 14, 2008

libgdata-java and basic ant project

I finished repackaging the libgdata-java package, so that it has a pre-requisite of jamvm, and was able to install it on the iphone:
root@iphone 32> dpkg -l | grep libgdata-java
ii libgdata-java 1.20.0-2 simple standard protocol for reading and wri
Its install location is all the same, all I did was add a single line to the control file:
root@thistle 45> diff orig/libgdata-java-1.20.0/debian/control libgdata-java-1.20.0/debian/control
17c17
<> java-gcj-compat | java1-runtime | java2-runtime | jamvm
Then I sketched up a basic ant build directory, with a trivial java class in it, and prepare targets for building and installing:
root@thistle 37> ant clean build install
Buildfile: build.xml

init:

clean:
[delete] Deleting directory /usr/src/iphone/dmsync/build

init:

build:
[mkdir] Created dir: /usr/src/iphone/dmsync/build/classes
[javac] Compiling 1 source file to /usr/src/iphone/dmsync/build/classes
[jar] Building jar: /usr/src/iphone/dmsync/build/dmsync-0.1.jar
[mkdir] Created dir: /usr/src/iphone/dmsync/build/Applications
[mkdir] Created dir: /usr/src/iphone/dmsync/build/Applications/dmSync
[copy] Copying 2 files to /usr/src/iphone/dmsync/build/Applications/dmSync

init:

build:
[javac] Compiling 1 source file to /usr/src/iphone/dmsync/build/classes
[exec] ln: creating symbolic link `build/Applications/dmSync/Java': File exists
[exec] Result: 1

install:
Installing just scp's the files over to the iphone. Once there, the package can be run:
root@iphone 30> /usr/bin/java -Xmx8M -Xss256K -cp /Applications/dmSync/dmsync-0.1.jar net.dmsync.dmSync
foo!

Tuesday, August 12, 2008

New Template

I futzed with the template, long enough to get blockquotes to mimic code segments for me: fixed width font, inset, different background, and in green. Also widened the column, and tidied up the sidebar. God I hate sidebars...

Blinds and Packaging

I finished mounting the venetian blinds thingy to the outside edge of my deck. This nicely blocks off the twit neighbor that leaves his backyard light on all the time. In your face extra light!

I also built my first debian package, in the service of dmsync. "dmsync", hmm, not sure about that name. Unfortunately ksync was already taken. I had problems with the build initially, it was complaining about:
root@thistle 24> dpkg-deb -b pkg
warning, `pkg/DEBIAN/control' contains user-defined field `Name'
warning, `pkg/DEBIAN/control' contains user-defined field `Author'
dpkg-deb: building package `net.dmsync' in `pkg.deb'.
dpkg-deb: control directory has bad permissions 2755 (must be >=0755 and <=0775)
But I couldn't change the permissions:
root@thistle 38> ls -ld .
drwxr-sr-x 3 root src 72 Aug 12 23:03 ./
root@thistle 39> chmod 0755 .
root@thistle 40> ls -ld .
drwxr-sr-x 3 root src 72 Aug 12 23:03 ./
WTF? Anyway, I worked around it by recreating the directory. Stupid permissions...

And then, since the libgdata-java package wouldn't install on the iphone because none of its jvm dependencies were met, I figured out how to rebuild a package, which essentially is:
root@thistle 21> apt-get source libgdata-java
...
root@thistle 22> cd libgdata-java-1.20.0
root@thistle 21> dpkg-buildpackage -b
...
Next step is to tweak the dependencies in the build file, and see if I can get it to install on the iphone.

Monday, August 11, 2008

MFF 2008

The MFF 2008 invite video is done, the page is prepared, and the email is sent. Booya!

http://denism.homeip.net/mff/2008.html

Sunday, August 10, 2008

Some Victory

“Be ashamed to die until you have won some victory for mankind."
- Horace Mann

Blog Archive