我正在开发一个动态网络项目。我想编写一个servlet类来响应帧提交请求,并使用apache spark执行一些集群计算任务(例如,计算pi)。 servlet的doGet函数(名为Hello)如下:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String [] args=new String[2];
args[0]="local";
args[1]="4";
double count=0;
count=performSpark.cpi(args);
//double count=3.14;
String text1 =String.valueOf(count);
response.sendRedirect("wresultjsp.jsp?text1=" + text1);
}
performSpark类如下:
public class performSpark {
static double cpi(String[] input)
{
JavaSparkContext jsc = new JavaSparkContext(input[0], "performspark",
System.getenv("SPARK_HOME"), JavaSparkContext.jarOfClass(performSpark.class));
int slices = (input.length == 2) ? Integer.parseInt(input[1]) : 2;
int n = 1000000 * slices;
List<Integer> l = new ArrayList<Integer>(n);
for (int i = 0; i < n; i++)
{
l.add(1);
}
JavaRDD<Integer> dataSet = jsc.parallelize(l);
int count = dataSet.map(new Function<Integer, Integer>() {
@Override
public Integer call(Integer integer) {
double x = Math.random() * 2 - 1;
double y = Math.random() * 2 - 1;
return (x * x + y * y < 1) ? 1 : 0;
}
}).reduce(new Function2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer integer, Integer integer2) {
return integer + integer2;
}
});
double result=4.0 * count / n;
return result;
}
}
spark-assemply-2.10-0.9.1-hadoop2.2.0.jar
被复制到WEB-INF/lib
。
构建成功但是当我在tomcat7服务器中运行servlet时,在创建JavaSparkContext时会报告java.lang.ClassNotFoundException
:
用于servlet [Hello]的Servlet.service()与path的上下文 [/ sparkdemo]抛出异常[Servlet执行抛出异常] 根本原因java.lang.ClassNotFoundException: org.apache.spark.api.java.function.Function at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720) 在 org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571) 在Hello.doGet(Hello.java:54)的Hello.doPost(Hello.java:74)at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)at at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
任何人都知道如何纠正这个问题?
答案 0 :(得分:1)
最后,我找到了解决方案如下。
当tomcat服务器启动时,它会加载spark-assemply-2.10-0.9.1-hadoop2.2.0.jar
并报告错误:validateJarFile (.....) - jar not loaded. See Servlet Spec3.0 ......
,这表示存在一些重叠的jar依赖关系。
然后我打开spark-assemply-2.10-0.9.1-hadoop2.2.0.jar
并在javax / servlet中找到重叠的文件夹。删除servlet文件夹后,spark-assemply-2.10-0.9.1-hadoop2.2.0.jar
在tomcat中成功加载,ClassNotFoundException消失。
答案 1 :(得分:0)
我们在项目中有一个类似的用例,我们要提交用户查询以从Web项目中以交互方式触发。 实现此目标的方法是,首先创建一个spark会话,然后将其自定义servlet附加到:.attachHandler()
在自定义servlet的attachHandler方法中,我们将Servlet类附加到spark的ServletContextHandler:
ServletContextHandler handler = new ServletContextHandler();
HttpServlet servlet = new <CustomServlet>(spark);
ServletHolder sh = new ServletHolder(servlet);
handler.setContextPath(<root context>);
handler.addServlet(sh, <path>);
spark.sparkContext().ui().get().attachHandler(handler);
现在,该Servlet已在端口4040上附加到Spark UI,例如,您可以直接向其提交请求。我们覆盖了servlet的doGet方法,以接受包含要运行的SQL的JSON,并使用
提交了SQL
ds = this.spark.sql(query);
迭代返回的数据集,并将其添加到响应对象。
另一种方法是利用Apache Livy。
希望这会有所帮助。