I need to export a library project without the source code for security reasons. Unfortunately the jar file generated within a library project does not contain the resources. I cannot expect the users of this library to deal with any resources needed by the library.
There have been similar post to this one, but I am yet to see a solution.
The following recipe used to work, though I have not tried it very recently:
Step #1: Get the library project working as-is. I will refer to the directory holding this project as $ORIG.
Step #2: If you have not done so already, create your Ant build scripts in $ORIG using android update project.
Step #3: Add a task to $ORIG/build.xml that creates a JAR file, something like:
<target name="jar" depends="debug">
<jar
destfile="bin/YOUR-LIBRARY-NAME-GOES-HERE.jar"
basedir="bin/classes"
/>
</target>
Step #4: Copy your entire library project from $ORIG into another directory, which I'll call $DIST.
Step #5: Get rid of the src/ tree in $DIST except for the root src/ directory itself.
Step #6: Move bin/YOUR-LIBRARY-NAME-GOES-HERE.jar into $DIST/libs/. This effectively replaces your source code from src/ with its compiled equivalent.
Step #7: Get rid of $DIST/bin/ as it is no longer needed.
$DIST now holds an Android library project that is the equivalent of $ORIG, except that the src/ tree is replaced by libs/YOUR-LIBRARY-NAME-GOES-HERE.jar.
Since the Google Play Services package from the SDK Manager is packaged this way, not only do I assume the recipe still works, but it would appear to be reasonably officially endorsed.
Note that there is new build system in the works that may give us more options here. If you are reading this question in, say, 2014, be sure to check to see if there are better alternatives.
One idea I've heard mention of is using a regular Library project with a reference to a Jar file which is where you would put all of your proprietary code. All of the assets would need to be in your library project and would be readable by the users of your library.
Keep in mind that anyone with apktool can extract these files from the final APK anyways.
However, the code in the JAR would not be readable and your users would need to reverse engineer them which can be difficult, especially if you obfuscate it.
Related
if I have a project with many library projects linked, could I improve build performances by packaging each of them in an AAR and including it in the main project ? Or this will not make any difference since that when the compiler need to assemble the apk it need to package everything together anyway?
Thanks to any one who will give me some clarifcation about performance differences between the 2 approach
I don't think you will save any build time by wrapping an existing .jar file into a .aar file and using that instead of the original .jar file.
As this SO post notes, .aar files are basically just zip files which may contain a jar file and some android resources.
Also, because .aar files are not precompiled into Dalvik byte code, the build process for your apk file must still carry out that step at least once. So, you won't save dexing time just by wrapping the .jar file into a .aar file either.
If you build a typical Android Studio project (with some Android library dependencies specified in the gradle build file) you can see the directory underneath app/build/intermediates/exploded-aar where these files have been unzipped. That work must still be done by your build machine even though you are using a .aar file.
Finally, as you pointed out, the .apk packaging work must still be done at the end of the build.
I believe the Library projects (which you are using) is the best way to go because of two reasons:
The library project gives the direct access to the code base of the libraries which can be compiled and packaged together with the main app code
In case, multiple .aar files are referenced within the project, then during the apk creation the unpacking, merging of resources and Manifest file will increase the build time.
I am working on an android library, and wish to export a JAR file that I can distribute for others to use in their apps. I don't want to distribute the source code as it contains details on posting to my web server.
I have tried using the JAR file that is created in the bin directory and copying the jar file to my project and referencing it within my project and ticking the export button.
When I try and run my project referencing the library that I've copied, my app throws an exception with NoClassDefFoundError. I've done some Googling and everything I have found suggests you have to provide the source code and let the user import into their IDE and then reference that project into their app which I don't want to do. It must be possible as other companies provide JAR files for libraries that can be included.
Thanks for your help.
I don't want to distribute the source code as it contains details on posting to my web server.
Bear in mind that anyone who wants to can get that data out of the JAR.
It must be possible as other companies provide JAR files for libraries that can be included.
AFAIK, this recipe still works:
Create an Android library project, with your source code, resources, and such, and get it working
Compile the Java source (e.g., via Ant) and turn it into a JAR file
Create a copy of your original Android library project to serve as a distribution Android library project
Place the compiled JAR from step #2 and put it in libs/ of the distribution library project from step #3.
Delete everything in src/ of the distribution library project (but leave the now-empty src/ directory there)
Distribute the distribution library project (e.g., ZIP it up)
This effectively gives you what you see with the Play Services SDK -- a library project with no source code, but instead a JAR in libs/, along with the resources and such.
I will be reconfiming this recipe tomorrow and will try to remember to update this answer if I find that it needs adjusting for the current crop of tools.
And the new Gradle-based build system supports the AAR package for distributing libraries and such, though I have not played with this yet.
UPDATE
This recipe works, so long as the library project does not itself have dependencies upon another JAR or library project. In those cases, things seem to get messed up in the build process -- everything can compile, but class references from the dependencies cannot be resolved at runtime.
Did you try putting your jar file in libs folder?And if you are exporting a jar library for android be sure it has no /res folder. As you know you can't reference to your res folder from a jar therefore you have to use library project to reference your res folder (drawable,xml,ect...)On the other hand you cant make your code safe (the part you say about posting to your web service) by using it as jar since it is so easy to retrieve by reverse engineering. you better use some encoding (like base64 or any algorithm that bouncycastle provides)
In my android application I have to separately implement a certain functionality and needs to make a library file(.jar) out of it.
Main idea is then I can distribute that jar file, so that other applications can easily integrate this functionality using the jar file within their apps.
Following I have indicate the Minimum and Target SDK versions that are in the Manifest file.
android:minSdkVersion="7"
android:targetSdkVersion="15"
I know I can create a library project to implement that specific functionality and have a reference for it from my main project. And then to distribute the jar file that creates under the bin folder of the library project.
I have couple of questions reagrding this.
1) Since I didn't find any good tutorial explaining this thing, bit not sure if this is the way to go (Distributing the jar file creates under bin folder).
2) Also the jar file that creates under the bin folder of the library project is with the same project name(Eg:- LibraryProjectName.jar). Is it okay if I rename it for what I want before I distribute it?
3) Are there any other alternative or good ways of doing this?
Any help would be highly appreciated. Thanks in advance.
Since I didn't find any good tutorial explaining this thing, bit not sure if this is the way to go(Distributing the jar file creates under bin folder).
I wouldn't. That JAR is an artifact of consuming the library project and may or may not be suitable for third parties. Besides, if you really need an Android library project, the JAR is insufficient.
Is it okay if I rename it for what I want before I distribute it?
JAR names can be whatever you want.
Are there any other alternative or good ways of doing this?
First, do not create an Android library project unless you need to ship resources along with the code (or JAR). And, in that case, you will need to distribute the JAR and all the resources (and the manifest and pretty much everything else in the project).
Second, create your own JAR, such as by adding a <jar> operation to your Ant script. That way, you are in control over exactly what goes in there, how it got compiled, etc., rather than making assumptions about the JAR that the build system created as a by-product.
For example, here is a jar target from one of my CWAC projects:
<target name="jar" depends="debug">
<jar
destfile="bin/CWAC-EndlessAdapter.jar"
basedir="bin/classes"
/>
</target>
I am currently developing an android application that allows me to dynamically load modules.
Therefore I can have as many modules as I like, and my main application just needs to load them.
I've managed to make this work for the most part - but I want to create an executable to "speed up" the module creation process, or even just find a way to simplify the steps involved.
To create a module I currently have to do the following:
Build the android project containing the files required for my
module [none of which are activity classes - so I don't have to
worry about the androidmanifest file at all]
Use the eclipse IDE jar creation tool to select which src files I want to be compiled into .class to put into my jar, and specify my own custom manifest file for this jar, as well as package all the images I use for the module into the jar as well.
Then using the jar file I run the dex creator command on it to generate a .dex file from the class files contained in the jar, and then use the aapt command to push the dex file back into the jar file.
At this point the jar(Now its a module) is created and I can put it on the server for downloading, download the modules in my app and load all the code I need in my app using reflection.
I have looked into building with ant. It looks fairly complicated for what I wish to achieve and I'm not quite sure where to start with it.
I obviously can't use simple javac to compile my java files contained in my module src because all that code makes references to the android sdk as well as a static library shared between my main application and my respective module.
Currently I use the Eclipse IDE to create the inital jar with all my packaged images, class files, manifest, and then I use two separate batch files that call on the android-sdk to create dex and push the dex into the jar.
Can I simplify this process in one easy step instead? Or is trying to do this - a whole project on its own?
I have looked into building with ant. It looks fairly complicated for what I wish to achieve and I'm not quite sure where to start with it.
The documentation for Ant is online, as is the documentation for building Android projects with Ant. The only difference is that you will want to add a <jar> task to your Ant build.xml file, as I have done in several projects, such as this one:
<target name="jar" depends="debug">
<jar
destfile="bin/CWAC-EndlessAdapter.jar"
basedir="bin/classes"
/>
</target>
You are also welcome to consider Maven. While I do not use Maven personally, it has many fans and community-driven Android support.
You are also welcome to write your own build script in any programming language that suits your fancy: Java, Ruby, Perl, Python, etc.
I obviously can't use simple javac to compile my java files contained in my module src because all that code makes references to the android sdk as well as a static library shared between my main application and my respective module.
Every Android IDE, and Ant, and Maven, and so on, "use simple javac to compile [an Android project's] java files". They simply add the appropriate Android SDK JAR file to the build path.
I maintain an Android app and am not using Eclipse. I am not using Eclipse. I am using ant and build.xml and build.properties.
I have places my .jar file into the libs/ directory. My code compiles just dandy. But when I run it on the emulator, the output APK does not include the .jar, so I get a runtime stacktrace:
ERROR/AndroidRuntime(470): java.lang.NoClassDefFoundError: com.google.ads.AdView
my build.properties looks like this:
jar.libs.dir=libs
And the libs/ directory contains my .jar file.
What needs to be in build.xml so that the external .jar file is included in the APK?
Edit: In theory this answer should work, but it doesn't for me. Is it out of date? What gives? How to add external jar libraries to an android project from the command line
I just came over a similar problem and noticed that libraries should not be placed in "myprojectdir\lib". When I moved them to "myprojectdir\libs" everything started to work.
It turns out that I needed to upgrade the version of ant I was using to 1.8. During the compile process, I had been getting this error message:
Warning: Reference out.dex.jar.input.ref has not been set at runtime,
but was found duringbuild file parsing, attempting to resolve. Future
versions of Ant may support referencing ids defined in non-executed
targets.
I googled it, and found that I needed to upgrade Ant, and now I don't get this warning, and my application does not force close.
What needs to be in build.xml so that the external .jar file is included in the APK?
Just putting it in libs/ is sufficient.
my build.properties looks like this:
That line should not be necessary. It does not appear in my build.properties files that build successfully with JAR files.
If you use dexdump -f classes.dex from your project's bin/ directory, you will be able to determine whether com.google.ads.AdView made it in there. If it did not, then something is strange with your build scripts. If it did, then perhaps there is a dependent JAR that you are missing (though I would expect a VerifyError in that case).
You use 3rd party library, but you seem didn't run DX on it. Make sure that not only your code processed by DX tool (I assume Ant does it), but also all 3rd party libraries you use. You can look in 7Bee script I use to convert web applications to Android davlik format, so it can work for you too. You can find more about the script on Atjeews page.
Solution:
right click on the project in project tree and select Project
properties
select Java Build Path
select TAB Order
and Export
check GoogleAdMobAdsSdk-4.0.4.jar (or your
version SDK)
press OK
clean project by menu Project
-> Clean
rebuild project (Project – Build Automatically)