Expand my Community achievements bar.

SOLVED

Issue with creating Custom Tag Library in CQ5.5

Avatar

Former Community Member

Hi,

I am creating a custom tag library and want to use it in one of my components. I have created a bundle which includes tag hello class which is extending TagSupport class and i created tags.tld file under my resource folder

In my pom.xml, I have used resource tag to include my .tld file in the generated jar file.

Here is my java class and tld file

TAG CLASS:-

package com.cb;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* Simple tag example to show how content is added to the
* output stream when a tag is encountered in a JSP page.
*/
public class Hello extends TagSupport {
private String name=null;
  /**
   * Getter/Setter for the attribute name
     as defined in the tld file
   * for this tag*/
public void setName(String value){
    name = value;
}
public String getName(){
      return(name);
}
/**
* doStartTag is called by the JSP container
  when the tag is encountered */
public int doStartTag() {
  try {
    JspWriter out = pageContext.getOut();
    out.println("<table border=\"1\">");
     if (name != null)
      out.println("<tr><td> Welcome <b>" + name +
        "</b> </td></tr>");
    else
      out.println("<tr><td> Hello World </td></tr></table>");
  } catch (Exception ex) {
    throw new Error("All is not well in the world.");
  }
  // Must return SKIP_BODY because we are not
       //supporting a body for this
  // tag.
  return SKIP_BODY;
}
/**
* doEndTag is called by the
  JSP container when the tag is closed */
public int doEndTag(){
   return EVAL_PAGE;
}
}

TLD File:-

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0">
    <description>My tag library123</description>
    <tlib-version>1.11</tlib-version>
    <uri>http://cs.test.com/bundles/cq/1.11</uri>
    <tag>
      <name>hello</name>
      <tagclass>com.cb.Hello</tagclass>
      <bodycontent>empty</bodycontent>
      <info>This is a simple hello tag</info>
    <attribute>
      <name>name</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
    </attribute>
    </tag>
</taglib>

I also successfully installed the bundle in my felix console without having any error. Then i written custom tag in my jsp as below

JSP:-

<%@include file="/libs/foundation/global.jsp"%>
<%@ page import="com.cb.Hello"%>
<%@ taglib prefix="mytest" uri="http://cs.test.com/bundles/cq/1.11"%>
<mytest:hello name="sachin"></mytest:hello>

I am getting error as "org.apache.sling.api.scripting.ScriptEvaluationException: org.apache.sling.scripting.jsp.jasper.JasperException: /apps/test/components/content/test/test.jsp(4,0) Unable to load tag handler class "com.cb.Hello" for tag "mytest:hello".

The same code is working fine in my apache tomcat server without having any issue. I am getting the error when i incorporate it in CQ.

What am i doing here? Is there any config i need to do in OSGI console to make it available?

Please guide me to resolve.

Thanks

1 Accepted Solution

Avatar

Correct answer by
Level 7

Justin is correct there, just thought I would add some info to the problem. 

Since you are embedding the JSP API outside the OSGi environment (a different API) you will get that specific class loading error message. 
This is due to that the classes, variables etc. loaded from the non OSGi environment are loaded with a different class loader than those in the OSGi environment. This will create problems since it wont see them as the same class.

I would strongly follow Justin's advice and remove all the unnecessary things from the POM.
/j

View solution in original post

16 Replies

Avatar

Employee

Hi,

The first thing you should check is that the package com.cb is exported by your bundle.

Regards,

Justin

Avatar

Former Community Member

Yes, I have included it my pom.xml as below

            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Export-Package>com.cb.*</Export-Package>
                        <Import-Package>*;resolution:=optional</Import-Package>
                        <Bundle-SymbolicName>com.cb.-bundle</Bundle-SymbolicName>
                    </instructions>
                </configuration>
            </plugin>

Is there any other thing that i am missing in my pom.xml?

Thanks

Avatar

Employee

If I'm reading this correctly, the package is com.cb. The pattern in your pom is com.cb.*. Therefore, com.cb won't be exported as it doesn't match that pattern. Perhaps you meant to have your taglib in com.cb.taglib or com.cb.tags ?

Avatar

Former Community Member

Hi,

I placed my tags.tld file inside com.cb folder and I have given full path in Export-Packag as below

<Export-Package>com.cb.Hello,com.cb.tags.tld</Export-Package>

But still it gives the same error "Unable to load tag handler class "com.cb.Hello" for tag "mytest:hello""

Is it what did you mean?

Thanks

Avatar

Employee

If your tag lib references the class com.cb.Hello, then the package com.cb needs to be exported. So that would be 

<Export-Package>com.cb</Export-Package>

In OSGi, you always export packages, not individual classes. So the directive

<Export-Package>com.cb.Hello</Export-Package>

is not correct, assuming that Hello is a class.

Avatar

Former Community Member

Hi,

I have tired with <Export-Package>com.cb</Export-Package> as you have said. But still it gives the same error "Unable to load tag handler class "com.cb.Hello" for tag "mytest:hello""

Could you please tell me whether i am following correct maven folder structure?

Here is my maven folder strusture

bundle -> src -> main -> java -> com-> cb -> Hello.java
bundle -> src -> main -> resources -> tags.tld

and here is my jar file structure

cb-bundle-1.0-SNAPSHOT -> META-INF -> tags.tld
cb-bundle-1.0-SNAPSHOT -> OSGI-INF -> .....
cb-bundle-1.0-SNAPSHOT -> com.cb -> Hello.class

I have also exported my Hello.java as below

<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <extensions>true</extensions>
    <configuration>
    <instructions>
        <Export-Package>com.cb</Export-Package>
        <Import-Package>*;resolution:=optional</Import-Package>
        <Bundle-SymbolicName>com.cb-bundle</Bundle-SymbolicName>
    </instructions>
    </configuration>
</plugin>

Is there anything i am following wrong here?

Thanks !

Avatar

Employee

Anderson-

Unless it is the optional import (which is usually a hack to work around some other issue), this looks OK to me. If you want to post the JAR file or private message it to me, I can take a look at it.

Johan-

I don't think this is the same issue - it looks like the TLD is being read - otherwise you wouldn't get the class name in the error message.

Avatar

Level 7

Ah ok, sorry.
Looks like you have and inconstisting URI for the t.ld file and the .jsp file. Shouldn't they both be 1.9 ?

Avatar

Former Community Member

Hi Justin,

Thanks for your interest. I have sent the jar file to your mail. Please find the attached jar and let me if anything requires.

@ Ojjis, I have been using same URI in both places. Sorry i forgot to change the version while posting here.

 

Thanks

Avatar

Employee

Hi Anderson,

It looks like your exports are still incorrect. In the bundle you sent, the tag class is com.cb.Helllo, so it is in the package com.cb. However, this package is not exported. In your pom.xml file you have:

<Export-Package>com.gecb.*</Export-Package>

Which won't export com.cb.

Regards,
Justin

Avatar

Former Community Member

Hi,

I am really sorry. I am exporting the correct package only. There was some conflict in copy/paste

Again I have sent correct bundle to you. Could you please check it once if possible?

Thanks

Avatar

Employee

There are a number of issues with the bundle you sent. The most significant is that the Activator defined in the MANIFEST.MF file does not exist. This causes an exception when the bundle is installed:

Caused by: java.lang.ClassNotFoundException: com.cqblueprints.example.taglib.osgi.Activator not found by com.gecb.gecapitalbank-bundle [323] at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1500) at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75) at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1923) at java.lang.ClassLoader.loadClass(ClassLoader.java:356) at org.apache.felix.framework.BundleWiringImpl.getClassByDelegation(BundleWiringImpl.java:1357) at org.apache.felix.framework.Felix.createBundleActivator(Felix.java:4311) ... 50 more

In addition, you should not be embedding the JSP API. This will cause other issues.  In fact, it looks like 100% of the configuration you have of the maven-bundle-plugin is either unnecessary or causing issues.

Avatar

Former Community Member

Hi Justin,

There was some problem with package name. Now Sling can read my tag handler class after i renamed the package name.

The error "Unable to load tag handler class" also has gone.

Now i am getting error as "org.apache.sling.api.scripting.ScriptEvaluationException: javax.servlet.ServletException: javax.servlet.jsp.JspException: com.testcb.TestCustomTag cannot be cast to javax.servlet.jsp.tagext.Tag"

I have the following dependency in pom.xml

<dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.1</version>
</dependency>

And Here is my tld

<?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0">
    <description>My tag library123</description>
    <tlib-version>1.0</tlib-version>
    <short-name>TagLib-Test</short-name>
    <uri>http://cs.test.com/bundles/cq/1.0</uri>
    <jspversion>2.1</jspversion>
    <tag>
      <name>testcustomtag</name>
      <tagclass>com.testcb.TestCustomTag</tagclass>
      <bodycontent>empty</bodycontent>
      <info>This is a simple hello tag</info>
    <attribute>
      <name>name</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
    </attribute>
    </tag>
</taglib>

Is there any problem with jsp version?

Thanks

Avatar

Employee

Hi,

First off, I find it very confusing that you are posting to two separate topics on the same issue. If your issue is still persisting, I'd recommend starting a new thread and only use a single thread.

The issue you are describing is caused by embedding the JSP API. I wrote this yesterday in this thread:

"In addition, you should not be embedding the JSP API. This will cause other issues.  In fact, it looks like 100% of the configuration you have of the maven-bundle-plugin is either unnecessary or causing issues."

Regards,

Justin

Avatar

Correct answer by
Level 7

Justin is correct there, just thought I would add some info to the problem. 

Since you are embedding the JSP API outside the OSGi environment (a different API) you will get that specific class loading error message. 
This is due to that the classes, variables etc. loaded from the non OSGi environment are loaded with a different class loader than those in the OSGi environment. This will create problems since it wont see them as the same class.

I would strongly follow Justin's advice and remove all the unnecessary things from the POM.
/j