RE: help with Liferay 7.1 Dependency + gradle + bnd

Pablo B, modified 6 Years ago. New Member Posts: 10 Join Date: 7/9/15 Recent Posts
Hi all, 
I've been working with Liferay since 5 years, so I understand how it works, but I'm having some issues, or more likely questions, about how DXP handles the dependencies, more specificly the Core dependencies, I give you an example}
I created a quick test project including some basic Core dependencies

build.gradle
dependencies {
    compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel"
    compileOnly group: "com.liferay.portal", name: "com.liferay.util.taglib"
    compileOnly group: "javax.portlet", name: "portlet-api"
    compileOnly group: "javax.servlet", name: "javax.servlet-api"
    compileOnly group: "jstl", name: "jstl"
    compileOnly group: "org.osgi", name: "osgi.cmpn"
}
*this config in build.gradle got generated by Eclipse automatically, notice the missing "version"I know compileOnly is used for this because the Portal will provide those at runtime, however if I don't specify the version, and run Gradle Build task, bnd will generate the MANIFEST.MF with an Import-Package header containing:

Import-Package: com.liferay.portal.kernel.portlet.bridges.mvc;version=
 "[1.6,2)",com.liferay.portal.kernel.search;version="[7.6,8)",javax.po
 rtlet;version="[2.0,3)",javax.servlet;version="[3.0,4)",javax.servlet
 .http;version="[3.0,4)"

so my question is, how does bnd knows which version to require? (i.e. 1.6 to 2 and 7.6 to 8 )
does it read or check somewhere within the Liferay Workspace?
I'm using Eclipse with Liferay Plugin but I also use IntelliJAnd my question is related to the fact that in my company we are upgrading Liferay DXP with hotfixes, and we see some updates in Liferay Core Modules, so we want to make sure we are using the latest version of module "x" in our Development environment (Eclipse or IntelliJ) Thanks!
thumbnail
Christoph Rabel, modified 6 Years ago. Liferay Legend Posts: 1555 Join Date: 9/24/09 Recent Posts
Well, I don't use that "automatic version detection" feature, so I don't remember the details.
But I think, the liferay workspace determines the necessary module versions based on the "portal.version" setting. I think, the workspace also determines that automatically from the bundle you use.
But, more importantly, you have a misconception here!

The compile version does not set/enforce the runtime version. It only says: This is the minimal version of the library I need. When you deploy your module, it tells the runtime: I need at least version 3.0.0. And  runtime will then use the version it has, be 3.2 or 3.5.

It is indeed best practice to use the minimal version in the build.gradle file and only update it to a higher version, if the interface changes. So, it is usually perfectly fine to build e.g. a 7.1 module with
compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel", version: "3.0.0"
for the whole project lifetime. Only when you upgrade to 7.2 you would update the version to 4.0.0.
Pablo B, modified 6 Years ago. New Member Posts: 10 Join Date: 7/9/15 Recent Posts
Hello Christoph, thanks for your reply
when you say:

It is indeed best practice to use the minimal version in the build.gradle file and only update it to a higher version, if the interface changes

Here is what is not clear to me

If you add:
compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel", version: "3.0.0"
​​​​​​​

to gradle.build, then Gradle will download that version and use it in the IDE, and code against that specific version, what if version 3.5 has some new interfaces or new method signatures, you will not be using the correct version, or the version that has the "improved" method...
​​​​​​​
And in fact you say "if the interface changes" , maybe I'm missing something, but where do you check if a specific core bundle got an important change? (git source repo?) sounds like much manual and time consuming work...
thank you!
thumbnail
Christoph Rabel, modified 6 Years ago. Liferay Legend Posts: 1555 Join Date: 9/24/09 Recent Posts
Pablo B:

to gradle.build, then Gradle will download that version and use it in the IDE, and code against that specific version, what if version 3.5 has some new interfaces or new method signatures, you will not be using the correct version, or the version that has the "improved" method...


There is no "correct" version.
There is a compile time version and a runtime version. Most of the time you want the highest runtime version possible. But you change the compile time version only when you really need to.

Lets say you have a compile time depency to a module in version 3.0.5. It's actually the most current version when you start developing. You have all the interfaces you need, implement your module and it works. Now, you deploy it on the production server.

But in the meantime, it was patched it is already on version 3.2.0. And later on, the server is patched again and the version of the module increases to 3.3.14

That's good. Since there was no major version increment, the interfaces were not changed in an incompatible manner. Everything is fine. Your module still compiles and works as intended. You could, of course update your dependency version to the most current version, but why bother?

But let's say, a few months later you have a new requirement and you find a superuseful method in the documentation. But it isn't there when you start implementing. You find out that it was added in version 3.5. That's bad. You can of course update your dependency in the IDE, but your module won't deploy. It needs version 3.5, but only 3.3.14 is provided. So you need to patch your server to at least patch 60. Since there is already patch 70, you patch it to 70.

Now you update the compile time version to 3.5 since the interface you need is there in that version. You could try to find the exact version of the deployed module, sure. But why bother. With the next patch, it will increase again.

And in fact you say "if the interface changes" , maybe I'm missing something, but where do you check if a specific core bundle got an important change? (git source repo?) sounds like much manual and time consuming work...


Nobody tracks all changes to all methods and all classes. Nobody cares. When you have a requirement, you check, if there is a method that might help, but otherwise, you simply don't track all changes. It's too much work.
Pablo Bucci, modified 6 Years ago. New Member Post: 1 Join Date: 7/25/17 Recent Posts
Hello again, thanks for your inputbut I must say that I've found the solution to my question by looking at the Liferay Workspace gradle.propertiesthere is a property called

"liferay.workspace.target.platform.version"

which is where one can set the DXP version with a fixpack level , I.E. "liferay.workspace.target.platform.version=7.1.10.fp11"
then you remove the "version" from your bundle and when you compile it, gradle will download a pom based BOM and get the correct version from there, having everything updated.

There is also some documentation available (but very hidden)
https://portal.liferay.dev/docs/7-0/tutorials/-/knowledge_base/t/managing-the-target-platform-for-liferay-workspace
I think this information should be written in BOLD on the main dev page after patching.
I hope some else find this information useful!