Where does sourceCompatibility directive belong in build.gradle? - android-studio

I have a java project in Android studio, and I am trying to use the "sourceCompatibility" directive as follows:
// build.gradle
apply plugin: 'java'
sourceCompatibility = 1.7
targetCompatibility = 1.7
dependencies {
...
}
the IDE reports that the "sourceCompatibility" and "targetCompatibility" directives are not used. I can't find where they should be placed - where should it go in the build.gradle file?
Thanks

Don't trust the IDE for Gradle file inspection - it treats them as, how should I say, source code files. What matters is whether script works when parsed or executed by Gradle. So disregard IDE's warnings, you did put the directives correctly.

Related

How to set Java language level to 8 in JetBrains Fleet?

I can't find the config to set Java language level.
You might find the answer here How to change project language level for all project in Intellij
Change the sourceCompality to 1.8, if it didn't work, also change the Project structure JDK.
If you are using Maven, in pom.xml file use:
<properties>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
</properties>
If you are using Gradle, in build.gradle file use:
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

Gradle/Groovy/Shadow project to create executable jar file

Using this build.gradle file:
plugins {
id 'groovy'
id 'com.github.johnrengelman.shadow' version '1.2.2'
}
repositories {
mavenCentral()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.4'
}
version = '0.1'
shadowJar {
mergeServiceFiles()
manifest {
attributes 'Main-Class': 'com.mycompany.tools.EncodeFile'
}
}
I get an essentially empty .jar file (264 bytes) when I run ~/TOOLS/gradle-2.10/bin/gradle shadowJar.
I would expect it to contain the groovy.jar and my .class files.
There is some confusion in looking at samples on the web because it seems that plugins { id... } is the new preferred syntax, but the samples are older and do not use that syntax.
The directory structure is:
./src/groovy/com/mycompany/tools/EncodeFile.groovy
./build.gradle
I would guess that I either have to move my .groovy file, or, I need to modify build.gradle to point to the groovy file.
How should I fix this such that that I get a .jar file that will execute like this: java -jar build/libs/EncodeFile.jar?
Any other tips on using gradle to build self contained .jar files is appreciated. Both Groovy and Java (and mixed).
I will probably be adding third party .jar files that I will want to embed in the executable jar. Any tips on that would be appreciated as well.
The structure
./src/groovy/com/mycompany/tools/EncodeFile.groovy
Should be
./src/main/groovy/com/mycompany/tools/EncodeFile.groovy
Gradle thinks you have no source code (due to the missing main directory)
Also, if you change your gradle file to (adding the application plugin):
plugins {
id 'groovy'
id 'application'
id 'com.github.johnrengelman.shadow' version '1.2.2'
}
repositories {
mavenCentral()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.4'
}
version = '0.1'
mainClassName = 'com.mycompany.tools.EncodeFile'
shadowJar {
mergeServiceFiles()
}
Then you get the same shadowJar functionality, but you also gain gradle run to just run the unjarred app

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'
}

Duplicate test execution when run gradle test

When I run >gradle test all the BDD test steps are executed twice. I created the project using intelliJ as my IDE and following are the task that could see under Gradle tasks window.
I choose command line to run the tests with above command
In my build.gradle I don't have test task defined
apply plugin: "groovy"
apply plugin: "idea"
repositories {
mavenCentral()
}
sourceCompatibility = 1.6
targetCompatibility = 1.6
def version = [
'groovy' : '1.8.6',
'junit' : '4.10',
'geb' : '0.7.2',
'selenium' : '2.25.0',
'cucumber' : '1.0.8'
]
ext.drivers = ["htmlunit", "firefox", "chrome"]
dependencies {
groovy "org.codehaus.groovy:groovy-all:$version.groovy"
testCompile "junit:junit:$version.junit"
testCompile "org.codehaus.geb:geb-junit4:$version.geb"
testCompile "info.cukes:cucumber-groovy:$version.cucumber"
testCompile "info.cukes:cucumber-junit:$version.cucumber"
// Drivers
drivers.each { driver ->
testCompile "org.seleniumhq.selenium:selenium-$driver-driver:$version.selenium"
}
}
How can I fix this
I managed to resolve this issue by deleting .idea and build folders and then by re-import the project.
But still curious what the root cause is.
I believe this happened when re-build the project via intelliJ
This happened to me also.
There is some confusion between test run inside Intellij and using Gradle.
When I run a test inside IntelliJ then run test in gradle, they are launched in double. I must run a gradle clean to get back to normal.
To prevent the issue from happening you can change in Intellij the gradle configuration to specify that test should be run using gradle.
see: https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000191604-Unit-Tests-run-from-Gradle-and-IDEA-differ

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