LibGDX Gradle task to export android project in a jar - android-studio

I'm using Android Studio with LibGDX and I'm trying to create a gradle task to export android project as a jar. I have added the following code to default build.gradle file under android project folder:
task exportMyLib(type: Jar){
from android.sourceSets.main.java.srcDirs
}
That orks fine to export source files.
But I need to export compiled classes also - how can I do that?

Maybe this would be interesting to somebody else out there -I have finally come up with this:
task exportMyLib(dependsOn: build, type: Jar) {
from android.sourceSets.main.java.srcDirs
from('build/intermediates/classes/release/')
from project(':core').sourceSets.main.output.classesDir
from project(':core').sourceSets.main.allSource
}
I don't like the fact that it uses hardcoded path instead of variable, but I could not figure this out otherwise.

Related

Configuring maven deploy script with Android Experimental Gradle Plugin

I am working on adding NDK builds to a module of a library I already have deployed in maven. In the past, I used the stable Android Gradle plugin v1.5, but do to needs with the NDK build I am trying to use the experimental plugin (I need to specify a shared library to link against). The NDK build is fine, my issue is with my Maven deploy script.
At the end of my module's build script I call
apply from: '../maven_push.gradle'
After all the maven configuration stuff I have the following tasks:
task androidJavadocs(type: Javadoc) {
source = android.sourceSets.main.java.sourceFiles
}
task androidJavadocsJar(type: Jar) {
classifier = 'javadoc'
//basename = artifact_id
from androidJavadocs.destinationDir
}
task androidSourcesJar(type: Jar) {
classifier = 'sources'
//basename = artifact_id
from android.sourceSets.main.java.sourceFiles
}
artifacts {
//archives packageReleaseJar
archives androidSourcesJar
archives androidJavadocsJar
}
When I try to compile the build script I receive the following error:
Error:Could not find property 'android' on task ':moduleName:androidJavadocs'.
What is odd is that in Android Studio, autocomplete does find android.sourceSets.main.java.sourceFiles if I start typing. I know the experimental plugin is, well, experimental and I am also aware its poorly documented. Google is unfortunately not giving us any good options when it comes to automated building in this matter but I am hoping maybe someone understands enough about gradle to help me with this one.

Can't import Material Design Library in android studio

I read this page, that learn "importing libraries into android studio". but it's doesn't work for me. i do those step for Material Design Library. in Material Design's build.gradle file have:
https://github.com/navasmdc/MaterialDesignLibrary/blob/master/MaterialDesign/build.gradle
when i click on "Sync Project with Gradle Files" it's gives me two error:
Error:(2, 0) Plugin with id 'com.github.dcendents.android-maven' not found.
Error:(3, 0) Plugin with id 'com.jfrog.bintray' not found.
Can any one tell me how to solve those error's?
note: i read this, but don't understand.
If you want to download the Material Design Library and import it without using the gradle method pyus13 mentioned, you need to add the following lines to the MaterialDesign Build.gradle file:
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.github.dcendents:android-maven-plugin:1.2'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0'
}
}
To find this file, you can double click on the error you get when syncing that looks like this:
Error:(2, 0) Plugin with id 'com.github.dcendents.android-maven' not found.
I also had to add compile project(':MaterialDesign') to the app build.gradle file.
Dont follow the above tutorial, the shown approach is useful when the library has not published as maven or gradle dependency.But as Github page say it is published on maven.
So remove the module or library project completely from your project and use gradle dependency instead.
Just copy this in your app module's build.gradle inside dependencies closure
dependencies {
// YOUR OTHER DEPENDENCIES
compile 'com.github.navasmdc:MaterialDesign:1.+#aar'
}
Sync your project with gradle.
This was kindly answered #pyus13 but I would like to give the complete answer, with the source, github.com/navasmdc/MaterialDesignLibrary#howtouse:
You can use the gradle dependency, you have to add these lines in your
build.gradle file:
repositories {
jcenter()
}
dependencies {
compile 'com.github.navasmdc:MaterialDesign:1.+#aar'
}
The build.gradle you are looking for is in ProjectName\app\src.
Add two dependencies in your Project build.gradle
dependencies {
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
}

Android Studio runtime error Stub! at com.amazon.device.messaging.ADMMessageReceiver.<init>()

When I build the Amazon (Kindle) flavor of my Android app I run into this Runtime error:
Caused by: java.lang.RuntimeException: Stub!
at com.amazon.device.messaging.ADMMessageReceiver.<init>()
I need the local amazon-device-messaging.jar file to compile my app, however I do not need to include it during runtime as the amazon device will have the necessary classes and methods.
How do I update my Android Studio build.gradle file to do this?
I also ran into this issue. When adding the Amazon Device Messaging jar as a library, Android Studio automatically generated
dependencies {
compile files('libs/amazon-device-messaging-1.0.1.jar')
}
I just needed to switch that to
dependencies {
provided files('libs/amazon-device-messaging-1.0.1.jar')
}
That did the trick for me. I'd up-vote your answer, #Clu, but I don't have a high enough reputation.
To solve this I used the provided type of dependency.
Inside my project modules build.gradle file, right before my dependencies closure I included the following:
configurations {
provided
}
sourceSets {
main {
compileClasspath += configurations.provided
}
}
And then, within my dependencies closure I included the following:
dependencies {
provided files('libs/amazon-device-messaging-1.0.1.jar')
}
This ensured that the .jar was only used for compile time and not runtime. I'm quite new to Android Studio, and this took me a while to figure out; hopefully this will help you make the switch to Android Studio as well.
Add the ADM jar in the Maven local repository.
Command :
mvn install:install-file "-Dfile=amazon-device-messaging-1.0.1.jar" "-DgroupId=com.amazon.device.messaging" "-DartifactId=amazondevicemessaging" "-Dversion=1.0.1" "-Dpackaging=jar"
Include local maven repository as project dependency :
Add “mavenLocal()” in main Gradle build script:
allprojects {
repositories {
mavenCentral()
mavenLocal()
}
Link the Maven artifact in ADM project.
Add below line ADMWrapperLib Gradle script (::).
provided 'com.amazon.device.messaging:amazondevicemessaging:1.0.1'

How to create a library project in Android Studio and an application project that uses the library project

How do I create an Android Library Project (e.g. com.myapp.lib1) and the application project (e.g. com.myapp.app) and make the build system include com.myapp.lib1 on the application project?
I went to the Project Structure -> Modules -> My App project and added a dependency to the lib project. IntelliJ now can recognize classes from the lib project when used in the app project, but when I run the app project, there are errors like:
Gradle: error: package com.myapp.lib1 does not exist
I wonder why there is no example of stand alone jar project.
In eclipse, we just check "Is Library" box in project setting dialog.
In Android studio, I followed this steps and got a jar file.
Create a project.
open file in the left project menu.(app/build.gradle): Gradle Scripts > build.gradle(Module: XXX)
change one line: apply plugin: 'com.android.application' -> 'apply plugin: com.android.library'
remove applicationId in the file: applicationId "com.mycompany.testproject"
build project: Build > Rebuild Project
then you can get aar file: app > build > outputs > aar folder
change aar file extension name into zip
unzip, and you can see classes.jar in the folder.
rename and use it!
Anyway, I don't know why google makes jar creation so troublesome in android studio.
To create a library:
File > New Module
select Android Library
To use the library add it as a dependancy:
File > Project Structure > Modules > Dependencies
Then add the module (android library) as a module dependency.
Run your project. It will work.
Google’s Gradle Plugin recommended way for configuring your gradle files to build multiple projects has some shortcomings If you have multiple projects depending upon one library project, this post briefly explain Google’s recommended configuration, its shortcomings, and recommend a different way to configure your gradle files to support multi-project setups in Android Studio:
An alternative multiproject setup for android studio
A Different Way :
It turns out there’s a better way to manage multiple projects in Android Studio. The trick is to create separate Android Studio projects for your libraries and to tell gradle that the module for the library that your app depends on is located in the library’s project directory. If you wanted to use this method with the project structure I’ve described above, you would do the following:
Create an Android Studio project for the StickyListHeaders library
Create an Android Studio project for App2
Create an Android Studio project for App1
Configure App1 and App2 to build the modules in the StickyListHeaders project.
The 4th step is the hard part, so that’s the only step that I’ll describe in detail. You can reference modules that are external to your project’s directory by adding a project statement in your settings.gradle file and by setting the projectDir property on the ProjectDescriptor object that’s returned by that project statement:
The code one has to put in settings.gradle:
include ':library1'
project(':library1').projectDir = new File('../StickyListHeader/library1')
If you’ve done this correctly, you’ll notice that the modules referenced by your project will show up in the project navigator, even if those modules are external to the project directory:
This allows you to work on library code and app code simultaneously. Version control integration also works just fine when you reference modules externally this way. You can commit and push your modifications to the library code just like you can commit and push modifications to your app code.
This way of setting up multiple projects avoids the difficulties that plague Google’s recommended configuration. Because we are referencing a module that is outside of the project directory we don’t have to make extra copies of the library module for every app that depends on it and we can version our libraries without any sort of git submodule nonsense.
Unfortunately, this other way of setting up multiple projects is very difficult to find. Obviously, its not something you’ll figure out from looking at Google’s guide, and at this point, there’s no way to configure your projects in this way by using the UI of Android Studio.
Check out this link about multi project setups.
Some things to point out, make sure you have your settings.gradle updated to reference both the app and library modules.
settings.gradle: include ':app', ':libraries:lib1', ':libraries:lib2'
Also make sure that the app's build.gradle has the followng:
dependencies {
compile project(':libraries:lib1')
}
You should have the following structure:
MyProject/
| settings.gradle
+ app/
| build.gradle
+ libraries/
+ lib1/
| build.gradle
+ lib2/
| build.gradle
The app's build.gradle should use the com.android.application plugin while any libraries' build.gradle should use the com.android.library plugin.
The Android Studio IDE should update if you're able to build from the command line with this setup.
For Intellij IDEA (and Android Studio) each library is a Module. Think of a Module in Android Studio as an equivalent to project in Eclipse. Project in Android Studio is a collection of modules. Modules can be runnable applications or library modules.
So, in order to add a new android library project to you need to create a module of type "Android library". Then add this library module to the dependency list of your main module (Application module).
The simplest way for me to create and reuse a library project:
On an opened project file > new > new module (and answer the UI questions)
check/or add if in the file settings.gradle: include ':myLibrary'
check/or add if in the file build.gradle:
dependencies {
...
compile project(':myLibrary')
}
To reuse this library module in another project, copy it's folder in the project instead of step 1 and do the steps 2 and 3.
You can also create a new studio application project
You can easily change an existing application module to a library module by changing the plugin assignment in the build.gradle file to com.android.library.
apply plugin: 'com.android.application'
android {...}
to
apply plugin: 'com.android.library'
android {...}
more here
You can add a new module to any application as Blundell says on his answer and then reference it from any other application.
If you want to move the module to any place on your computer just move the module folder (modules are completely independent), then you will have to reference the module.
To reference this module you should:
On build.gradle file of your app add:
dependencies {
...
compile project(':myandroidlib')
}
On settings.gradle file add the following:
include ':app', ':myandroidlib'
project(':myandroidlib').projectDir = new File(PATH_TO_YOUR_MODULE)
Don't forget to use apply plugin: 'com.android.library' in your build.gradle instead of apply plugin: 'com.android.application'
Documentation Way
This is the recommended way as per the advice given in the Android Studio documentation.
Create a library module
Create a new project to make your library in. Click File > New > New Module > Android Library > Next > (choose name) > Finish. Then add whatever classes and resourced you want to your library.
When you build the module an AAR file will be created. You can find it in project-name/module-name/build/outputs/aar/.
Add your library as a dependency
You can add your library as a dependency to another project like this:
Import your library AAR file with File > New Module > Import .JAR/.AAR Package > Next > (choose file location) > Finish. (Don't import the code, otherwise it will be editable in too many places.)
In the settings.gradle file, make sure your library name is there.
include ':app', ':my-library-module'
In the app's build.gradle file, add the compile line to the dependencies section:
dependencies {
compile project(":my-library-module")
}
You will be prompted to sync your project with gradle. Do it.
That's it. You should be able to use your library now.
Notes
If you want to make your library easily available to a larger audience, consider using JitPac or JCenter.
Had the same question and solved it the following way:
Start situation:
FrigoShare (root)
|-Modules: frigoshare, frigoShare-backend
Target: want to add a module named dataformats
Add a new module (e.g.: Java Library)
Make sure your settings.gradle look like this (normally automatically):
include ':frigoshare', ':frigoShare-backend', ':dataformats'
Make sure (manually) that the build.gradle files of the modules that need to use your library have the following dependency:
dependencies {
...
compile project(':dataformats')
}
Purpose: Android library at single place - Share across multiple projects
http://raevilman.blogspot.com/2016/02/android-library-project-using-android.html
As theczechsensation comment above I try to search about Gradle Build Varians and I found this link: http://code.tutsplus.com/tutorials/using-gradle-build-variants--cms-25005
This is a very simple solution. This is what I did:
- In build.gradle:
flavorDimensions "version"
productFlavors {
trial{
applicationId "org.de_studio.recentappswitcher.trial"
flavorDimension "version"
}
pro{
applicationId "org.de_studio.recentappswitcher.pro"
flavorDimension "version"
}
}
Then I have 2 more version of my app: pro and trial with 2 diffrent packageName which is 2 applicationId in above code so I can upload both to Google Play. I still just code in the "main" section and use the getpackageName to switch between to version. Just go to the link I gave for detail.
There are two simplest ways if one does not work please try the other one.
Add dependency of the library inside dependency inside build.gradle file of the library u r using, and paste ur library in External Libraries.
OR
Just Go to your libs folder inside app folder and paste all your .jar e.g Library files there Now the trick here is that now go inside settings.gradle file now add this line "include ':app:libs'" after "include ':app'" It will definitely work...........:)
In my case, using MAC OS X 10.11 and Android 2.0, and by doing exactly what Aqib Mumtaz has explained.
But, each time, I had this message : "A problem occurred configuring project ':app'. > Cannot evaluate module xxx : Configuration with name 'default' not found."
I found that the reason of this message is that Android 2.0 doesn't allow to create a library directly. So, I have decided first to create an app projet and then to modify the build.gradle in order to transform it as a library.
This solution doesn't work, because a Library project is very different than an app project.
So, I have resolved my problem like this :
First create an standard app (if needed) ;
Then choose 'File/Create Module'
Go to the finder and move the folder of the module freshly created in your framework directory
Then continue with the solution proposed by Aqib Mumtaz.
As a result, your library source will be shared without needing to duplicate source files each time (it was an heresy for me!)
Hoping that this help you.

how to export a executable jar in gradle, and this jar can run as it include reference libraries

how to export a executable jar in gradle, and this jar can run as it include reference libraries.
build.gradle
apply plugin: 'java'
manifest.mainAttributes("Main-Class" : "com.botwave.analysis.LogAnalyzer")
repositories {
mavenCentral()
}
dependencies {
compile (
'commons-codec:commons-codec:1.6',
'commons-logging:commons-logging:1.1.1',
'org.apache.httpcomponents:httpclient:4.2.1',
'org.apache.httpcomponents:httpclient:4.2.1',
'org.apache.httpcomponents:httpcore:4.2.1',
'org.apache.httpcomponents:httpmime:4.2.1',
'ch.qos.logback:logback-classic:1.0.6',
'ch.qos.logback:logback-core:1.0.6',
'org.slf4j:slf4j-api:1.6.0',
'junit:junit:4.+'
)
}
after i run : gradle build
it create the build folder, and i run the jar in build/libs/XXX.jar:
java -jar build/libs/XXX.jar
here is a execution says :
Exception in thread "main" java.lang.NoClassDefFoundError: ch/qos/logback/core/joran/spi/JoranException
how can i run it with the reference libraries?
You can achieve it with Gradle application plugin
Hopefully this helps someone (as I unfortunately spent quite some time trying to find the solution). Here's the solution that worked for me for creating an executable JAR. I'm embedding Jetty in the main method, Jetty 9 to be specific and using Gradle 2.1.
Include the following code into your build.gradle file (if a subproject is the "main" project that the jar needs to be built from, then add it to the subproject which should start like this project(':') { insert the code somewhere here, after dependencies.}.
Also, you need to add the plugin java for this to work: apply plugin: 'java' .
My jar task looks as follows:
apply plugin: 'java'
jar {
archiveName = "yourjar.jar"
from {
configurations.runtime.collect {
it.isDirectory() ? it : zipTree(it)
}
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes 'Main-Class': 'your.package.name.Mainclassname'
}
exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
}
And then you can execute your yourjar.jar via the commandline:
java -jar yourjar.jar
The META-INF/.RSA, META-INF/.SF and META-INF/*.DSA have to be excluded for it to work. Otherwise a SecurityException gets thrown.
The problem seems to lie with embedded Jetty, as Jetty moved to Eclipse and now is signing their JARs, which I read becomes problematic when other, unsigned JARs want to load the signed ones. Please feel free to educate me if I am wrong in this, that's just what I read.
The JARs that the project depends on are defined in the dependencies as follows:
dependencies {
// add the subprojects / modules that this depends on
compile project(':subproject-1')
compile project(':subproject-2')
compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '9.2.6.v20141205'
compile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '9.2.6.v20141205'
compile group: 'org.eclipse.jetty', name: 'jetty-http', version: '9.2.6.v20141205'
}
EDIT: Before, instead of just
configurations.runtime.collect{...}
i had
configurations.runtime.asFileTree.files.collect{...}
This caused strange behaviour in a larger project in clean build. When running the jar after executing gradle clean build for the first time (after manually cleaning the build directory), it would throw a NoClassDefFoundException (in our project with many subprojects), but running the jar after executing gradle clean build a second time (without emptying the build directory manually), for some reason it had all dependencies. This didn't happen if asFileTree.files was left out.
Also I should note, all compile dependencies are included in runtime, however not all runtime are included in compile. So if you are just using compile
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
Then be sure to remember that if there is a NoClassDefFoundException thrown, some class isn't found at runtime, which means you should also include this:
configurations.runtime.collect {
it.isDirectory() ? it : zipTree(it)
}
Quick answer
Add the following to your build.gradle:
apply plugin: 'application'
mainClassName = 'org.example.app.MainClass'
jar {
manifest {
attributes 'Main-Class': mainClassName,
'Class-Path': configurations.runtime.files.collect {"$it.name"}.join(' ')
}
}
From the project directory, run gradle installDist
Run java -jar build/install/<appname>/lib/<appname>.jar
I recommend adding the app version to your build.gradle as well, but it's not required. If you do, the built jar name will be <appname>-<version>.jar.
Note: I'm using gradle 2.5
Details
In order to create a self contained executable jar that you can simply run with:
java -jar appname.jar
you will need:
your jar to include a MANIFEST file pointing to your application main class
all your dependencies (classes from jars outside of your application) to be included or accessible somehow
your MANIFEST file to include the correct classpath
As some other answers point out, you can use some third-party plugin to achieve this, such as shadow or one-jar.
I tried shadow, but didn't like the fact that all my dependencies and their resources were dumped flat out into the built jar together with my application code. I also prefer to minimize the use of external plugins.
Another option would be to use the gradle application plugin as #erdi answered above. Running gradle build will build a jar for you and nicely bundle it with all your dependencies in a zip/tar file. You can also just run gradle installDist to skip zipping.
However, as #jeremyjjbrown wrote in a comment there, the plugin does not create an executable jar per se. It creates a jar and a script which constructs the classpath and executes a command to run the main class of your app. You will not be able to run java -jar appname.jar.
To get the best of both worlds, follow the steps above which create your jar together with all your dependencies as separate jars and add the correct values to your MANIEST.
All of these answers are either wrong or out of date.
The OP is asking for what is known as a "fat jar". That is an exectuable jar which contains all the dependencies so that it requires no outside dependencies in order to run (except for a JRE of course!).
The answer at the time of writing is the Gradle Shadow Jar plugin, explained pretty clearly at Shadow Plugin User Guide & Examples.
I struggled a bit. But this works:
put all these lines somewhere in your build.gradle file (I put them near the top) :
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.4'
}
}
apply plugin: 'com.github.johnrengelman.shadow'
shadowJar {
baseName = 'shadow'
classifier = null
version = null
}
jar {
manifest {
attributes 'Class-Path': '/libs/a.jar'
attributes 'Main-Class': 'core.MyClassContainingMainMethod'
}
}
PS don't worry about any other "repositories", "dependency" or "plugin" lines elsewhere in your build file, and do leave the lines thus inside this "buildscript" block (I haven't a clue why you need to do that).
PPS the Shadow Plugin User Guide & Examples is well-written but doesn't tell you
to include the line
attributes 'Main-Class': 'core.MyClassContainingMainMethod'
where I've put it above. Perhaps because the author assumes you are less clueless than I am, and you probably are. I haven't a clue why we are told to put a strange "Class-Path" attribute like that in, but if it ain't broke don't fix it.
When you then go
> gradle shadowjar
Gradle will hopefully build a fat executable jar under /build/libs (default name "shadow.jar") which you can run by doing this:
> java -jar shadow.jar
I checked quite some links for the solution, finally did the below mentioned steps to get it working. I am using Gradle 2.9.
Make the following changes in your build,gradle file :
1. Mention plugin:
apply plugin: 'eu.appsatori.fatjar'
2. Provide the Buildscript:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "eu.appsatori:gradle-fatjar-plugin:0.3"
}
}
3. Provide the Main Class:
fatJar {
classifier 'fat'
manifest {
attributes 'Main-Class': 'my.project.core.MyMainClass'
}
exclude 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.SF'
}
4. Create the fatjar:
./gradlew clean fatjar
5. Run the fatjar from /build/libs/ :
java -jar MyFatJar.jar

Resources