1

I have an AAR library that depends on a certain lib.jar. I added it in my AAR by doing:

dependencies {
    implementation files('myexternallibs/lib.jar')
    ...
}

In the resulting AAR, I can still access the classes in lib.jar. Based on many answers here in SO, the keyword implementation should keep this from happening. Anything I missed?

user1506104
  • 4,616
  • 2
  • 49
  • 67

4 Answers4

1

implementation will prevent from accessing libraries implemented by lib.jar, not this library

For example:

Library1
  |-> Class1
  |-> Class2

Library2 (implementation 'Library1')
  |-> Class3 (this library can access Class1 and Class2)

YourProject (implementation 'Library2')
  |-> Main (this library can access Class3, but not Class1 and Class2)
Martin
  • 562
  • 7
  • 24
  • @user1506104 can you please define what does `I can still access the classes in lib.jar` mean? Can you access lib.jar classes or also its depedencies classes? – Martin Oct 10 '18 at 17:52
  • yes, this is similar to my case. I have lib.jar (Library1 in your diagram). It is a dependency of my project which generates an .aar by using "implementation 'lib.jar' (Library2 in your diagram). From that project, I can access lib.jar's classes. When I generate an .aar from this project and use it in project2 (YourProject in your diagram), I can still access the classes from lib.jar even if I used "implementation project.aar". – user1506104 Oct 10 '18 at 18:15
  • @usee1506104 I think it's caused by generating .aar. I think implementation is designed for modules and repositary depedencies because generating .jar (I don't know if it's same for .aar) will put all classes together (even inherited ones). – Martin Oct 10 '18 at 18:21
1

ordinary implementation should be used, along with a properly written & built library.

simply adding the .jar code as a Java module might be the most easy -

in order to provide full control which methods are accessible.

see the Java Library Plugin.

Martin Zeitler
  • 49,224
  • 12
  • 97
  • 156
  • @user1506104 most libraries are not obfuscated; see http://plugins.jetbrains.com/plugin/7100 - unless you can control it's build, you won't gain full control over what is being accessible; double-wrapping (as suggested by @Martin) might be an option - but appears to be a little crappy. never tried that, just wonder what the implications would be. – Martin Zeitler Oct 10 '18 at 18:12
0

Have you defined the api?

See the example from gradle site: https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation

dependencies {
    api 'commons-httpclient:commons-httpclient:3.1'
    implementation 'org.apache.commons:commons-lang3:3.5'
}
Deian
  • 848
  • 9
  • 24
0

I changed implementation to compileOnly. It worked.

Note from documentation:

If you use this configuration, then your library module must include a runtime condition to check whether the dependency is available, and then gracefully change its behavior so it can still function if it's not provided.

To do this, you need to check the classpath like so:

try {
    Class.forName("com.company.ClassName");
}
catch (ClassNotFoundException ex) {
    // class is not available
}
user1506104
  • 4,616
  • 2
  • 49
  • 67