HAPI FHIR Android client problems

370 views
Skip to first unread message

douglas.an...@gmail.com

unread,
Apr 2, 2016, 12:09:14 AM4/2/16
to HAPI FHIR
Hello,

I am attempting to build an Android-based client for a FHIR server, and am trying to use the HAPI FHIR client with HL7 DSTU2 data model, but am having many problems...
  • When I attempt to define the dependencies thusly (as is described in the docs, but with the version switched to the stable release):
compile group: 'ca.uhn.hapi.fhir', name: 'hapi-fhir-android', version: '1.4', classifier: 'dstu2'
 
I get this problem on build:
 
Error:(13, 35) error: package org.hl7.fhir.instance.model does not exist

So it appears that the HL7 DSTU2 data model is missing from the jar. 
 
  • However, if I define the dependencies thusly (like the regular client dependencies, but removing the problematical stax and woodstock libs, which clash with Android system classes):
compile ('ca.uhn.hapi.fhir:hapi-fhir-base:1.4') {
exclude module: 'stax'
exclude module: 'stax-api'
exclude module: 'woodstox'
exclude module: 'woodstox-core-asl'
}
compile ('ca.uhn.hapi.fhir:hapi-fhir-structures-hl7org-dstu2:1.4') {
exclude module: 'stax'
exclude module: 'stax-api'
exclude module: 'woodstox'
exclude module: 'woodstox-core-asl'
}
compile ('ca.uhn.hapi.fhir:hapi-fhir-validation-resources-dstu2:1.4') {
exclude module: 'stax'
exclude module: 'stax-api'
exclude module: 'woodstox'
exclude module: 'woodstox-core-asl'
}
 
However, even though the app builds and deploys OK, I get this problem at runtime:
 
java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/http/impl/conn/PoolingHttpClientConnectionManager;
        at ca.uhn.fhir.rest.client.RestfulClientFactory.getHttpClient(RestfulClientFactory.java:104)
        at ca.uhn.fhir.rest.client.RestfulClientFactory.newGenericClient(RestfulClientFactory.java:208)
        at ca.uhn.fhir.context.FhirContext.newRestfulGenericClient(FhirContext.java:378)
                              ...
 
This same code, with the same gradle dependencies config (except I didn't exclude the stax and woodstox modules) worked fine in a plain java application.

Has anyone had any recent success with using the HAPI FHIR client on Android, and if so, any idea how I can solve these issues?

Thanks,
Douglas Harley

Karl M. Davis

unread,
Apr 2, 2016, 5:14:33 AM4/2/16
to douglas andrew harley, HAPI FHIR
Douglas,

Coincidentally, I just ran across some information on your Android issue a few days ago. The problem is that Android includes, as part of its public API, a very old & buggy version of the Apache HTTPClient. Because that version is "baked in" to the classpath of all Android applications, it will always win if your app also tries to include a newer version. See this mailing list thread for more information: https://web.archive.org/web/20120614203130/http://old.nabble.com/HttpClient-in-Android-td27915358.html

FWIW, it sounds like they're finally fixing this in Android 6: http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client. You might try moving your dev to Android 6 and see if that resolves your problem.

If not, though, there's a fairly simple(ish) solution! You can use something like Maven's shade plugin to build an "Uber" JAR for your application, and leverage its bytecode rewriting/relocation feature to include HTTPClient in a different (and non-conflicting-with-Android's-SDK) package. Here's the documentation on that for the maven-shade-plugin: https://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html, and here's an example of me doing this exact thing (in a non-Android project, for different reasons): https://github.com/HHSIDEAlab/fhir-stress-test/blob/master/pom.xml#L146. For Gradle, it looks like the shadow plugin can accomplish the same thing: https://github.com/johnrengelman/shadow.

Best of luck tomorrow wrapping up your Codeathon entry!

Best regards,
Karl M. Davis



From: "douglas andrew harley" <douglas.an...@gmail.com>
To: "HAPI FHIR" <hapi...@googlegroups.com>
Sent: Saturday, April 2, 2016 12:09:14 AM
Subject: HAPI FHIR Android client problems

--
You received this message because you are subscribed to the Google Groups "HAPI FHIR" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hapi-fhir+...@googlegroups.com.
To post to this group, send email to hapi...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/hapi-fhir/5e156479-8917-4a4b-b657-35ee5d96c857%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

douglas.an...@gmail.com

unread,
Apr 2, 2016, 9:02:18 AM4/2/16
to HAPI FHIR, douglas.an...@gmail.com, ka...@justdavis.com
Thanks Karl...back at it again with the excellent and timely info. Unfortunately, I cannot move to Marshmallow due to my phone being on Lollipop, and I don't want to root it to update, so the shadow plugin it is.

Actually, I am not submitting an official code-a-thon artifact, just testing out community technologies, seeing what's up with and what others are working on with BlueButton on FHIR, and reporting everything back to the ONC DAF team (http://wiki.siframework.org/Data+Access+Framework+Homepage). However, hopefully I will have something cool to showoff when I go down to see the presentations and judging this afternoon.

Cheers,
Doug

douglas.an...@gmail.com

unread,
Apr 2, 2016, 9:57:40 AM4/2/16
to HAPI FHIR, douglas.an...@gmail.com, ka...@justdavis.com
As always with software, more complications: turns out the shadow plugin has to be used with either the java plugin, of the groovy plugin, but the android.application plugin is incompatible with both of these, so shadow cannot be used...I will instead just package-up the dependencies in a separate project, and then put it in a lib dir in the android app repo.

Doug

douglas.an...@gmail.com

unread,
Apr 2, 2016, 11:23:35 AM4/2/16
to HAPI FHIR, douglas.an...@gmail.com, ka...@justdavis.com
OK, finally got an Android client working with HAPI-FHIR client 1.4 using HL7 DSTU2 data model after doing the following:
  1. switched to JDK 7 (HAPI-FHIR needs to be compiled using JDK 8, so I previously had my dev environment setup to use that, but Android requires JDK 7)
  2. in separate previously-created java HAPI-FHIR client project I added the following build.gradle cfgchanges:
    • added buildscript cfg:
    • buildscript {
        repositories { jcenter() }
        dependencies {
          classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3'
        }
      }
    • added the shadow plugin:
      apply plugin: 'com.github.johnrengelman.shadow'
    • used this dependencies cfg:
      dependencies {
          compile 'ca.uhn.hapi.fhir:hapi-fhir-base:1.4'
          compile 'ca.uhn.hapi.fhir:hapi-fhir-structures-hl7org-dstu2:1.4'
          compile 'ca.uhn.hapi.fhir:hapi-fhir-validation-resources-dstu2:1.4'
          compile 'org.slf4j:slf4j-simple:1.6.1'
      }
    • added these tasks:
      task fatJar(type: Jar) {
          from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
          with jar
      }

      shadowJar {
          relocate 'org.apache.http', 'net.dfunkt.org.apache.http'
          relocate 'javax.xml', 'net.dfunkt.javax.xml'
      }
    • executed gradle command:
      gradle clean shadowJar
  3. copied the built jar from #2 above to android project's lib/hapi-fhir-client-all-1.4.jar
  4. made the following build.gradle cfg changes for the Android app:
  5. added to the android plugin's cfg defaultConfig:
    multiDexEnabled = true
  6. added to android plugin's cfg:
    packagingOptions {
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/NOTICE.txt'
    exclude 'META-INF/MANIFEST.MF'
    }

    dexOptions {
    javaMaxHeapSize "4g"
    }
  7. added following dependency:
    compile files('lib/hapi-fhir-client-all-1.4.jar')
Cheers,
Doug

douglas.an...@gmail.com

unread,
Apr 2, 2016, 10:06:53 PM4/2/16
to HAPI FHIR, douglas.an...@gmail.com, ka...@justdavis.com
I made a much more elegant fix by adding the HAPI-FHIR android client jar generation as a main project subproject (as is the android app project, that's Android Studio default behavior), and then having the android app subproject depend upon the client jar subproject...all the details can be found in this commit: https://github.com/douglas-andrew-harley/BlueButtonOnFHIRPrototype/commit/b658826bff59286ddd8c99ef9fb9f8b25891958c

Cheers (hopefully for the last time on this matter...),
Doug
Reply all
Reply to author
Forward
0 new messages