hapi-fhir icon indicating copy to clipboard operation
hapi-fhir copied to clipboard

[Android] java.lang.NoSuchMethodError: No static method decodeBase64 when fetching Patient resource

Open jameswoody opened this issue 6 years ago • 5 comments

issue I'm building a personal health info app on Android using Android Studio. When trying a test to fetch a patient data from https://fhirtest.uhn.ca/, it fails on error: java.lang.NoSuchMethodError: No static method decodeBase64(Ljava/lang/String;)[B in class Lorg/apache/commons/codec/binary/Base64; or its super classes (declaration of 'org.apache.commons.codec.binary.Base64' appears in /system/framework/org.apache.http.legacy.boot.jar) at org.hl7.fhir.r4.model.Base64BinaryType.parse(Base64BinaryType.java:61) at org.hl7.fhir.r4.model.Base64BinaryType.parse(Base64BinaryType.java:38) at org.hl7.fhir.r4.model.PrimitiveType.fromStringValue(PrimitiveType.java:79) at org.hl7.fhir.r4.model.PrimitiveType.setValueAsString(PrimitiveType.java:135) at ca.uhn.fhir.parser.ParserState$PrimitiveState.attributeValue(ParserState.java:1288) at ca.uhn.fhir.parser.ParserState.attributeValue(ParserState.java:66) at ca.uhn.fhir.parser.JsonParser.parseChildren(JsonParser.java:1047) at ca.uhn.fhir.parser.JsonParser.parseChildren(JsonParser.java:952) at ca.uhn.fhir.parser.JsonParser.parseChildren(JsonParser.java:1035) at ca.uhn.fhir.parser.JsonParser.parseChildren(JsonParser.java:1016) at ca.uhn.fhir.parser.JsonParser.parseChildren(JsonParser.java:952) at ca.uhn.fhir.parser.JsonParser.doParseResource(JsonParser.java:183) at ca.uhn.fhir.parser.JsonParser.doParseResource(JsonParser.java:165) at ca.uhn.fhir.parser.BaseParser.parseResource(BaseParser.java:668) at ca.uhn.fhir.parser.BaseParser.parseResource(BaseParser.java:653) at ca.uhn.fhir.rest.client.impl.BaseClient$ResourceResponseHandler.invokeClient(BaseClient.java:578) at ca.uhn.fhir.rest.client.impl.BaseClient$ResourceResponseHandler.invokeClient(BaseClient.java:530) at ca.uhn.fhir.rest.client.impl.BaseClient.invokeClient(BaseClient.java:380) at ca.uhn.fhir.rest.client.impl.GenericClient.doReadOrVRead(GenericClient.java:134) at ca.uhn.fhir.rest.client.impl.GenericClient.access$2600(GenericClient.java:66) at ca.uhn.fhir.rest.client.impl.GenericClient$ReadInternal.execute(GenericClient.java:1535) at com.dtc.patientportalmobil.MyFhirHelper.searchPatient(MyFhirHelper.java:383) at com.dtc.patientportalmobil.HealthCenterFragment$MyAsyncTask.doInBackground(HealthCenterFragment.java:312) at com.dtc.patientportalmobil.HealthCenterFragment$MyAsyncTask.doInBackground(HealthCenterFragment.java:286) at android.os.AsyncTask$2.call(AsyncTask.java:333) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)  at java.lang.Thread.run(Thread.java:764) 

My code snippet Patient patient = client.read().resource(Patient.class).withId(id).execute();

Environment (please complete the following information):

  • HAPI FHIR Version 3.8.0 hapi-fhirandroid:3.8.0 hapi-fhir-structures-r4:3.8.0
  • OS: Android

Additional context Not every patient ID causes the error. And my guess is hapi-fhir-structures-r4 include the library commons-codec-1.11.jar, but Android's base framework include an old version commons-codec, which causes the conflict.

jameswoody avatar Aug 23 '19 08:08 jameswoody

I can confirm the cause of the issue, run into another related issue:

As fhir.core uses Base64.isBase64 from commons-codec 1.5+ and Android still ships with 1.3? (no android expert) this will break the android build at runtime if used with Binary resources. Possible solution would be to replace the usage of this method by another library in fhir.core in the checkValidBase64() method of the Base64BinaryType classes.

patrick-werner avatar Jun 18 '22 15:06 patrick-werner

@patrick-werner is that the only thing from commons-codec that is used in HAPI FHIR?

jkiddo avatar Jun 22 '22 20:06 jkiddo

The JPA server also uses commons-codec, but obviously that's not a concern here since I sure hope nobody's running that on Android. :)

I don't believe there are any other hapi-fhir-base uses of commons-codec aside from Base64 verification, parsing, and serializing in the datatype objects.

jamesagnew avatar Jun 22 '22 21:06 jamesagnew

I guess it would be feasible to extract simply that part of the code and embed it into the model class or a util class to make it easier shippable for Android?

jkiddo avatar Jun 22 '22 21:06 jkiddo

@jkiddo yes. Or switch Base64 handling to a extra library.

patrick-werner avatar Jul 09 '22 10:07 patrick-werner