After applying CF39 on 6.1.0.3, 6.1.0.4, 6.1.0.5 (PM25810) or 6.1.5.x (PM25794) WCM, the Ephox EditLive! editor does not load up

After applying CF39 on 6.1.0.3, 6.1.0.4, 6.1.0.5 (PM25810) or 6.1.5.x (PM25794) WCM, the Ephox EditLive! editor does not load up.

Symptoms :-

The primary symptom is when viewing a rich text element the following error is seen on the browser

JSP Processing Error
HTTP Error Code 500

Error Messages :-

JSPG0227E: Exception caught while translating /jsp/html/EditLiveJavaEditor.jsp:
/jsp/html/EditLiveJavaEditor.jsp(0,1) --> JSPG0005E: tld file could not be found for uri[/WEB-INF/tld/ilwwcm.tld] prefix [ilwwcm]

Root Cause :-

com.ibm.ws.jsp.translator.JspTranslationException: JSPG0227E: Exception caught while translating /jsp/html/EditLiveJavaEditor.jsp:
/jsp/html/EditLiveJavaEditor.jsp(0,1) --> JSPG0005E: tld file could not be found for uri[/WEB-INF/tld/ilwwcm.tld] prefix [ilwwcm]
at com.ibm.ws.jsp.translator.visitor.validator.ValidateVisitor.visitJspRootStart(ValidateVisitor.java:516)
at com.ibm.ws.jsp.translator.visitor.JspVisitor.processJspElement(JspVisitor.java:138)


Resolution :-

CF40 will resolve this issue. This should be installed on top of CF39.
Until CF40 is available, a downgrade to CF38 will resolve this issue

IBM Support Tools portlet for Lotus WCM

The IBM Support Tools portlet for Lotus WCM is useful to troubleshoot content related issues.

ClickHere to download Portlet from IBM Solution Catalog (Lotus GreenHous login required)

This portlet includes tools to view the JCR repository for WCM content, run an xpath query and view results, and directly execute various support jsps

Writing Custom Portlet Mode in WebSphere Portal



Steps
a.  Override generic portlet Dispatch method

private static final PortletMode CUSTOM_CONFIG_MODE = new PortletMode("config");
private static final PortletMode CUSTOM_EDIT_DEFAULTS_MODE = new PortletMode("edit_defaults");

protected void doDispatch(RenderRequest request, RenderResponse response) throws PortletException, IOException {
              if (!WindowState.MINIMIZED.equals(request.getWindowState())){
                     PortletMode mode = request.getPortletMode();                 
                     if (CUSTOM_CONFIG_MODE.equals(mode)) {
                           doCustomConfigure(request, response);
                           return;
                     }
                     else if (CUSTOM_EDIT_DEFAULTS_MODE.equals(mode)) {
                           doCustomEditDefaults(request, response);
                           return;
                     }
              }
              super.doDispatch(request, response);
       }

b. Add following in the portlet.xml

<custom-portlet-mode>
            <portlet-mode>config</portlet-mode>
      </custom-portlet-mode>
      <custom-portlet-mode>
            <portlet-mode>edit_defaults</portlet-mode>
</custom-portlet-mode>

Add following entries under the portlet tag
<supports>
      <portlet-mode>config</portlet-mode>
      <portlet-mode>edit_defaults</portlet-mode>
</supports>

Note: If a custom portlet mode defined in the deployment descriptor is not mapped to a custom portlet mode provided by WebSphere Portal, portlets must not be invoked in that portlet mode.  Ex: you can not create like "resize" mode for the portlet that deployed in websphere as websphere doesn't support it.

Making AJAX call using DWR (Direct Web Remoting)

This Article will explain how to make DWR (Direct Web Remoting) AJAX call from JSP

Follow the simple Steps
a         Copy the DWR jar file to the Lib directory under webcontent/WEB-INF (download from here)
b        Copy the following xml snippet to the web.xml
<servlet> 
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
                      <param-name>debug</param-name>
                      <param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>

c         Create or Copy the dwr.xml under the WEB-INF directory and content of the file is as follows
<!DOCTYPE dwr PUBLIC
    "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"
    "http://getahead.org/dwr/dwr20.dtd">

<dwr>
  <allow>
    <create creator="new" javascript=" AjaxDWRTest">
      <param name="class" value="com.vaka.siva.helper.AjaxDWRTest"/>
    </create>
  </allow>
</dwr>

d        Write a class with public methods and className  should be like as specified in dwr.xml (If you need the  HTTPServletSession then we use below extra code)

public class AjaxDWRTest {
public String getDisplayedTickets(int pageIndex) {
                                               
                                                WebContext ctx = WebContextFactory.get();
                                                HttpServletRequest request = ctx.getHttpServletRequest();
                                                HttpSession session = ctx.getSession();
                                                if (session == null)return null;
                                               
//call to some helpers and do the processing
//you can make backend calls now or you can make backend calls first and store it in the session and now retrieve from session

return tktstr
}
e        In above XML , we have specified the AjaxDWRTest as javascript ,so DWR will create  that for us we just need to include the following in JSP where we need the AJAX call

<script type="text/javascript" src='<%= renderResponse.encodeURL(renderRequest.getContextPath()+ "/dwr/interface/AjaxDWRTest.js") %>'>
</script>
<script type="text/javascript" src='<%= renderResponse.encodeURL(renderRequest.getContextPath()+ "/dwr/engine.js") %>'>

f          Following is the way we invoke the callback method in JSP

//Print the table with initial values List (this is not ajax call)
<c:if test="${!empty SessionBean.initialTicketValuesMap}">
<script type="text/javascript">
               <portlet:namespace/>paintDynaSec(intialTicketValuesString);
</script>
</c:if>

//following is AJAX call , when somebody click next page then we call below
AjaxDWRTest.getDisplayedTickets(currentPageIndex, <portlet:namespace/>paintDynaSec);

//Once AJAX backend call is over then above statement will automatically calls paintDynaSec javascript function with parameter that is returned from the AJAX
function <portlet:namespace/>paintDynaSec(tktstr) {
                        ticketList.innerHTML =tktstr;
}

Making AJAX call using smiple XMLHTTPRequest Object

This Article will explain how to make simple AJAX call from JSP 

Follow the simple Steps 
a.         Create a servlet (can be any server side component that listen to requests and respond back like JSP or PHP).
b.       In JSP file, first get the XMLHttpRequest object (it is different for different browsers)
c.         onreadystatechange property: After a request send to a server, we need a function to receive the data returned from the server. The onreadystatechange property stores the function that will process the response from a server. The function is stored in the property to be called automatically.
xmlhttp.onreadystatechange=function()
{
// We are going to write some code here
}
d.        readyState property: The readyState property holds the status of the server's response each time the readyState property changes, the onreadystatechange function will be executed .Possible values for readyState property are
i           0 – request is not intialized
ii         1 – request has been setup
iii        2 – request has sent
iv       3 – request in progress
v         4 – request is completed
e.        To send off a request to the server, we use the open() and send() methods.
i           Open(): The open() method takes three arguments. The first argument defines which method to use when sending the request (GET or POST). The second argument specifies the URL of the server-side script. The third argument specifies that the request should be handled asynchronously(true – asynchronous , false – synchronous )
ii         Send: The send() method sends the request off to the server.
f.          Sample is as follows
//getting XMLHttpRequest Object
function getXMLHTTPObject(){
if(window.XMLHttpRequest){
return new XMLHttpRequest();
}
if(typeof XMLHttpRequest != 'undefined'){
   return new XMLHttpRequest();
}else{
  try{
  return new ActiveXObject("Msxml2.XMLHTTP");
  }catch(e){
  try{
          return new ActiveXObject("Microsoft.XMLHTTP");
  }catch(e){}
  }
}
 return false;
}
//make AJAX call
function invokeAjax(){
       xmlHTTP=getXMLHTTPObject();
       var ajaxServletURL="<%=response.encodeUrl(request.getContextPath())%>"+"/SivaAjaxServlet?name=siva";
       xmlHTTP.open("POST",ajaxServletURL,true);
       xmlHTTP.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");
       xmlHTTP.onreadystatechange=httpResponse;
       xmlHTTP.send(null);
}
 //callback method
function httpResponse(){
  if(xmlHTTP.readyState==4){
    document.getElementById("ajaxdiv").innerHTML=xmlHTTP.responseText;
  }
}
 //simple html elements gets change after ajax call
<div id="ajaxdiv">
 <table>
       <tr><td>Loading ....Ajax example</td><td><input type="button" onClick="invokeAjax()" name="but1" value="submit"/></td></tr>
 </table>
</div></div>


Invalidate the browser cache

Set the following response headers to invalidate any browser Cache.


response.setHeader("Pragma","no-cache"); 
response.setHeader("Cache-Control","no-cache, no-store, must-revalidate"); response.setHeader("max-age","0");  


Alternatively you can use the HTTP meta equivalent tags to do in HTML 

<meta http-equiv="Cache-Control" content="no-store,no-cache, must-revalidate,post-check=0, pre-check=0,max-age=0">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0"> 


Click Here for more options on cahce-control

Troubleshooting DataBase (DB) Performance Issues

At some point in any project implementation, need to troubleshoot the DB either to resolve the problem or performance.

Things to consider

1. Check the connection pool size
2. Fine Tune SQL statements
3. Execute  "UPDATESTATS" at DB side  to update the tablespace sizes and make updates to stats
4. Check the webserver I/O timeout , if it is very low (like 10sec) sometime you may receive the 500 (server timeout). HTTP server timeout should be aggregate of  considering DB response time + application response time
5. Considering the option of creating materialized view or MQT(materialized query table).