Do an exclusion in build.gradle? - java

I want to add an exclusion to my build.gradle because my jar doesnt run after I compile it. The problem can be fixed if some modules are excluded.
How do I do that correctly? The following code should fix the problem:
compile ("com.badlogicgames.gdx:gdx-tools:$gdxVersion") {
exclude group: 'com.badlogicgames.gdx', module: 'gdx-backend-lwjgl'
}

For the most recent gradle versions (7+), you need to use the new syntax implementation or compileOnly. This should also be in a dependencies block as shown below:
dependencies {
implementation("com.badlogicgames.gdx:gdx-tools:$gdxVersion") {
exclude group: 'com.badlogicgames.gdx', module: 'gdx-backend-lwjgl'
}
}
See for more info
However for gradle 6 and below, your compile block should work fine inside a dependencies block.

Related

Package 'com.example' reads package 'javafx.beans' from both 'javafx.base' and 'javafx.base'

In module-info.java i get the error
Package 'com.example' reads package 'javafx.beans' from both 'javafx.base' and 'javafx.base'.
Not only does the migration (Java 8 to Java 11) frustrate me slowly but surely, this error does not make any sense to me.
The dependencies part fo my build.gradle:
def springFrameworkVersion = '5.1.2.RELEASE'
def hibernateVersion = '5.3.7.Final'
def junitJupiterVersion = '5.3.1'
dependencies {
compile 'org.transentials:cardhouse-commons:1.1.1'
compile 'ch.qos.logback:logback-classic:1.2.3'
compile "org.springframework:spring-context:$springFrameworkVersion"
compile "org.springframework:spring-jdbc:$springFrameworkVersion"
compile "org.springframework:spring-orm:$springFrameworkVersion"
compile "org.hibernate:hibernate-core:$hibernateVersion"
compile 'org.apache.commons:commons-dbcp2:2.5.0'
compile 'org.apache.commons:commons-lang3:3.8.1'
compile 'commons-io:commons-io:2.6'
compile 'com.h2database:h2:1.4.197'
compile 'javax.xml.bind:jaxb-api:2.3.1'
compile 'com.google.guava:guava:27.0-jre'
compile 'org.flywaydb:flyway-core:5.2.1'
compile 'javax.validation:validation-api:2.0.1.Final'
compile "org.openjfx:javafx-base:11:$platform"
compile "org.openjfx:javafx-graphics:11:$platform"
compile "org.openjfx:javafx-controls:11:$platform"
compile "org.openjfx:javafx-fxml:11:$platform"
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:2.+'
testCompile 'de.saxsys:jfx-testrunner:1.2'
testCompile 'org.apache.commons:commons-text:1.6'
testCompile "org.junit.jupiter:junit-jupiter-api:$junitJupiterVersion"
testCompile "org.junit.jupiter:junit-jupiter-engine:$junitJupiterVersion"
testCompile 'org.hamcrest:hamcrest-all:1.3'
}
And the module-info.java:
module open.terms.client.jfx {
requires org.transentials.cardhouse.commons;
requires com.google.common;
requires org.apache.commons.lang3;
requires org.hibernate.orm.core;
requires java.persistence;
requires slf4j.api;
requires javafx.graphics;
requires javafx.fxml;
requires java.desktop;
}
Can someone explain to me what the compiler wants to tell me by this?
With the required list of dependencies, if you remove all the required modules from the module-info, the IDE will still complain with the same error:
Module '' reads package 'javafx.beans' from both 'javafx.base' and 'javafx.base'
So the problem is not in your module-info, but in your dependencies. If you comment out all of them, except the JavaFX ones, the problem is gone.
This means that some dependency is carrying some unnecessary JavaFX dependency.
I've managed to isolate the problem by commenting only the first dependency:
compile 'org.transentials:cardhouse-commons:1.1.1'
So the question is why is this happening and how can we fix it.
If you go to Maven Central repo it shows the GitHub repo of the dependency, where you can find the build.gradle file and its module-info.
As expected, it uses JavaFX:
compile "org.openjfx:javafx-base:11:$platform"
and it also requires javafx.base in its module-info.
When you consume this artifact with your dependencies you are importing their javafx.base import, along with yours from your JavaFX dependencies and there is the conflict.
The fastest way to solve the issue is just changing this in your build:
compile 'org.transentials:cardhouse-commons:1.1.1'
to this:
compile ('org.transentials:cardhouse-commons:1.1.1') {
exclude group: 'org.openjfx'
}
so you will exclude its JavaFX dependencies and will use yours.
A more permanent fix will be changing the artifact org.transentials:cardhouse-commons's module-info to:
`requires transitive javafx.base`
You can read about the use of transitive here.
An issue should be reported to the author.
Note
As an aside, you can use the javafx gradle plugin to take care of all the related JavaFX parts of the build, simplifying it to:
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.5'
}
repositories {
mavenCentral()
}
dependencies {
compile ('org.transentials:cardhouse-commons:1.1.1') {
exclude group: 'org.openjfx'
}
compile files('libs/cardhouse-commons-master-1.1.1.jar')
...
compile 'javax.validation:validation-api:2.0.1.Final'
}
javafx {
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
mainClassName = 'open.terms.client.jfx.Main'
The OpenJFX docs already make use of this plugin.
The error reads, that you've ended up placing same module twice in your modulepath for JavaFX.
The chances are that you might have placed both the jmods for the OpenJFX as well as the OpenJFX SDK/lib on your modulepath.
The JavaFX 11 runtime is available as
a platform-specific SDK
as a number of jmods and
as a set of artifacts in maven central.
Either(one) of these three should be sufficient enough to work with further depending on how you are planning to build your application - modular or non-modular.
Edit 1 [Conceptual Improvement]
In your build.gradle, you should just need to have dependencies over
compile "org.openjfx:javafx-controls:11:$platform"
compile "org.openjfx:javafx-fxml:11:$platform"
since the module, javafx.base and javafx.graphics are transitively present in the module path via javafx-controls anyway. Also, you must ensure, given these dependencies you are not adding any libraries under Project Settings > Libraries.
Edit 2 [Extensible improvement]
Following the documentation at OpenJFX, you can make use of the plugin and get rid of the openjfx dependencies
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.5'
}
javafx {
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
dependencies {
// all dependencies except openjfx
}
Edit 3 [Hands on]
The actual culprit in your example is the dependency
compile 'org.transentials:cardhouse-commons:1.1.1'
disabling this fixes the issue. You might want to raise it to the library owner(or fix this if you own it) to ensure that it doesn't bring along javafx.base module along with. To be precise this dependency is bringing in the org.openjfx:javafx-base:linux:11.0.1 as a dependency the reason being clear in their pom.xml dependencies.

Does gradle project with dependency to another project get libraries?

I have two projects:
ProjectA makes use of ProjectB
ProjectA:
-- Settings.graddle:
include ':projectB'
-- build.gradle:
dependencies {
compile project(':projectB')
}
ProjectB:
-- build.gradle:
dependencies {
compile group: 'org.modelmapper.extensions', name: 'modelmapper-jackson', version: '1.1.1'
}
This imports into ProjectB the modelmapper-jackson lib. (Expected behaviour)
It also imports modelmapper-jackson lib into ProjectA.
It might be this is the behaviour I want, but:
I would like to understand how to define what it is imported and what it is not, since in the future I might have more projects, and do not want all of them to have all the libraries
Is there anything in gradle I missed?
You can use gradle dependencies to inspect your dependency graph.
There are multiple approaches to stop transitive dependencies.
Set dependency to compileOnly in project B*
compileOnly group: 'org.modelmapper.extensions', name: 'modelmapper-jackson', version: '1.1.1'
Exclude in project A
dependencies {
compile project(':projectB') {
exclude module 'modelmapper-jackson'
}

Cannot exclude module from build.gradle

I'm trying to exclude some modules from my build.gradle file but it(code1 and code2) still downloads the excluded files.
code 1:
compile (group: 'com.amazonaws', name: 'aws-java-sdk', version: '1.11.7') {
exclude group: 'com.amazonaws', module: 'aws-java-sdk-machinelearning'
}
code 2:
compile (group: 'com.amazonaws', name: 'aws-java-sdk', version: '1.11.7') {
exclude module: 'aws-java-sdk-machinelearning'
}
when I tried using the following code,
configurations {
compile.exclude module: 'aws-java-sdk-machinelearning'
}
it excludes the files but I don't want to use this method to exclude files
I second/confirm with #Opal that code1 works fine in Gradle 2.13.
What is likely happening is that you have some other (maybe non-aws) dependency, that may be transitively using aws-java-sdk which then brings in the machine-learning dependency. Which is why, it works fine when you do a global exclude, but not when you do a local exclude on just aws-java-sdk.
Try running gradlew dependencies --configuration=compile to get a tree of dependencies, including transitives, to check which dependency might be bringing in aws-java-sdk-machinelearning

Remove dependency in Gradle

In my project I have to libraries that uses com.google.javascript:closure-compiler. Due to some jars problem I want to exclude one. To do this I wrote this code:
compile('com.bertramlabs.plugins:asset-pipeline-core:2.8.1') {
exclude group: 'com.google.javascript', module: 'closure-compiler'
}
When I run ./gradlew dependecies old jar seems to be removed.
My problem occurs when I run ./gradlew install and import my lib in another project, because in another project I have both jars. How can I remove it?
You could try adding a provided configuration as described here.
Once that is in place, try changing your code to something like:
provided('com.bertramlabs.plugins:asset-pipeline-core:2.8.1') {
exclude group: 'com.google.javascript', module: 'closure-compiler'
}

Gradle can't find package in dependent test project

I'm trying to run ./gradlew build for a nested multi project structure and I'm running into issues that only seem to appear for projects with test source roots. Being new to both java and gradle I'm sure I'm breaking more than one convention, but I still think this should be working.
Essentially, all the dependencies seem to be added fine, but when I have one project that only has a Test srcDir that depends on another project that has a Test srcDir, it doesn't recognize packages/symbols in that root project. However, projects with regular srcDirs (not test) don't seem to have a problem.
My project has more going on than this, but here is the simplest setup I've tried that illustrates the problem.
My project structure:
qatests
/Applications
/AppGroupName
/AppBasePageObjects
/src
/AppBaseTests
/src
/BasePageObjects
/src
/BaseTests
/src
My settings.gradle in qatests:
rootProject.name = 'QaTests'
include 'BasePageObjects'
include 'BaseTests'
include 'Applications:AppGroupName'
include 'Applications:AppGroupName:AppBasePageObjects'
include 'Applications:AppGroupName:AppBaseTests'
My build.gradle in qatests:
version '1.0-SNAPSHOT'
allprojects {
repositories {
mavenCentral()
}
}
subprojects{
if(project.name.contains("Tests")){
apply plugin: 'java'
sourceCompatibility = 1.8
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '2.+'
}
if(project.name != "BaseTests")
{
println "$project.name depends on BaseTests"
dependencies {
testCompile project(':BaseTests')
}
}
sourceSets {
test {
java {
srcDir 'src'
}
}
}
}
if(project.name.contains("PageObjects")){
apply plugin: 'java'
sourceCompatibility = 1.8
dependencies {
compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '2.+'
}
if(project.name !="BasePageObjects")
{
dependencies {
compile project(':BasePageObjects')
}
}
sourceSets {
main {
java {
srcDir 'src'
}
}
}
}
}
I won't include my build.grade for the BaseTest project since that seems to compile fine during the gradlew build, but here is my build.gradle for AppBaseTests:
version '1.0-SNAPSHOT'
dependencies {
compile 'org.apache.commons:commons-lang3:3.4'
compile project(':Applications:AppGroupName:AppBasePageObjects')
}
When I run ./gradlew build in the qatests root, the BaseTests, BasePageObjects, and AppBasePageObjects projects seem to compile fine and AppBasePageObjects successfully uses packages and symbols from BasePageObjects. For some reason however, AppBaseTests can't seem to recognize packages and symbols in BaseTests.
If I clone this project from scratch, IntelliJ runs the gradle scripts scripts automatically and everything seems to work out of the box just fine with the dependencies, so this just confuses me even more.
I've tried adding compile and testcompile for all the project dependencies since that's the only real difference between AppBasePageObjects which works and AppBaseTests which doesn't work. I've also tried adding compileJava.dependsOn(':BaseTests:build') to the AppBaseTests build.gradle file. And a few other rabbit holes, but nothing seems to have any effect on this dependency issue.
For what it's worth, here is the first error I see in the actual build:
error: package Tests does not exist import Tests.BaseTest;
Any help or suggestions are greatly appreciated. If you would like to distribute some harsh insults I'll take those as well. Thank you.
I believe I found an answer while reading another solution here:
Multi-project test dependencies with gradle
It seems I needed to use testCompile project(':BaseTests').sourceSets.test.output for command line builds as well as testCompile project(':BaseTests') for IDE functionality in my root build.gradle file. This only seems to be required for the test projects.
Here are the actual changes in my root build.gradle file:
if(project.name != "BaseTests")
{
println "$project.name depends on BaseTests"
dependencies {
testCompile project(':BaseTests')
testCompile project(':BaseTests').sourceSets.test.output
}
}
This seems a bit hacky but works, if somebody has a more thorough and intelligent answer please post!

Categories