Pet*_*ček 5 java classloader apache-storm
我正在尝试从Web容器运行本地集群(是的,它仅用于开发和测试目的)并且在使用类加载器时遇到困难.
当我这么简单和推荐的方式,
ILocalCluster localCluster = new LocalCluster();
localCluster.submitTopology(topologyName, stormConf, topology);
Run Code Online (Sandbox Code Playgroud)
我得到了回报
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)
Run Code Online (Sandbox Code Playgroud)
这是因为用于加载和实例化它的类加载器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);
}
Run Code Online (Sandbox Code Playgroud)
这实际上让我更进一步:
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
Run Code Online (Sandbox Code Playgroud)
笏?
如何从系统类加载器以外的类加载器安全地在本地模式下运行Storm拓扑?
我正在运行Apache Storm 1.0.1,Jetty 8.1,Java 8u112 x64,Windows 7 x64.
Apache Storm 1.0.3 神奇地解决了这个问题。
即使没有TOPOLOGY_TESTING_ALWAYS_TRY_SERIALIZE,尽管发行说明中没有修复的痕迹,所以我无法追踪到代码更改。不管怎样,我们很高兴它现在能按预期工作。
| 归档时间: |
|
| 查看次数: |
222 次 |
| 最近记录: |