Java Class Compiles Normally By Itself, But Throws NoClassFoundException Or NoClassDefFoundError When Run Through A JSP
I have a java class that successfully sends a Firebase message to my android phone. I am trying to run that class from a JSP file, but it results in NoClassFoundException and NoClassDefFoundError. Here is the JSP file:
<%@ page import="send.Notify" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
Api token is: <%
out.print(request.getParameter("token"));
%>
<%
Notify.SendMessage(request.getParameter("token"),"title","body");
%>
</body>
</html>
To be clear, I do get a normal output from out.print when Notify.SendMessage is commented out, so the problem isn't the input.
Here is my class:
package send;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.messaging.FirebaseMessaging;
import com.google.firebase.messaging.Message;
import com.google.firebase.messaging.Notification
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
public class Notify {
public static void main(String[] args) throws Exception{
SendMessage("f7ne...",
"title", "body");
}
public static void SendMessage(String registrationToken, String title, String body) throws Exception{
FileInputStream serviceAccount =
new FileInputStream("C:\\Users\\michael\\IdeaProjects\\servlet 3\\web\\notification-32ebc-firebase-adminsdk-5lbs4-643271e91a.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("https://notification-32ebc.firebaseio.com")
.build();
FirebaseApp.initializeApp(options);
Notification notification = new Notification(title, body);
Message message = Message.builder()
.setToken(registrationToken)
.setNotification(notification)
.build();
String response = FirebaseMessaging.getInstance().send(message);
System.out.println(response);
}
private static String getAccessToken() throws IOException {
GoogleCredential googleCredential = GoogleCredential
.fromStream(new FileInputStream("C:\\Users\\michael\\IdeaProjects\\servlet 3\\web\\notification-32ebc-firebase-adminsdk-5lbs4-643271e91a.json"))
.createScoped(Arrays.asList("https://www.googleapis.com/auth/firebase.messaging",
"https://www.googleapis.com/auth/firebase.database",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/firebase"));
googleCredential.refreshToken();
return googleCredential.getAccessToken();
}
}
Here is the error:
Type Exception Report
Message An exception occurred processing [/notification.jsp] at line [15]
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
org.apache.jasper.JasperException: An exception occurred processing [/notification.jsp] at line [15]
12: /*Notify.SendMessage("f7neXi6q4KQ:APA91bFI3acBwgtDq99_D2duax_qY1zAMGCE62yHQ5CsL-UhyJdvAs97CUhzXzY0q7tyWKX2JM0WlyvZtL-arTW9s1useO816ujda5c4gYKM-I_uCN8m81EH9clwNeVG6kQzGU-zl93k",
13: "jsp title", "jsp body");*/
14: try{
15: Notify.SendMessage(request.getParameter("token"),"title","body");
16: }catch (Exception e){
17: out.print("error!");
18: }
Stacktrace:
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:593)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:467)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
javax.servlet.ServletException: java.lang.NoClassDefFoundError: com/google/firebase/FirebaseOptions$Builder
org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:667)
org.apache.jsp.notification_jsp._jspService(notification_jsp.java:154)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:444)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
java.lang.NoClassDefFoundError: com/google/firebase/FirebaseOptions$Builder
send.Notify.SendMessage(Notify.java:26)
org.apache.jsp.notification_jsp._jspService(notification_jsp.java:135)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:444)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
java.lang.ClassNotFoundException: com.google.firebase.FirebaseOptions$Builder
org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1292)
org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1121)
send.Notify.SendMessage(Notify.java:26)
org.apache.jsp.notification_jsp._jspService(notification_jsp.java:135)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:444)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Note The full stack trace of the root cause is available in the server logs.
Here is my folder structure: https://prnt.sc/jocl6h
Answer
The problem was that Intellij doesn't use dependencies that you added to a project also to the tomcat server. To fix this, I manually added all the jars from my maven folder (C:\Users\user.m2) to the project/web/WEB-INF/lib folder.
It's a solution, but I'm still looking for the proper way to do it.
Update: I recently tried to refactor my program. In IntelliJ, create a new maven project from the apache webapp archetype. Then you can add all your dependencies and classes, and Tomcat will successfully find all of them.
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM