0

This has been killing me all day. I am working on android / java in eclipse.

This is what I want to do

  • I want to embed one of my libraries - DatabaseLibrary

  • within another of my libraries - LogicLibrary

Crucially - without exposing any of the methods in DatabaseLibrary to a 3rd party who has access to the LogicLibrary.


I have tried including it using the proguard-maven-plugin like this

 <configuration>
                <assembly>
                 <inclusions>
                     <inclusion>
                         <groupId>xxx</groupId><artifactId>DatabaseLibrary</artifactId><library>true</library>
                     </inclusion>
                 </inclusions>
             </assembly> 

However this includes all methods into the DatabaseLibrary and exposed them to a 3rd party.

I want my LogicLibrary to be able to call against the DatabaseLibrary without the 3rd party ever seeing it.

I have searched all over the web and it seems like something called an uber jar is what i need to do. However I have tried a few methods such as maven-assembly-plugin mentioned here https://stackoverflow.com/a/1834905/1312937

maven embed dependency artifact code in jar

However I have got no where with this, it looks like it is a maven 2 answer so maybe there is something different i need to do for maven 3?

Can anyone tell me if uberjar is the correct way for me to achieve my aims? If there are alternate patterns please let me know, im not tied into maven.

Community
  • 1
  • 1
Aiden Fry
  • 1,672
  • 3
  • 21
  • 45

3 Answers3

1

The Java classpath just doesn't work the way you think it does. You can't 'hide' one of the jar files, and still have it accessible.

The 'uberjar' concept is to simply decompress all of the jar files, and then add all of the classes / resources to one big jar file.

Unfortunately, I'm not aware of any way to limit access to a jar file.

GreyBeardedGeek
  • 29,460
  • 2
  • 47
  • 67
  • Ok maybe this uberjar is incorrect, surely i can have a jar which references another jar without exposing this internal jar to the user though? Or maybe the uberjar is the correct way to go as i can let the obsufcation/access modification stage of my maven build to make private all my methods & classes apart from the few public facing ones in the outer jar that i want the user to be able to use. – Aiden Fry May 28 '13 at 13:28
  • No, I'm afraid that there is no special status that you can confer on a particular jar file, nor any good way to both give it to the user and 'hide' it from them. AFAIK, If you *need* that sort of control, you'll need to use something other than Java. Making Java methods private doesn't really stop anyone but the casual observer from invoking them. – GreyBeardedGeek May 28 '13 at 23:52
1

I think the uber jar is the wrong route. Instead to accomplish your goal of hiding methods from the DatabaseLibrary but make them accessible to your Logic I would declare your methods as "protected" which limits its visibility to the package level. Given that you would make sure that any classes that needed to talk between jars were within the same package (though in seperate jars). This will force a 3rd party vendor only to use the public methods that are available to them.

- DatabaseLibrary
  |- com.mycompany
      |- DatabaseClass

-LogicLibrary
  |- com.mycompany
      |- LogicClass


 public class DatabaseClass{
    protected void doSomething(){
    }
 }

 public class LogicClass{
    public void doSomething(){
       DatabaseClass dbClass = new DatabaseClass();
       dbClass.doSomething();
    }
 }

Now you're 3rd party vendor will only see LogicClass.doSomething()

See also: http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

jsurls
  • 365
  • 2
  • 11
  • Thanks this looks like it is what I am likely to do. I shall award you the points for being helpful, thanks to the other respondents too you information will be vital! – Aiden Fry May 29 '13 at 16:18
0

This might not apply to Android, because I am not 100% sure how classloaders in Android work. But this idea should work in Java in general.

So what you want to do it so create a a classloader that will allow your classes inside LogicLibrary to load the DatabaseLibrary. There are few solutions, One-Jar being one of them: http://one-jar.sourceforge.net/ This one allows you to pack one jar into another and then uses a custom classloader to load a jar within "uber" jar. In one of your links there's another link how to create this using maven assembly.

I did not use it, so I am not sure it will suit your needs. But what you can do is to create your own classloader that will decrypt encrypted JARs, or verify signature or use whatever mechanism you need. You can even put your library into a password-protected zip file and let the classloader uncompress it. Using the custom classloader is a way to go.

You can use maven assembly plugin to simply decompress one Jar, include another Jar and then package it back (and then use custom classloader). But it won't protect the Jar much...

MartinTeeVarga
  • 10,478
  • 12
  • 61
  • 98