6

I appreciate that this might sound absurd, but is it possible to drop two different versions of a .jar library into an Android project (where both versions obviously have identical or overlapping package and class names), and somehow explicitly point to one of them when importing the library's classes into my own Java sources?

My development environment is Android Studio with Gradle.

My reason for considering doing this (if it is possible) is because I rely on a closed-source vendor-supplied .jar driver library for a USB device that my Android application works with. The vendor has added support for newer chip versions in their latest driver, but at the same time they have dropped support for older chip versions. This is a decision they have made for their own good reason and it is unlikely to be reversed. An idea I have is to somehow carry both old and new versions of the library in my application so that I can continue to support the older hardware.

I suppose something like this would be theoretically possible, but a complicated affair, perhaps requiring one .jar to be decompiled and package names changed?

Trevor
  • 10,903
  • 5
  • 61
  • 84
  • 1
    You would need to use something like **`jarjar`** to repackage one of the JARs, short of playing some nasty classloader games. – CommonsWare May 07 '15 at 19:53
  • The order of those JAR files in CLASSPATH matters. Which ever comes first, that JAR classes will be loaded (since the namespace is same). – K139 May 07 '15 at 19:57
  • Thanks gents, your input is much appreciated. The `jarjar` suggestion is a very interesting one. – Trevor May 07 '15 at 19:59
  • Interesting question. I'd ask you if you have the original sources to the jar file. How does the decompiled version look like, is it readable? – Bojan Kseneman May 07 '15 at 20:03
  • I don't have the sources unfortunately. I must admit I haven't attempted to decompile it yet. I've just grabbed jarjar, though, to give that a try. – Trevor May 07 '15 at 20:09
  • I seem to have had success! Answer now provided. Thanks for your terrific help. – Trevor May 07 '15 at 20:53
  • another option is to include the jar as a resource, to copy it somewhere at runtime, and to load it afterwards with PathClassLoader – njzk2 May 07 '15 at 20:56

1 Answers1

6

To my amazement, I've very quickly had success at this using the jarjar utility as suggested by CommonsWare.

The key in understanding how to do this was this QA:

Hand Edit A Jar to Change Package Names

I renamed one of my .jars using the directions given above and I now have them both sat side by side in my project.

I don't want to duplicate SO content, but for completeness, I did the following:

Obtained the latest version of jarjar.

Created a configuration file called rules.txt containing a single line:

rule uk.co.dog.** uk.co.cat.@1

That's just an example. Given a .jar with the package uk.co.dog.*, the dog will change to cat. Obviously change this to suit your real case.

Then use the command line:

java -jar jarjar.jar process rules.txt in.jar out.jar

Where in.jar is the source .jar and out.jar is the transformed one.

Community
  • 1
  • 1
Trevor
  • 10,903
  • 5
  • 61
  • 84