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)
Related
I have added the dependencies for drools in my build.gradle file.
implementation group: 'org.kie', name: 'kie-api', version: '7.16.0.Final'
implementation group: 'org.drools', name: 'drools-core', version: '7.16.0.Final'
implementation group: 'org.drools', name: 'drools-compiler', version: '7.16.0.Final'
implementation group: 'org.kie', name: 'kie-spring', version: '7.16.0.Final'
I can't understand the steps to proceed the project to write a rule in drools. please help me to know what should i do to write a rule in drools.(should i install plugins in drools and kie)
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 project uses
compile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
I added Google Sheets API to dependencies. Now
gradle dependencies says Google Sheets API uses org.mortbay.jetty:servlet-api:2.5-20081211 which I assume to exclude, because classes are loaded from the wrong jar:
compile (group: 'com.google.apis', name: 'google-api-services-sheets', version: 'v4-rev25-1.22.0') {
exclude(module: 'servlet-api')
}
compile (group: 'com.google.gdata', name: 'core', version: '1.47.1') {
exclude(module: 'servlet-api')
}
Now gradle dependencies does not show servlet-api:2.5 to be used anywhere. But after gradle clean distZip I see that archive contains servlet-api-2.5-20081211.jar! How can I exclude it from the build?
gradle looks like:
dependencies{
compile files('libs/myJarContainingGuava.jar')
compile group: 'com.google.guava', name: 'guava', version: '18.0'
}
myJarContainingGuava has an old guava version in it.
My current code is picking that jar instead of picking the guava 18.
I cannot modify myJarContainingGuava.jar
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").