Minimizing external JAR by removing all non-dependent classes from source code - java

I have an Android project which requires Apache's POI external JARs (libraries used to read and manipulate MS Office files, but that's irrelevant).
Upon compilation I get an error stating that my project has over 65536 method declarations - I only have a few dozens and the rest are from the external libraries.
I only need a fraction of the functionality of POI so I downloaded the full source code and imported it into Eclipse. I have a list of classes I'd like to keep, however each one of these classes depends on other classes in the code, and I can only assume that these classes also have dependencies.
Is there a way to clean the source code so I'd keep only the classes I need and all their dependencies (without manually tracking each dependency, as there are a lot of them)?
P.S - I've looked at this question but it deals with compiled JARs and I also have the source code.

Related

Add Native Shared Library (.so or .dll/.lib) to Jar File Using Maven Plugin

There are lots of posts about this already but I have not found one that describes my exact situation. Which is:
I have a preexisting build system that generates a C++ shared library in both .dll and .so format (depends on OS).
The build system also produces a set of java files generated by swig.
I also have a pom.xml file that builds the java source into a package.
What I need is a plugin for maven that simply copies the native shared library into the jar. It would be nice if the native shared library was also loadable from within the jar so clients don't have to manually add it to the library path. This seems like a problem that has been solved before.
I have looked at maven-dependency-plugin. Which seems to be able to copy artifacts that are in a maven repository (not my case). Or if you use an assembly it might be possible. However, if it is possible, it seems overly complicated for what I want to accomplish. I would like to accomplish it with only a pom.xml.
I have also looked at nar-maven-plugin, but this seems like it focuses only on building the native library and adding it to a .nar file. This is not what I need since I can already build the C++ library.
Finally, I looked at one-jar which I got to place the native library inside the jar. However, I was not able to import the classes from within that jar, and the clients of this library will expect to be able to do that.
If what I want is possible and I don't need to install the shared library into my local repository please provide a link or an example of how you accomplished it. If it is not possible, please state why.

AEM 6.1 Sightly Java class does not update on build

I have recently started using Sightly in AEM 6.1, which allows the Java files to be located in the same folder as the component and use the WCMUse class. However, I am noticing that whenever I do a Maven build that involves a change to one of those Java files that the page functionality operates as if the Java class had not been changed, though the Java file in the crx does include the changes. As a workaround I have been been able to modify the Java file in the crx, save it, then modify it back and save again in order to update the functionality, but I do not have that capability on all of my instances.
Anybody have an idea how to force the recompile of the Sightly Java within the components either during or following the build?
A few things to validate:
1- Do you change the version of the software when doing a maven build/deploy? Sometime if your zip or jar does not have -SNAPSHOT in it AEM won't update the code when maven deploys.
2- there a /var/classes/sightly in CRX/DE that you can delete compiled classes, I think even in the system console there is an entry
Hope this help.
Bambara actually helped me get to the answer that I needed. It turns out the /var/classes folder holds the compiled sightly files, but it doesn't naturally recompile on build. Deleting that folder on build, then running a page that uses the sightly code forces a recompile and shows the new functionality.
Hopefully others can answer why this happens and how to avoid it. Having faced this a number of times, I'm beginning to think placing Java code into the component folders is not a very good idea. Using a maven multi-module project with a Services/Core bundle, then all Java code could go there. Calling it from the view just requires using the fully qualified classname (including the package). Placing the Java into the services bundle has the following benefits
Allows the classes to be extended. For some reason compilation was unpredictable when extending classes from component folders.
Easier IDE setup. Java classes in component folders in the view module have a Sling specific folder structure, so getting IDE's to provide code assist requires extra effort.
Sling folder conventions follow URI practices and might have dashes, Java packages cannot have dashes... import apps.my-cool-project.components.pages.base.Header; // won't compile

Missing jar file error

I am developing an application with many functionality, where one functionality requires a jar file which is only commercially available. When I release it for public use for free, I have to remove this jar file from my source. When I run this application in Eclipse IDE with the jar file removed, it gives me "Errors exist in required Project". I would like to avoid this warning.
Only the users using the library should be able to access its corresponding functionality (The application has many functionality.)
Users who don't include this jar file should be able to access other functionality without any error/warning.
Requirement:
Gray out the functionality based on the absence of the jar file.
Avoid the warning message when I run the Main.java
Any help appreciated. Thanks!
What you need indeed is dynamic class loading, isn't it?
To enable this feature, you have some options:
Implement your own classloader.
Use OSGI.
Additional to yanana's solution, you can simply leave the commercial JAR file in your Eclipse project. When creating your setup you can create one setup for commercial use (including the JAR) and one for the open source version (without the JAR).
But you should be carefully separate the usage of the commercial classes into one or more package/module. At runtime you can check the presence of one class which is part of the commerical JAR file via reflection before accessing code dependent on the commercial JAR.
Your integration tests should contain some corresponding test cases with and without the commercial JAR in classpath.

Create sources jar for shrunk classes in a module via proguard

There is a business module - say kilo-business in one of the applications. Now there are some APIs in this module that is to be used by another application (locally within the organization - say kilo-client1). I have used Proguard (via its maven plugin) to only extract the classes relevant to the API and make a JAR out of it - the shrunk API JAR called kilo-business-apis. kilo-client1 uses this kilo-business-apis dependency and invokes the service. As a policy, we always include sources along with any artifact that we share between applications (for debugging ease and additional documentation).
In this case, is there a way that one can have Proguard also give out the (probable) source files (belonging to kilo-business module) from where it has sourced the classes for the kilo-business-apis using which a sources JAR can be conjured? Actually, we don't shrink the JAR to the extent of removing unused methods/variables from the class, so giving out the source java files would also suffice.
I understand that one can use jd-eclipse or some other decompiler in eclipse to aid debugging even if we don't publish it, but wanted to check if we can generate the sources first class whereby documentation needs are also addressed.
One thought is to break up kilo-business itself into a separate module for kilo-business-apis where only the API definitions reside and both kilo-business and kilo-client1 can use it, but unfortunately I can't do it for legacy reasons.
Thanks in advance!
ProGuard optionally writes out information about kept entry points (-printseeds), unused code (-printusage), and obfuscation mapping (-printmapping), but nothing related to source files. If you don't obfuscate the code, you can simply list the .class names in the processed output, and find the corresponding .java files.

Proguard: avoiding naming collisions with pre-obfuscated library JARs

It seems that Proguard doesn't make any attempt to avoid naming collisions with classes in library JARs when it renames/repackages classes. Is this correct, or have I just not configured it correctly?
I am obfuscating an Android application that uses the latest Google AdMob SDK. Previously I was using the old AdMob SDK without a problem. The new SDK JAR file contains some classes that have been obfuscated. One of these classes is a.class in the default/unnamed package. When I obfuscate my app, Proguard renames/repackages one of my classes to also be a.class in the unnamed package, despite having read in the AdMob JAR as a library JAR (so it ought to know that this will cause a collision). Predictably, my build fails when the dx tool attempts to combine these two identically named classes in a single .dex file.
As a workaround I have reconfigured Proguard so that it moves all of my classes into a named package (just a single letter) to avoid collisions with the Google classes, but I'm interested to know if there is a better solution or if this is a limitation of the current version (4.6) of Proguard?
From the progaurd manual,
If an input jar and a library jar contain classes in the same package, the obfuscated output jar may contain class names that overlap with class names in the library jar. This is most likely if the library jar has been obfuscated before, as it will then probably contain classes named 'a', 'b', etc. Packages should therefore never be split across input jars and library jars.
So it looks like using your own package is the recommended answer.
In closed libraries to prevent conflict between multiple obfuscated modules/libraries you should use
-keeppackagenames
proguard rule to prevent complete classes repackaging, otherwise you can find errors like:
Duplicate class a.a.a.a in [jetified-lib1] and a.a.a.a in [jetified-lib2]

Categories

Resources