I am migrating my Liferay portlets from 6.0 to Liferay 7.0 and one of the many roadblocks that I am hitting is the inclusion of my custom taglib.
I followed the advice from: Creating a custom taglib in Liferay 7 but my portlet fails to load the taglib, the following error is logged:
09:50:48,566 ERROR [http-nio-8080-exec-10][FreeMarkerManager:208] Unable to add taglib my_tags to context
FreeMarker template error:
freemarker.template.TemplateModelException: Error while loading tag library for URI "/META-INF/my_tags.tld" from TLD location "servletContext:/META-INF/my_tags.tld"; see cause exception.
at freemarker.ext.jsp.TaglibFactory.get(TaglibFactory.java:260)
at com.liferay.portal.template.freemarker.internal.FreeMarkerManager$TaglibFactoryWrapper.get(FreeMarkerManager.java:647)
at com.liferay.portal.template.freemarker.internal.FreeMarkerManager.addTaglibSupport(FreeMarkerManager.java:205)
at com.liferay.taglib.util.ThemeUtil.doIncludeFTL(ThemeUtil.java:276)
at com.liferay.taglib.util.ThemeUtil.doDispatch(ThemeUtil.java:157)
at com.liferay.taglib.util.ThemeUtil.includeFTL(ThemeUtil.java:100)
at com.liferay.taglib.util.ThemeUtil.include(ThemeUtil.java:82)
However, my bundle JAR does contain META-INF/my_tags.tld
What strikes me, is that the error does not happen when my JSP is loaded but somewhere inside the theme's FreeMarker template. Apparently my JSP isn't even loaded at that point.
The error is thrown on each page in my portal, not only those that contain my portlet(s) (which is to be expected if the theme is already failing to access the taglib)
The structure of the bundle JAR is:
com/
content/
META-INF/
+--- resources/
MANIFEST.MF
taglib-mappings.properties
my_tags.tld
OSGI-INF/
WEB-INF/
The MANIFEST.MF that is generated by the bnd task contains the following dependency:
Require-Capability: osgi.extender;osgi.extender="jsp.taglib";uri="/META-INF/my_tags.tld"
The file taglib-mappings.properties
contains:
my_tags=/META-INF/my_tags.tld
I also tried putting the .tld files into WEB-INF/tld
where it would be with a plain, simple, standard portlet or web application, but to no avail either.
Do I need to add a mapping in the web.xml
(I am not sure if the new OSGi portlets even use web.xml) or add some other configuration option?
OK, I managed to figure this out by myself.
The directory layout needs to be like this:
+---java
| \---com
| \---mypackage
| |
| +---portlet
| | MyPortlet.java
| |
| \---tags
| LabelTag.java
|
\---resources
+---content
| Language.properties
|
+---META-INF
| | my_tags.tld
| |
| \---resources
| | view.jsp
|
\---WEB-INF
In contrast to some hints on the internet, the file taglib-mappings.properties
is not needed. If it is present, Liferay throws a gazillion of exceptions because the Freemarker engine tries to access the taglibs that are referenced in taglib-mappings.properties
.
And my_tags.tld
contains the following:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.1</jsp-version>
<short-name>ka</short-name>
<uri>http://example.com/tld/my_tags</uri>
<tag>
<name>label</name>
<tag-class>com.mypackage.tags.LabelTag</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>labelText</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
</attribute>
</tag>
</taglib>
The in the JSP page, the tag is defined as:
<%@ taglib uri="http://example.com/tld/my_tags" prefix="my" %>
I do not include a Require-Capability:
for my own tags in the OSGI MANIFEST.MF file.
I only include that for the standard JSTL and Liferay tags:
Require-Capability: osgi.extender;filter:="(&(osgi.extender=jsp.taglib)(
uri=http://java.sun.com/portlet_2_0))",osgi.extender;filter:="(&(osgi.e
xtender=jsp.taglib)(uri=http://liferay.com/tld/aui))",osgi.extender;fil
ter:="(&(osgi.extender=jsp.taglib)(uri=http://liferay.com/tld/portlet))
",osgi.extender;filter:="(&(osgi.extender=jsp.taglib)(uri=http://lifera
y.com/tld/theme))",osgi.extender;filter:="(&(osgi.extender=jsp.taglib)(
uri=http://liferay.com/tld/ui))",osgi.ee;filter:="(&(osgi.ee=JavaSE)(ve
rsion=1.8))"
However, I did need to exclude some packages in the OSGI bnd.bnd file that were included due to the dependency on javax.servlet.jsp
and jstl
Import-Package: \
.....
!com.ibm.*,\
!com.sun.*,\
!javax.jmdns.*,\
*
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With