Blogs
Just a quick one this morning...
So I'm working on a project for 7.1. With my new love of the target platform, I decide I'm going to enable the 7.1 target platform for my DXP project.
Everything seems to work fine until I deploy the portlet jar. That's when I get the following during deployment:
2020-02-01 08:40:06.324 ERROR [fileinstall-/Users/dnebinger/liferay/71ee/bundle2/osgi/modules] [LogService:93] Error while starting bundle: file:/Users/dnebinger/liferay/71ee/bundle2/osgi/modules/com.example.test.web-1.0.0.jar org.osgi.framework.BundleException: Could not resolve module: com.example.test.web [985]_ Unresolved requirement: Import-Package: javax.servlet; version="[3.1.0,4.0.0)"_ [Sanitized] at org.eclipse.osgi.container.Module.start(Module.java:444) at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:428) at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundle(DirectoryWatcher.java:1275) at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundles(DirectoryWatcher.java:1248) at org.apache.felix.fileinstall.internal.DirectoryWatcher.doProcess(DirectoryWatcher.java:520) at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:365) at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:316)
So my portlet bundle wouldn't deploy because the javax.servlet available was not 3.1.0 or greater and less than 4.0.0. I happen to know that, with 7.1, the servlet spec jar version included is 3.0.1, so I know it is definitely not available.
The question, of course, is why am I trying to use 3.1.0?
Hmm, I think, and go check the dependency line in the build.gradle file:
compile group: "javax.servlet", name: "javax.servlet-api"
Yep, that looks right...
Ah well, I think, I'll just override what the target platform is assigning:
compile group: "javax.servlet", name: "javax.servlet-api", version: "3.0.1"
I do a clean build and deploy, but still get the same error.
What the heck?
Long story short, it's actually the Liferay 3rd party BOM file. In that BOM, it declares that version 3.1.0 is provided, even though it isn't.
But this setting trumps everything, even the specific version that I want to use when I put it in the dependency line.
I was stuck on this, but found some help from Ray Auge. He, too, had hit this recently when trying to use a custom BOM for an organization (they want to manage their versions across multiple projects).
I adapted the solution he came up with. I built and deployed my module, and all was well.
Here's the fix:
dependencies { implementation enforcedPlatform(group: "javax.servlet", name: "javax.servlet-api", version: "3.0.1") ... compile group: "javax.portlet", name: "portlet-api" compile group: "javax.servlet", name: "javax.servlet-api" compile group: "jstl", name: "jstl" ... }
The magic line w/ the enforcedPlatform() is a Gradle thing. I honestly don't know a lot about it (I'm sure you Gradle-heads can fill us in).
But I do know that it forces resolution to stick with the exact dependency version I've listed, regardless of what any of the BOMs might say and even regardless of a version added on the dependency line itself.
So if you're using the 7.1 Target Platform and you get this weird servlet 3.1.0 unresolved requirement issue, sneak that line in at the top of your dependencies list and you'll be able to get it to work.
Enjoy!