I've found the problem, answer below:
Original question: noob programmer here. I am working on a openfire server project, where our team is trying to integrate a apple push notification service plugin. However, the plugin I found has some trouble in the code, and the jsp page could never show up in openfire's admin console.
After numerous hours of manual debugging (cuz I totally suck and have no idea about apache's file upload module), I figured out the problem lies between this line:
List<FileItem> multiparts = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
If I disable the entire try clause, the page shows up fine. Of course, that means this jsp page would lose the ability to save uploaded files. After another countless hours of searching about this line I discovered nothing, so I decided to ask it here and give it a try.
I don't really understand what went wrong with this line, eclipse gave me a warning of Type safety: The expression of type List needs unchecked conversion to conform to List<FileItem>
, but the plugin compiles and builds fine. The syntax also looks right to me (been googling awhile, saw people using the same syntax too). Openfire is pretty useless in debugging, no valuable information was logged in error.log or debug.log.
Here is the entire jsp file if that helps. Thanks in advance.
apns.jsp:
<%@ page import="java.io.File,
java.util.List,
org.jivesoftware.openfire.XMPPServer,
org.jivesoftware.util.*,
com.wecapslabs.openfire.plugin.apns.ApnsPlugin,
org.apache.commons.fileupload.FileItem,
org.apache.commons.fileupload.disk.DiskFileItemFactory,
org.apache.commons.fileupload.servlet.ServletFileUpload,
org.apache.commons.fileupload.FileUploadException"
errorPage="error.jsp"
%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%-- Define Administration Bean --%>
<jsp:useBean id="admin" class="org.jivesoftware.util.WebManager" />
<c:set var="admin" value="${admin.manager}" />
<% admin.init(request, response, session, application, out ); %>
<% // Get parameters
boolean save = request.getParameter("save") != null;
boolean success = request.getParameter("success") != null;
boolean error = request.getParameter("error") != null;
String password = ParamUtils.getParameter(request, "password");
String badge = ParamUtils.getParameter(request, "badge");
String sound = ParamUtils.getParameter(request, "sound");
String production = ParamUtils.getParameter(request, "production");
ApnsPlugin plugin = (ApnsPlugin) XMPPServer.getInstance().getPluginManager().getPlugin("apns");
// Handle a save
if (save) {
plugin.setPassword(password);
plugin.setBadge(badge);
plugin.setSound(sound);
plugin.setProduction(production);
try {
List<FileItem> multiparts = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
for (FileItem item : multiparts) {
if (!item.isFormField()) {
String filename = item.getName();
item.write(new File(ApnsPlugin.keystorePath()));
}
}
response.sendRedirect("apns.jsp?success=true");
return;
} catch (Exception e) {
response.sendRedirect("apns.jsp?error=true");
return;
}
}
password = plugin.getPassword();
badge = Integer.toString(plugin.getBadge());
sound = plugin.getSound();
production = plugin.getProduction() ? "true" : "false";
%>
<html>
<head>
<title>APNS Settings Properties</title>
<meta name="pageID" content="apns-settings"/>
</head>
<body>
<% if (success) { %>
<div class="jive-success">
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr><td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0"></td>
<td class="jive-icon-label">
APNS certificate updated successfully.
</td></tr>
</tbody>
</table>
</div><br>
<% } %>
<form action="apns.jsp?save" method="post" enctype="multipart/form-data">
<div class="jive-contentBoxHeader">APNS certificate</div>
<div class="jive-contentBox">
<label for="file">p12 certificate:</label>
<input type="file" name="file" />
<br>
<label for="password">certificate password:</label>
<input type="password" name="password" value="<%= password %>" />
<br>
<label for="badge">payload badge</label>
<input type="badge" name="badge" value="<%= badge %>" />
<br>
<label for="sound">payload sound</label>
<input type="badge" name="sound" value="<%= sound %>" />
<br>
<label for="production">sandbox or production</label>
<input type="radio" name="production" value="false" <%= production.equals("true") ? "" : "checked" %>>Sandbox
<input type="radio" name="production" value="true" <%= production.equals("true") ? "checked" : "" %>>Production
</div>
<input type="submit" value="Save">
</form>
</body>
</html>
Let me answer my own questions here --
Because eclipse didn't warn me about the import problem, I thought everything the plugin needs was included, it wasn't.
Because openfire doesn't really tell you what went wrong, you have no idea that it was just a missing import.
Because the plugin failed to install via maven openfire plugin (author stopped supporting plugin ...), I had to manually link the source files into openfire source code, and inevitably missed the most important thing maven did for us -- dependencies check.
It turns out that all I need was commons-fileupload.jar and commons-io.jar, according to this post: How to upload files to server using JSP/Servlet?
Put the files inside {plugin-name}/lib, rebuild, and voila.