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'
}
Related
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.
I have a java project made by some sibling modules. One of these modules is a library and I'm applying java-library plugin on it. All the other modules depend on it.
What I need to do is to automate the creation of a zip for each module, containing all the classes and all the dependencies needed for it to work (I'm deploying the zip as aws-lambda functions).
So far this is what I have achieved, but the resulting zip only contains module's classes. I thought that the problem might be the type of dependency I'm using (implementation) and I tried switching to the default one but gradle doesn't even success in building.
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
task buildZip(type: Zip) {
from compileJava
from processResources
from configurations.runtime
}
dependencies {
implementation project(':utils')
testCompile group: 'junit', name: 'junit', version: '4.12'
}
After some testing, I think I have the answer.
First: the order you declared the task and the dependencies is fine! It's OK to use a configuration before it's populated. I only say this because I indicated in my comments that it might be an issue.
Second, the issue here is the use of configurations.runtime. This does not extend implementation and api, so those dependencies are not included. runtime has been superseded by runtimeOnly, which hopefully makes the behaviour clear.
The following task definition should work:
task buildZip(type: Zip) {
from compileJava
from processResources
from configurations.runtimeClasspath
}
i am using a lot of library in my project. And some libraries using same jar file therefore i writed this on build.gradle :
dependencies {
compile fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.twotoasters.jazzylistview:library:1.2.1'
compile 'com.google.firebase:firebase-core:10.2.4'
compile 'com.google.firebase:firebase-database:10.2.4'
compile 'com.orhanobut:dialogplus:1.11#aar'
compile 'com.github.recruit-lifestyle:FloatingView:2.2'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.nineoldandroids:library:2.4.0'
compile ('com.specyci:residemenu:1.6+'){
exclude group: 'com.nineoldandroids', module: 'library' }
compile files('libs/poppyview.jar'){
exclude group: 'com.nineoldandroids', module: 'library' }
}
And i am getting error :
Error:(54, 0) Gradle DSL method not found: 'exclude()'
Possible causes:The project 'DopingEng' may be using a version of the Android Gradle plug-in that does not contain the method (e.g. 'testCompile' was added in 1.1.0).
Upgrade plugin to version 2.3.1 and sync projectThe project 'DopingEng' may be using a version of Gradle that does not contain the method.
Open Gradle wrapper fileThe build file may be missing a Gradle plugin.
Apply Gradle plugin
Gradle already update , how can i solve this problem ?
Here's the problem
compile files('libs/poppyview.jar'){
exclude ...
}
A file based dependency does not work in the same way as a dependency coming from a repository. There is no meta data associated with it (eg no dependency information) so there's also nothing to exclude (since there's no transitive dependencies).
Do you have the pom/ivy meta-data for libs/poppyview.jar? If so then you shouldn't declare it like this (I suggest a local maven repository folder). If you don't then there's nothing to exclude
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!
I'm starting with Gradle and I was wondering how do I include a single dependency (TeamSpeak API in my case) into my JAR so that it could be available at the runtime.
Here is a part of my build.gradle :
apply plugin: 'java'
compileJava {
sourceCompatibility = '1.8'
options.encoding = 'UTF-8'
}
jar {
manifest {
attributes 'Class-Path': '.......'
}
from {
* What should I put here ? *
}
}
dependencies {
compile group: 'org.hibernate', name: 'hibernate-core', version: '4.3.7.Final'
compile group: 'org.spigotmc', name: 'spigot', version: '1.8-R0.1-RELEASE'
// Many other dependencies, all available at runtime...
// This one isn't. So I need to include it into my JAR :
compile group: 'com.github.theholywaffle', name: 'teamspeak3-api', version: '+'
}
Thanks for your help :)
The easiest way is to start with a separate configuration for the dependencies you want to include. I know you only asked about a single jar but this solution will work if you add more dependencies to your new configuration. Maven has a well known name for this sort of thing called provided, so that is what we will use.
configurations {
provided
// Make compile extend from our provided configuration so that things added to bundled end up on the compile classpath
compile.extendsFrom(provided)
}
dependencies {
provided group: 'org.spigotmc', name: 'spigot', version: '1.8-R0.1-RELEASE'
}
jar {
// Include all of the jars from the bundled configuration in our jar
from configurations.provided.asFileTree.files.collect { zipTree(it) }
}
Using provided as the name of the configuration is also important because when the jar gets published, any dependencies you have in the providedconfiguration will show up as provided in the POM.xml that gets published with the JAR. Maven dependency resolvers will not pull down provided dependencies and users of your jar will not end up with duplicate copies of classes on the classpath. See Maven Dependency Scopes