Say I want to add guice-assistedinject as a dependency in my project. It specifies the guice artifact as a dependency itself. How do I tell it to use the no_aop version of guice?
I know I can do the following, but can I do it in one step without excluding the guice module?
dependencies {
compile (group: 'com.google.inject.extensions', name: 'guice-assistedinject', version: '3.0') {
exclude module: 'guice'
}
compile group: 'com.google.inject', name: 'guice', version: '3.0', classifier: 'no_aop'
}
There is no simpler solution. You can shorten the code by using short dependency notation (e.g. "com.google.inject:guice:3.0:no_aop").
Related
So I've seen other posts (eg. Can't use hbase-shaded-client jar because of its internal dependency to log4j-1.2.17(CVE-2019-1757)) stating that they have a way to exclude the transitive dependency of log4j:log4j:1.2.17 however if I run ./gradlew app:dependencies I can still see that the transitive dependency exists.
I have tried referring to the following migration doc https://logging.apache.org/log4j/2.x/manual/migration.html but Im not sure if this is just transferring the calls over from log4j 1.x over to 2.x at runtime or if its supposed to update the transitive dependency all together. I tried even excluding the transitive dependency and using slf4j instead in my build.gradle file like so:
compile ('custom-library-that-I-cant-change-code-in'), {
exclude group: 'log4j', module: 'log4j'
}
// https://mvnrepository.com/artifact/org.slf4j/log4j-over-slf4j
implementation 'org.slf4j:log4j-over-slf4j:1.7.35'
How can I make sure if this is even working, or at least not using that older log4j:log4j:1.2.17 or am I going about this all wrong and there is an easier way of doing this
To answer you first question the following exclude wasn't working for me as well,
compile ('custom-library-that-I-cant-change-code-in'), {
exclude group: 'log4j', module: 'log4j'
}
try this in your build.gradle it should work
configurations {
compile.exclude group: "log4j", module: "log4j"
}
I am using gradle 3.2.1. I have a framework that pulls up dependencies (newer version). But the problem is that my project already has these dependencies (old version) and I don't want to change their version. And the required framework cannot work without a new version. And my question is, can you restrict the built-in dependencies of the framework only for it? and use the same version for my application? is there such a possibility in gradle?
An example of how i exclude the loading of components, but i need to leave them only for this dependency:
compile(group: 'io.javalin', name: 'javalin', version: '4.1.1') {
exclude group: 'org.eclipse.jetty'
exclude group: 'org.eclipse.jetty.websocket'
}
I'm trying to include JsonPath Library into my Liferay MVC Portlet.
I found thread on Liferay Help Center:
https://help.liferay.com/hc/en-us/articles/360028710272-Resolving-Third-Party-Library-Package-Dependencies
but still I don't know what to do exactly.
I read that i should use compileInclude in build.gradle file, because it's include also dependences for library I want to.
That's how it's look like
#build.gradle
dependencies {
compileOnly group: "com.liferay.portal", name: "release.portal.api"
cssBuilder group: "com.liferay", name: "com.liferay.css.builder", version: "3.0.2"
compileInclude group: 'com.jayway.jsonpath', name: 'json-path', version: '2.4.0'
}
When I build a *.jar which i deploy to Liferay I have that error.
2021-07-15 06:56:16.994 INFO [com.liferay.portal.kernel.deploy.auto.AutoDeployScanner][AutoDeployDir:272] Processing mycustomportlet2-1.0.0.jar
2021-07-15 06:56:26.140 ERROR [fileinstall-directory-watcher][DirectoryWatcher:1159] Unable to start bundle: file:/opt/liferay/osgi/modules/mycustomportlet2-1.0.0.jar
com.liferay.portal.kernel.log.LogSanitizerException: org.osgi.framework.BundleException: Could not resolve module: mycustomportlet2 [1411]_ Unresolved requirement: Import-Package: com.google.gson_ [Sanitized]
at org.eclipse.osgi.container.Module.start(Module.java:444) ~[org.eclipse.osgi.jar:?]
at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:428) ~[org.eclipse.osgi.jar:?]
at com.liferay.portal.file.install.internal.DirectoryWatcher._startBundle(DirectoryWatcher.java:1142) [bundleFile:?]
at com.liferay.portal.file.install.internal.DirectoryWatcher._startBundles(DirectoryWatcher.java:1175) [bundleFile:?]
at com.liferay.portal.file.install.internal.DirectoryWatcher._startAllBundles(DirectoryWatcher.java:1120) [bundleFile:?]
at com.liferay.portal.file.install.internal.DirectoryWatcher._process(DirectoryWatcher.java:1032) [bundleFile:?]
at com.liferay.portal.file.install.internal.DirectoryWatcher.run(DirectoryWatcher.java:272) [bundleFile:?]
I tried including also gson in build.gradle but then error shows another library that have unresolved requiremnt.
I'm using Liferay Portal 7.4-ga2 docker image with Java 11.
If you know how to do this without including a lot dependecies manually I will really appreciate a solution for that.
EDIT
I created build.gradle file with all includes needed to work. That's how it look:
dependencies {
compileOnly group: "com.liferay.portal", name: "release.portal.api"
cssBuilder group: "com.liferay", name: "com.liferay.css.builder", version: "3.0.2"
compileInclude group: 'com.jayway.jsonpath', name: 'json-path', version: '2.6.0'
compileInclude group: 'com.google.code.gson', name: 'gson', version: '2.8.7'
compileInclude group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.12.3'
compileInclude group: 'org.apache.tapestry', name: 'tapestry-json', version: '5.7.2'
compileInclude group: 'org.apache.tapestry', name: 'commons', version: '5.7.2'
compileInclude group: 'org.codehaus.jettison', name: 'jettison', version: '1.4.1'
compileInclude group: 'org.json', name: 'json', version: '20210307'
compileInclude group: 'org.slf4j.impl', name: 'log4j12', version: '1.7.2'
}
repositories {
maven {
url "https://maven.averbis.com/m2/"
}
}
If you compileInclude external resources (which is possible, but should be your last resort), unfortunately you will need to include all transitive dependencies as well. You're including jayway/jsonpath, and gson is missing. So you'll need to compileInclude gson. And as you say, when you do that, a different library is missing - so you'll need to include it as well.
That's part of the reason why this should be your last resort.
An alternative is: Check if jayway/jsonpath or gson are OSGi bundles themselves - in which case you can just drop them into Liferay's deploy folder and they'll be dynamically resolved. Of course, in this case their transitive dependencies need to be resolvable as well, so you might need to deploy a couple more bundles than just these two. But this way, all modules that use these libraries will share the same bundle.
Either way, you can inspect a bundle's MANIFEST.mf for imports to figure out what they depend on. Note: there are mandatory and optional dependencies in there. You'll need to satisfy the mandatory ones and the optional ones that you're using. If the libraries in question aren't bundles, they're managing their dependencies differently. I'd at least suggest to the project teams to OSGi'ify their packages - but that's a fix for the long run.
There's a chapter on this on Liferay's University's (free, registration required) course OSGi Basics, called "Bringing along your dependencies" (disclaimer: by yours truly), where I still like the animated special effect visualizing the option to compileInclude and what it does to file size)
I am posting here to understand how does JHipster work with Gradle dependencies, in particular with regards to the fact that I am unable to copy some of them into a Gradle submodule I have created inside my JH project.
For example, the following doesn't work in a Gradle submodule
compile "junit:junit"
Error is
Could not resolve: junit:junit
However, the classic one copied from mvnrepository works great
compile group: 'junit', name: 'junit', version: '4.12'
Some additional information: I am creating a submodule that contains a set of classes related to testing, mainly a large load of custom Hamcrest matchers copied from another project from the Ant world. The original project had a lot of spaghetti code mess, so now I am refactoring into an isolated Gradle module. The testlib module shall depend on the testing frameworks and contain everything required for writing good tests. It can be compared to spring-test project you would use to write your own Spring-based tests.
At the moment, the gradle file looks like
plugins {
id "java"
}
configurations {
providedRuntime
implementation.exclude module: "spring-boot-starter-tomcat"
}
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
group 'org.example' //different from com.acme of super-project
version '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
dependencies {
compile group: 'org.assertj', name: 'assertj-core', version: '3.13.2'
compile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.2'
compile group: 'org.hamcrest', name: 'hamcrest', version: '2.1'
compile group: 'org.mockito', name: 'mockito-core', version: '3.0.0'
compile group: 'org.springframework.boot', name: 'spring-boot', version: spring_boot_version
compile "junit:junit" //Fails
}
Question
So the question is in two parts:
why does the scope "orgId:name" syntax work in the JHipster-generated module but not in submodules? Is it part of standard Gradle syntax?
why is that not working in a sub-module? Does JHipster apply a custom plugin to apply the correct version number that is clearly missing? How I do the same in a sub-module that is supposed to contain only Java library code?
With regards to JHipster, a little of more investigation helped. According to this answer, there is a trick in Gradle called Bill Of Materials project, so...
TL;DR
Add the following to the sub-project
// import JHipster dependencies BOM
implementation platform("io.github.jhipster:jhipster-dependencies:${jhipster_dependencies_version}")
So that the whole block looks like
dependencies {
// import JHipster dependencies BOM
implementation platform("io.github.jhipster:jhipster-dependencies:${jhipster_dependencies_version}")
compile "org.assertj:assertj-core"
compile "org.junit.jupiter:junit-jupiter-api"
compile "org.hamcrest:hamcrest"
compile "org.mockito:mockito-core"
compile "org.springframework.boot:spring-boot"
compile "junit:junit"
}
Long answer
Maybe in the future when I will understand Gradle more. Or just edit this answer 😁 to contribute
The bom defines the versions (besides other things) of 3rd party dependencies to be used so you can omit the explicit version. If you do not use the bom you can also write compile "junit:junit:4.12" but keep in mind jhipster uses already junit5 for all tests by default.
Regarding the import of the bom you can do it like you proposed or try to apply that dependency to all gradle subprojects in your main gradle file.
My gradle project uses the application plugin to build a jar file. As part of the runtime transitive dependencies, I end up pulling in org.slf4j:slf4j-log4j12. (It's referenced as a sub-transitive dependency in at least 5 or 6 other transitive dependencies - this project is using spring and hadoop, so everything but the kitchen sink is getting pulled in... no wait... that's there too :) ).
I want to globally exclude the slf4j-log4j12 jar from my built jar. So I've tried this:
configurations {
runtime.exclude group: "org.slf4j", name: "slf4j-log4j12"
}
However, this seems to exclude all org.slf4j artifacts including slf4j-api. When running under debug mode I see lines such as:
org.slf4j#slf4j-api is excluded from com.pivotal.gfxd:gfxd-demo-mapreduce:1.0(runtime).
org.slf4j#slf4j-simple is excluded from com.pivotal.gfxd:gfxd-demo-mapreduce:1.0(runtime).
org.slf4j#slf4j-log4j12 is excluded from org.apache.hadoop:hadoop-common:2.2.0(runtime).
I do not want to have to look up the source of each slf4j-log4j12 transitive dependency and then have individual compile foo { exclude slf4j... } statements in my dependencies block.
Update:
I did also try this:
configurations {
runtime.exclude name: "slf4j-log4j12"
}
Which ends up excluding everything from the build! As though I specified group: "*".
Update 2:
I'm using Gradle version 1.10 for this.
Ah, the following works and does what I want:
configurations {
runtime.exclude group: "org.slf4j", module: "slf4j-log4j12"
}
It seems that an Exclude Rule only has two attributes - group and module.
Hence for excluding from only an individual dependency, we can do something like:
dependencies {
compile ('org.springframework.data:spring-data-hadoop-core:2.0.0.M4-hadoop22') {
exclude group: "org.slf4j", module: "slf4j-log4j12"
}
}
However, the above syntax doesn't prevent you from specifying any arbitrary property as a predicate. When trying to exclude from an individual dependency you cannot specify arbitrary properties. For example, this fails:
dependencies {
compile ('org.springframework.data:spring-data-hadoop-core:2.0.0.M4-hadoop22') {
exclude group: "org.slf4j", name: "slf4j-log4j12"
}
}
with
No such property: name for class: org.gradle.api.internal.artifacts.DefaultExcludeRule
So even though you can specify a dependency with a group: and name: you can't specify an exclusion with a name:!?!
Perhaps a separate question, but what exactly is a module then? I can understand the Maven notion of groupId:artifactId:version, which I understand translates to group:name:version in Gradle. But then, how do I know what module (in gradle-speak) a particular Maven artifact belongs to?
For excluding one or more library globally add the following to your build.gradle
configurations.all {
exclude group:"org.apache.geronimo.specs", module: "geronimo-servlet_2.5_spec"
exclude group:"ch.qos.logback", module:"logback-core"
}
Now the exclude block has two properties group and module. For those of you coming from maven background, group is same as groupId and module is same as artifactId.
Example: To exclude com.mchange:c3p0:0.9.2.1 following should be exclude block
exclude group:"com.mchange", module:"c3p0"
Your approach is correct. (Depending on the circumstances, you might want to use configurations.all { exclude ... }.) If these excludes really exclude more than a single dependency (I haven't ever noticed that when using them), please file a bug at http://forums.gradle.org, ideally with a reproducible example.
in the example below I exclude
spring-boot-starter-tomcat
compile("org.springframework.boot:spring-boot-starter-web") {
//by both name and group
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
I was using spring boot 1.5.10 and tries to exclude logback, the given solution above did not work well, I use configurations instead
configurations.all {
exclude group: "org.springframework.boot", module:"spring-boot-starter-logging"
}
In addition to what #berguiga-mohamed-amine stated, I just found that a wildcard requires leaving the module argument the empty string:
compile ("com.github.jsonld-java:jsonld-java:$jsonldJavaVersion") {
exclude group: 'org.apache.httpcomponents', module: ''
exclude group: 'org.slf4j', module: ''
}
compile is deprecated and it was replaced by implementation. Therefore, the solution for those running newer versions of gradle:
implementation("org.springframework.boot:spring-boot-starter-web") {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
This is for Kotlin DSL (build.gradle.kts) which prevents you from using wrong properties.
Exclude the library from all configrations (implementation, runtimeOnly, etc.):
configurations.all {
exclude(group = "ir.mahozad.android", module = "pie-chart")
// OR exclude("ir.mahozad.android", "pie-chart")
}
// Another notation:
// configurations {
// all {
// exclude(group = "ir.mahozad.android", module = "pie-chart")
// }
// }
Exclude the library from a single configuration (like implementation):
configurations.implementation {
exclude(group = "ir.mahozad.android", module = "pie-chart")
}
// Another notation:
// configurations {
// implementation {
// exclude(group = "ir.mahozad.android", module = "pie-chart")
// }
// }
Exclude the library for a single dependency:
dependencies {
// ...
implementation("ir.mahozad.android:charts:1.2.3") {
exclude(group = "ir.mahozad.android", module = "pie-chart")
}
}