What are the possible causes of JasperException - java

I have a JSP that takes an Arraylist from the session object and removes the items from it. It seemed to be working fine and then out of nowhere when I navigate to that page, the page is blank. I checked the Tomcat log files and in catalina.out I am receiving a JasperException an it is showing it as being on a line with the following
for(int i; i < agentItems.size(); i++)
agentItems is the name of the ArrayList I am using. I have been debugging it and can't seem to figure out what the problem might be. I have read that a JasperException is sometiems thrown as a JSP's NullPointerException. Is this true or am I just completely overlooking the problem?
I have the web application running on a local machine and a intermediate server for development in which both of them have had no trouble. Why could it be that only on this server it is giving me problems?

That can be everything. You need to look a bit further in the stacktrace, peek to the caused by or root cause part and the trace which comes thereafter. It can be caused by many things. The JSP basically get compiled into one large try block and any catched Throwable will be wrapped into a servletcontainer specific exception like JasperException in Tomcat and clones. It boils down to this:
try {
// All translated JSP code comes here. Max 64K.
} catch (Throwable t) {
throw new JasperException(t);
}
Check the .java filename in the 1st line of the stacktrace, locate this in the work directory of the servletcontainer and open the file in an editor. Do you see it?
That said, using scriptlets is a bad practice. Use Servlets to control/preprocess/postprocess requests, use Javabeans to represent data models, use Taglibs in JSP to control the page flow and output, use Expression Language (EL) in JSP to access backend data. In your specific case, you can loop over an array or List using JSTL's c:forEach tag.
<c:forEach items="${agents}" var="agent">
<p>Agent: ${agent.name}
</c:forEach>

jasperexception can also occur when JSP is not able to access an element or item it's obtaining from outside and here it maybe is unable to access agentItems. Try to provide fully qualified class name or import the package otherwise.

Related

Display custom error message from a liferay hook service after an exception

I am overriding the addArticle and updateArticle methods of JournalArticleServiceImpl using a Hook. I am checking for all articles with a particular ddmStructureKey and that the current article has a unique value in a particular field.
I am throwing DuplicateEntryException exception when I find non-uniqueness. Within the curresponding catch method, I gave return null;. But it threw a NullPointerException. Then I tried to throw SystemException like follows.
try {
// logic
} catch (DuplicateEntryException e) {
LOG.error("Value already present", e);
throw new SystemException("Value already present", e);
}
But the result for the end users was as shown below. Even though in the logs, it displayed the actual error, it is not possible for users to understand what exactly happened in the background from this message.
I do not know how to display a custom error message to the end users from a Hook. Also to return to the same page to edit the same article.
Display error messages in Liferay:
You may use session messages, like <liferay-ui:error> tag.
For example in the jsp page:
<%# taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
...
<liferay-ui:error key="err1" message="Third message" translateMessage="false"/>
or with exception, like in edit_article.jsp:
<liferay-ui:error exception="<%= ArticleContentSizeException.class %>" message="you-have-exceeded-the-maximum-web-content-size-allowed" />
You can define your own exception class and your own message-key and the value for the key in Language.properties.
And in the render method:
SessionErrors.add(renderRequest, "err1");
or when catching an exception (e) use this:
SessionErrors.add(renderRequest, e.getClass());
A complete example on github - portlet, github - hook
As the UI layer seems to not expect any exception from these methods, this might call for changes in the UI- or Action-layer as well. When you do that, you might even get well along without service changes (because you can check upfront).
A hacky idea might be to not return null, but the duplicated value - simulating a successful update but returning the already existing article. Note that this is hacky, I'm not sure if it works always. If it breaks, please let me know how it breaks.

Why do I get an error "The method ... is undefined for the type..."?

I've build a method which takes strings as input parameter. In my index.jsp page, I retrieve a GET-variable from the URL using request.getParameter(). Now, I want to call the aforementioned method on this string, but I get a compiler error saying:
The method <method name>(String) is undefined for the type __2F_<webapp name>_2F_src_2F_main_2F_webapp_2F_index_2E_jsp".
Does anyone know why I get this error and how I can get rid of it. Any help is greatly appreciated!
My code is rather lengthy, but I think this is relevant code:
categorie = request.getParameter("categorie");
if (categorie.equals("")) {
categorie = "Category;";
}
ArrayList<String> categorieen = queryCategories(categorie);
You are calling ArrayList<String> categorieen = queryCategories(categorie); and you did not define queryCategories method. Since the JSP page is compiled into a big servlet class, it tries to locate queryCategories method as member of that class and it could not find it.
Very little information. Where is your app deployed? From what I gather, it seems you either haven't restarted the deployed app or have not replaced the changed class file and haven't set some sort of "development mode" on wherein you don't require a restart for a Jsp modification.
Just replace the .jsp and JSP_NAME.class file.

Servlet not retrieve parameters from AJAX call

I used AJAX to call an action and pass parameters, the AJAX call occurs from xsl page and its as follows:
xmlHttp.open("GET","examcont?action=AJAX_SectionsBySessionId&sessionId="+sessionId,true);
I decided to put the amp; after & as xsl raises this error when I removed it:
The reference to entity "sessionId" must end with the ';' delimiter
the problem is that the action is unable to read the parameter sessionId however I tried the same action URL but without the amp; and the action reads the parameter successfully
The problem seems to be that the & represents & in the style sheet but gets expanded/escaped to & again during output (because it is HTML/XML). You may try to use the following in XSL to avoid escaping:
xmlHttp.open("GET","examcont?action=AJAX_SectionsBySessionId<xsl:text disable-output-escaping="yes">&</xsl:text>sessionId="+sessionId,true);
However, note that - if you happen to let your XSL run in the browser - this does not work (although it is correct XSL and it should) on Firefox according to https://bugzilla.mozilla.org/show_bug.cgi?id=98168.
As portable alternative, you can use the following which avoids mentioning & by inserting it at runtime with what you might call "Javascript-escaping":
xmlHttp.open("GET","examcont?action=AJAX_SectionsBySessionId"+String.fromCharCode(38)+"sessionId="+sessionId,true);
Also have a look at similar question with deeper discussion and other options using a html entity in xslt (e.g. )

struts validation problem in IE

I am using Struts 2.1.8 and facing validation problem in IE. I am getting the following error
An exception occurred: Error. Error message: Invalid argument.
I tried out to figure out the cause and found the following. My generated javascript code is:
field = form.elements['district.name'];
var error = "Enter only alphabets for district";
if (continueValidation && field.value != null && !field.value.match("^[a-zA-Z ]*$")) {
addError(field, error);
errors = true;
}
I tried to mock up by putting the same code in a function and calling it in onclick event. The method addError() throws the exception and the reason is field variable. If I change it to field[0], it works fine. How to fix this error?
Check the generated HTML source. Open the page in webbrowser, rightclick and choose View Source. Is the input field's name really district.name? Isn't it prefixed/suffixed with some other autogenerated key (possibly the ID/name of the <form>) like as many other MVC frameworks do? If so, you'll need to change the JavaScript code accordingly that it uses the right element name as it appears in the HTML DOM tree. You know, JavaScript runs at the client machine and only sees the generated HTML DOM tree, not the "original" server-side code which is responsible for generating the HTML.

Where does Tomcat append / to directory paths?

Suppose my Tomcat webapps directory looks like this:
webapps/
webapps/fooapp/
webapps/fooapp/WEB-INF/
webapps/fooapp/WEB-INF/web.xml
webapps/fooapp/bardir/
When I make a GET request for /fooapp/bardir, Tomcat sees that webapps/fooapp/bardir is a directory and sends back a 302 to /fooapp/bardir/ (with a slash at the end).
Here is my question: Where in the Tomcat source code does this take place? (I'm looking at 6.0.x but a correct answer for any version would be a great starting point.)
The only reference material I can find on this subject is in the Catalina Functional Specifications which states, regarding the Default Servlet:
On each HTTP GET request processed by this servlet, the following processing shall be performed:
[...]
If the requested resource is a directory:
If the request path does not end with "/", redirect to a corresponding path with "/" appended so that relative references in welcome files are resolved correctly.
However, this functionality does not appear to be in org.apache.catalina.servlets.DefaultServlet; or at least, it's not there exclusively: if I replace the default servlet in web.xml with a servlet whose servlet-class does not exist, directory paths still come back 302 to add the slash, while every other request comes back with an error as expected.
I think it happens in org.apache.tomcat.util.http.mapper.Mapper, namely in the internalMapWrapper (Context, CharChunk, MappingData) method.
But unfortunately I'm not really sure -- maybe this really is a question better suited for the tomcat-users mailing list. Sorry for not having a better answer.
The Eclipse debugger learnt me that the redirect happens in line 504 of CoyoteAdapter class, almost in the end of the postParseRequest() method.
// Possible redirect
MessageBytes redirectPathMB = request.getMappingData().redirectPath;
if (!redirectPathMB.isNull()) {
// ...
response.sendRedirect(redirectPath); // <--- Here.
return false;
}
Tomcat 6.0.20 btw.
Update: actually, the redirectPath is indeed filled by the Mapper as mentioned in #Henning's answer, indeed in the internalMapWrapper() method. Checkout the source code here.
if(mappingData.wrapper == null && noServletPath) {
// The path is empty, redirect to "/"
mappingData.redirectPath.setChars
(path.getBuffer(), pathOffset, pathEnd);
path.setEnd(pathEnd - 1);
return;
}

Categories