Java 在非默认类加载器下运行本地群集 来自web类加载器的本地集群

Java 在非默认类加载器下运行本地群集 来自web类加载器的本地集群,java,classloader,apache-storm,Java,Classloader,Apache Storm,我试图从web容器运行本地集群(是的,它仅用于开发和测试目的),但在使用类加载器时遇到了困难 直接法 当我用简单的方式做的时候 我得到了回报 Async loop died!: java.lang.ClassCastException: my.company.storm.bolt.SomeFilteringBolt cannot be cast to org.apache.storm.task.IBolt at org.apache.storm.daemon.executor$fn__7

我试图从web容器运行本地集群(是的,它仅用于开发和测试目的),但在使用类加载器时遇到了困难

直接法 当我用简单的方式做的时候

我得到了回报

Async loop died!: java.lang.ClassCastException: my.company.storm.bolt.SomeFilteringBolt cannot be cast to org.apache.storm.task.IBolt
    at org.apache.storm.daemon.executor$fn__7953$fn__7966.invoke(executor.clj:787)
    at org.apache.storm.util$async_loop$fn__625.invoke(util.clj:482)
    at clojure.lang.AFn.run(AFn.java:22)
    at java.lang.Thread.run(Thread.java:745)
这是因为用于加载和实例化
StormTopology
的类加载器是Jetty
WebAppClassLoader
的实例,但是
LocalCluster.submitTopology()
生成的(子)进程显然使用了系统类加载器。我通过将类加载器记录在
SomeFilteringBolt
的静态块中确认了这一点-该类确实加载了两次,而且WebAppCL中的螺栓显然不能稍后转换为系统类加载器上的螺栓

预期行为 现在,这让我感到惊讶,因为我认为Storm会序列化
StormTopology
实例,在本地“发送”它,反序列化它并运行它。不过,如果它做到了这一点,肯定会奏效。相反,它似乎直接使用提供的
StormTopology
实例,这在不同的类加载器下是有问题的

从那以后我试过什么 我尝试将这些设置为
true
,以强制Storm在本地序列化我的拓扑。没有变化

我尝试在系统类加载器下运行LocalCluster:

ClassLoader originalClassloader = Thread.currentThread().getContextClassLoader();
try {
    Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());

    Config topologyConf = createTopologyConfig();
    Map<String, Object> stormConf = createStormConfig(topologyConf);
    StormTopology topology = createTopology(topologyConf);

    ILocalCluster localCluster = new LocalCluster();
    localCluster.submitTopology(topologyName, stormConf, topology);
} finally {
    Thread.currentThread().setContextClassLoader(originalClassloader);
}
ClassLoader originalClassloader=Thread.currentThread().getContextClassLoader();
试一试{
Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
Config topologyConf=createTopologyConfig();
Map stormConf=createStormConfig(地形Conf);
StormTopology=createTopology(topologyConf);
ILocalCluster localCluster=新的localCluster();
localCluster.submitTopology(topologyName、stormConf、topology);
}最后{
Thread.currentThread().setContextClassLoader(originalClassloader);
}
这实际上让我更进一步:

Thread  died: java.lang.ExceptionInInitializerError
    at clojure.core__init.__init0(Unknown Source)
    at clojure.core__init.<clinit>(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at clojure.lang.RT.classForName(RT.java:2154)
    at clojure.lang.RT.classForName(RT.java:2163)
    at clojure.lang.RT.loadClassForName(RT.java:2182)
    at clojure.lang.RT.load(RT.java:436)
    at clojure.lang.RT.load(RT.java:412)
    at clojure.lang.RT.doInit(RT.java:454)
    at clojure.lang.RT.<clinit>(RT.java:330)
    at clojure.lang.Namespace.<init>(Namespace.java:34)
    at clojure.lang.Namespace.findOrCreate(Namespace.java:176)
    at clojure.lang.Var.internPrivate(Var.java:151)
    at org.apache.storm.LocalCluster.<clinit>(Unknown Source)
    at my.company.storm.LocalTopologyRunner.startTopology(LocalTopologyRunner.java:146)
    ... 10 more
Caused by: java.lang.IllegalStateException: Attempting to call unbound fn: #'clojure.core/refer
    at clojure.lang.Var$Unbound.throwArity(Var.java:43)
    at clojure.lang.AFn.invoke(AFn.java:32)
    at clojure.lang.Var.invoke(Var.java:379)
    at clojure.lang.RT.doInit(RT.java:467)
    at clojure.lang.RT.<clinit>(RT.java:330)
    ... 18 more
线程死机:java.lang.ExceptionInInitializerError
在clojure.core\uuuu init.\uuuu init0(未知源)
在clojure.core\uuu init(未知源)
位于java.lang.Class.forName0(本机方法)
位于java.lang.Class.forName(Class.java:348)
位于clojure.lang.RT.classForName(RT.java:2154)
位于clojure.lang.RT.classForName(RT.java:2163)
位于clojure.lang.RT.loadClassForName(RT.java:2182)
在clojure.lang.RT.load(RT.java:436)
在clojure.lang.RT.load处(RT.java:412)
在clojure.lang.RT.doInit(RT.java:454)
在clojure.lang.RT.(RT.java:330)
位于clojure.lang.Namespace。(Namespace.java:34)
位于clojure.lang.Namespace.findOrCreate(Namespace.java:176)
位于clojure.lang.Var.internPrivate(Var.java:151)
位于org.apache.storm.LocalCluster。(来源未知)
在my.company.storm.LocalTopologyRunner.startTopology(LocalTopologyRunner.java:146)
... 10多
原因:java.lang.IllegalStateException:尝试调用未绑定的fn:#'clojure.core/reference
位于clojure.lang.Var$Unbound.throwArity(Var.java:43)
位于clojure.lang.AFn.invoke(AFn.java:32)
在clojure.lang.Var.invoke(Var.java:379)
在clojure.lang.RT.doInit(RT.java:467)
在clojure.lang.RT.(RT.java:330)
... 还有18个

问题 如何从系统类加载器以外的类加载器以本地模式安全运行Storm拓扑


我运行的是Apache Storm 1.0.1、Jetty 8.1、Java 8u112 x64、Windows 7 x64。

根本不是Storm专家,但这让我想起了我过去遇到的一个“身份危机”问题

尝试两件事:

  • 通过调用
    org.eclipse.jetty.webapp.WebAppContext.setParentLoaderPriority(true)

  • 如果不起作用,可以调用方法
    org.eclipse.jetty.webapp.WebAppContext.setSystemClasses
    org.eclipse.jetty.webapp.WebAppContext.addSystemClass
    ,以控制哪些类在webapp域内被视为系统类

在加载之前(在webappinit期间),对整个storm包执行此操作(它允许使用通配符,如“org.apache.storm.”)


值得一试!祝你好运。

Apache Storm 1.0.3神奇地修复了这个问题


即使没有
TOPOLOGY\u TESTING\u ALWAYS\u TRY\u SERIALIZE
,即使发行说明中没有修复的痕迹,我也无法跟踪到代码更改。无论如何,我们很高兴它现在能像预期的那样工作。

第一个选项不幸不起作用(我必须升级和重新配置很多东西才能到达那里,并通过系统属性进行设置,真遗憾),抛出了同样的错误。第二个选项目前对我不可用,因为我无法控制服务器初始化(本地是因为GWT Maven插件不是很灵活,在服务器上是因为我们公司提供的Jetty库不是很灵活,argh)。我最终会到达那里,只是需要时间。将更新。非常感谢。
Thread  died: java.lang.ExceptionInInitializerError
    at clojure.core__init.__init0(Unknown Source)
    at clojure.core__init.<clinit>(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at clojure.lang.RT.classForName(RT.java:2154)
    at clojure.lang.RT.classForName(RT.java:2163)
    at clojure.lang.RT.loadClassForName(RT.java:2182)
    at clojure.lang.RT.load(RT.java:436)
    at clojure.lang.RT.load(RT.java:412)
    at clojure.lang.RT.doInit(RT.java:454)
    at clojure.lang.RT.<clinit>(RT.java:330)
    at clojure.lang.Namespace.<init>(Namespace.java:34)
    at clojure.lang.Namespace.findOrCreate(Namespace.java:176)
    at clojure.lang.Var.internPrivate(Var.java:151)
    at org.apache.storm.LocalCluster.<clinit>(Unknown Source)
    at my.company.storm.LocalTopologyRunner.startTopology(LocalTopologyRunner.java:146)
    ... 10 more
Caused by: java.lang.IllegalStateException: Attempting to call unbound fn: #'clojure.core/refer
    at clojure.lang.Var$Unbound.throwArity(Var.java:43)
    at clojure.lang.AFn.invoke(AFn.java:32)
    at clojure.lang.Var.invoke(Var.java:379)
    at clojure.lang.RT.doInit(RT.java:467)
    at clojure.lang.RT.<clinit>(RT.java:330)
    ... 18 more