我试图在Weblogic上公开用Java编写的Spark ML代码作为REST服务。但是,在尝试初始化Spark Context时,代码会从 org.apache.hadoop.security 包中抛出 InvocationTargetException 。
以下是我使用的步骤:
经过分析,我发现代码在尝试初始化SparkContext时失败,这在我的Java代码中以下列方式完成:
SparkConf conf = new SparkConf().setAppName("IssuePredictor").setMaster("local").set("spark.sql.warehouse.dir", "spark-warehouse");
SparkContext sc = new SparkContext(conf);
我已经尝试过各种方式来引用spark-warehouse,包括文件夹的绝对路径或使用像这里指定的相对路径。但没有任何效果。
错误追踪:
ServletException的根本原因。了java.lang.RuntimeException: java.lang.reflect中。的的InvocationTargetException 在org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:134) 在 org.apache.hadoop.security.Groups。(Groups.java:79) 在org.apache.hadoop.security.Groups。(Groups.java:74) at org.apache.hadoop.security.Groups.getUserToGroupsMappingService(Groups.java:303) 在org.apache.hadoop.security.UserGroupInformation.initialize(UserGroupInformation.java:283) 在org.apache.hadoop.security.UserGroupInformation.ensureInitialized(UserGroupInformation.java:260) at org.apache.hadoop.security.UserGroupInformation.loginUserFromSubject(UserGroupInformation.java:790) at org.apache.hadoop.security.UserGroupInformation.getLoginUser(UserGroupInformation.java:760) at org.apache.hadoop.security.UserGroupInformation.getCurrentUser(UserGroupInformation.java:633) 在org.apache.spark.util.Utils $$ anonfun $ getCurrentUserName $ 1.apply(Utils.scala:2245) 在org.apache.spark.util.Utils $$ anonfun $ getCurrentUserName $ 1.apply(Utils.scala:2245) 在scala.Option.getOrElse(Option.scala:121) 在org.apache.spark.util.Utils $ .getCurrentUserName(Utils.scala:2245) 在 org.apache.spark.SparkContext。(SparkContext.scala:297) at myapps.ml.spark.IssuePredictor.predict(IssuePredictor.java:78)
...
引起者:java.lang.reflect.InvocationTargetException at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:132) 在org.apache.hadoop.security.Groups。(Groups.java:79) 在org.apache.hadoop.security.Groups。(Groups.java:74) at org.apache.hadoop.security.Groups.getUserToGroupsMappingService(Groups.java:303) 在org.apache.hadoop.security.UserGroupInformation.initialize(UserGroupInformation.java:283) 在org.apache.hadoop.security.UserGroupInformation.ensureInitialized(UserGroupInformation.java:260) at org.apache.hadoop.security.UserGroupInformation.loginUserFromSubject(UserGroupInformation.java:790) at org.apache.hadoop.security.UserGroupInformation.getLoginUser(UserGroupInformation.java:760) at org.apache.hadoop.security.UserGroupInformation.getCurrentUser(UserGroupInformation.java:633) 在org.apache.spark.util.Utils $$ anonfun $ getCurrentUserName $ 1.apply(Utils.scala:2245) 在org.apache.spark.util.Utils $$ anonfun $ getCurrentUserName $ 1.apply(Utils.scala:2245) 在scala.Option.getOrElse(Option.scala:121) 在org.apache.spark.util.Utils $ .getCurrentUserName(Utils.scala:2245) 在org.apache.spark.SparkContext。(SparkContext.scala:297) at myapps.ml.spark.IssuePredictor.predict(IssuePredictor.java:78)
...
引起者:java.lang.StackOverflowError 在org.slf4j.impl.JDK14LoggerAdapter.log(JDK14LoggerAdapter.java:659) at org.slf4j.bridge.SLF4JBridgeHandler.callLocationAwareLogger(SLF4JBridgeHandler.java:221) 在org.slf4j.bridge.SLF4JBridgeHandler.publish(SLF4JBridgeHandler.java:303) 在java.util.logging.Logger.log(Logger.java:738)
...
感谢任何帮助。
谢谢, 巴斯卡尔
答案 0 :(得分:0)
我认为您的问题是this。即您的类路径中存在jul-to-slf4j.jar和slf4j-jdk14.jar。
查看堆栈跟踪,Spark在创建spark上下文时试图找出用户及其组映射。为此,它需要实例化(堆栈中的ReflectionUtils.newInstance
调用)ShellBasedUnixGroupsMapping
类。在ShellBasedUnixGroupsMapping
中有这个静态调用
private static final Log LOG =
LogFactory.getLog(ShellBasedUnixGroupsMapping.class);
因为你正在进入上面提到的无限递归并最终导致堆栈溢出错误。
希望这有帮助。