Android Studio Gradle: execute static Java method (transition from ANT to Gradle)

I am trying to run the static core method of the java class from my build.gradle script asp art build process. I am using Android Studio 1.0.2 with Android / Gradle Plugin 'com.android.tools.build:gradle:1.0.0'

The java class whose main method I want to run at build time is in ... \ trunk- gradle \ myproject \ src \ main \ java \ de \ myapp \ gradle

package de.myapp.gradle; public class ConfigureCustomer { public static void main(String[] args){ String server = args[0]; String customer = args[1]; System.out.println(String.format("Configuring customer %s with server %s", customer, server)); } } 

Before using ANT to call this java method as follows:

 <java failonerror="yes" classname="de.myapp.gradle.ConfigureCustomer "> <classpath> <path location="${base.dir}/bin/classes/"/> </classpath> <arg line="${customer}"/> <arg line="${server }"/> </java> 

But now I turn to Groovy, so here is the corresponding part of my project build.gradle file that is trying to execute the main method of the above class (the actual definition of the task is at the end before the dependencies):

 apply plugin: 'com.android.application' android { project.ext.set("customer", "") project.ext.set("server", "") dexOptions { preDexLibraries = false } compileSdkVersion 19 buildToolsVersion "21.1.2" defaultConfig { //Default configuration } signingConfigs { release { //Configuration for release builds } } buildTypes { debug{ server = "test" } release { server = "release" } } productFlavors { customerA{ customer = "a" } customerB{ customer = "b" } customerC{ customer = "c" } } } task (configureCustomer, type: JavaExec) { println 'Running customer configuration...' main = 'de.myapp.gradle.ConfigureCustomer' args customer, server } dependencies { //Dependency settings } 

So now when I run the following through the command line (windows):

 graldew configureCustomer 

The following error message appears:

Error: could not find or load the main class de.myapp.gradle.ConfigureCustomer

My questions are therefore the following:

  • How do I fix the error message above? Should I move my java class to another folder? Maybe configure sth in the assembly?
  • How can I make sure that the java task is executed after the classes have really been compiled?
  • If I wanted to run the configureCustomer task as part of another task, can I just write the next line in the gradle task definition?

configureCustomer

I also tried adding the classpath:

 task (configureCustomer, type: JavaExec) { println 'Running customer configuration...' main = 'de.myapp.gradle.ConfigureCustomer' classpath = sourceSets.main.runtimeClasspath args customer, server } 

But all I got was a gradle build error message saying:

Could not find property "main" in SourceSet container

Therefore, apparently, "sourceSets.main.runtimeClasspath" does not exist in Android Studio Gradle. Maybe he is named differently. Although I also tried to set the classpath as follows:

 classpath = '${projectDir.getAbsolutePath()}\\build\\intermediates\\classes\\' + customer + '\\release' 

and I also tried this:

 classpath = '${projectDir.getAbsolutePath()}\\build\\intermediates\\classes\\' + customer + '\\release\\de\\myapp\\gradle' 

None of them worked, the error from above is saved:

Error: could not find or load the main class de.myapp.gradle.ConfigureCustomer

+3
source share
2 answers

I finally found something that works for Android / Gradle, but getting there was a lot harder than it should have been.

So, for recap, here is a Java class whose main method I would like to execute:

de.myapp.gradle package

 public class ConfigureCustomer { public static void main(String[] args){ String customer = args[0]; String versionName = args[1]; System.out.println(String.format("Configuring customer %s with versionName %s", customer, versionName )); } } 

I want to do the above for each flavor and only for releases (not for debugging lines), so here is the definition of my task (you still have to make your task depend on one of the gradle build tasks to make it work - I'm depending on the preBuild task for this purpose):

 android { //Build type setup, signing configuration and other stuff } //After the android block my task definition follows: task buildPrintout(type: JavaExec) { android.applicationVariants.all { variant -> //Runt he java task for every flavor variant.productFlavors.each { flavor -> println "Triggering customer configuration for flavor " + flavor.name if (variant.buildType.name.equals('release')) { //Run the java task only for release builds //Cant find the runtime classpath in android/gradle so I'll directly link to my jar file here. The jarfile contains the class I want to run (with the main method) classpath += files("libs/my-jarfile.jar") //This is the fully qualified name of my class, including package name (de.myapp.gradle) and the classname (ConfigureCustomer) main = "de.myapp.gradle.ConfigureCustomer" //Pass in arguments - in this case the customer name and the version name for the app (from AndroidManifest.xml) args flavor.name, variant.versionName } } } } 

You will notice that I abandoned the idea of ​​integrating my class into the Android project that I am going to build. Instead, I made this class a separate project, created a jar file, and dumped it into the libs folder of the android project that I am creating.

UPDATE February 4, 2015

I slightly modified the above to use the javaexec method instead of the JavaExec task type:

 preBuild.doFirst { android.applicationVariants.all { variant -> variant.productFlavors.each { flavor -> if (variant.buildType.name.equals('release')) { javaexec { println "Triggering customer build for flavor " + flavor.name classpath += files("libs/my-jarfile.jar") main = "de.myapp.gradle.ConfigureCustomer" args flavor.name, variant.versionName } println "Done building customer for flavor " + flavor.name } } } } 

And here is another variation in which we define javaexec as part of the reusable task (which is preferred), which we then add as a dependency on the preBuild task:

 //Define our custom task and add the closures as an action task buildCustomer << { android.applicationVariants.all { variant -> variant.productFlavors.each { flavor -> if (variant.buildType.name.equals('release')) { javaexec { println "Triggering customer build for flavor " + flavor.name classpath += files("libs/my-jarfile.jar") main = "de.myapp.gradle.ConfigureCustomer" args flavor.name, variant.versionName } println "Done building customer for flavor " + flavor.name } } } } //Make preBuild depend on our task preBuild.dependsOn buildCustomer 

If you have any questions, let me know and I will try to answer them.

+1
source

Change the classpath configuration method

 classpath(files('build/intermediates/classes/release',"${android.getSdkDirectory().getAbsolutePath() + '/platforms/' + android.compileSdkVersion + '/android.jar'}")) 

It works on android gradle 1.5

0
source

Source: https://habr.com/ru/post/1212271/


All Articles