enonic / xp

Enonic XP
https://enonic.com
GNU General Public License v3.0
202 stars 34 forks source link

Invalid BundleContext when using libEvent.send in main.js #6667

Closed ComLock closed 4 years ago

ComLock commented 6 years ago

It should be possible to use libEvent.send in main.js, right?

I'm trying to make a queue that wakes up and looks for something to do whenever it gets a event.

So basically I do this:

listen for FINISHED | FAILED | HUP and when available power submitNamedTask;
while (true) { sleep(delay) and send HUP };

But I just get Invalid BundleContext

ComLock commented 6 years ago

Here is the stack trace. It actually starts sending the events afterwards, so perhaps its just the first one that fails.

2018-10-17 15:04:01,874 ERROR c.e.xp.portal.impl.main.MainExecutor - Error executing [com.enonic.app.crawler:/main.js]
com.enonic.xp.resource.ResourceProblemException: Invalid BundleContext.
    at com.enonic.xp.resource.ResourceProblemException$Builder.build(ResourceProblemException.java:131)
    at com.enonic.xp.script.impl.util.ErrorHelper.doHandleException(ErrorHelper.java:54)
    at com.enonic.xp.script.impl.util.ErrorHelper.handleError(ErrorHelper.java:27)
    at com.enonic.xp.script.impl.executor.ScriptExecutorImpl.executeRequire(ScriptExecutorImpl.java:223)
    at com.enonic.xp.script.impl.executor.ScriptExecutorImpl.requireJs(ScriptExecutorImpl.java:268)
    at com.enonic.xp.script.impl.executor.ScriptExecutorImpl.requireJsOrJson(ScriptExecutorImpl.java:282)
    at com.enonic.xp.script.impl.executor.ScriptExecutorImpl.executeRequire(ScriptExecutorImpl.java:177)
    at com.enonic.xp.script.impl.executor.ScriptExecutorImpl.executeMain(ScriptExecutorImpl.java:129)
    at com.enonic.xp.script.impl.standard.ScriptRuntimeImpl.execute(ScriptRuntimeImpl.java:34)
    at com.enonic.xp.portal.impl.script.PortalScriptServiceImpl.execute(PortalScriptServiceImpl.java:53)
    at com.enonic.xp.portal.impl.main.MainExecutor.executeMain(MainExecutor.java:63)
    at com.enonic.xp.portal.impl.main.MainExecutor.started(MainExecutor.java:51)
    at com.enonic.xp.portal.impl.main.MainExecutor.started(MainExecutor.java:46)
    at com.enonic.xp.portal.impl.main.MainExecutor.onEvent(MainExecutor.java:40)
    at com.enonic.xp.core.impl.event.EventMulticaster.publish(EventMulticaster.java:51)
    at com.enonic.xp.core.impl.event.EventMulticaster.publish(EventMulticaster.java:43)
    at com.enonic.xp.core.impl.event.EventPublisherImpl.lambda$dispatchEvent$0(EventPublisherImpl.java:66)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalStateException: Invalid BundleContext.
    at org.apache.felix.framework.BundleContextImpl.checkValidity(BundleContextImpl.java:511)
    at org.apache.felix.framework.BundleContextImpl.getServiceReference(BundleContextImpl.java:360)
    at org.apache.felix.framework.BundleContextImpl.getServiceReference(BundleContextImpl.java:381)
    at com.enonic.xp.script.impl.service.ServiceRefImpl.findService(ServiceRefImpl.java:33)
    at com.enonic.xp.script.impl.service.ServiceRefImpl.get(ServiceRefImpl.java:22)
    at com.enonic.xp.lib.event.EventSenderHelper.send(EventSenderHelper.java:63)
    at jdk.nashorn.internal.scripts.Script$Recompilation$13963$1214A$event.L:1#send(com.enonic.app.crawler:/lib/xp/event.js:52)
    at jdk.nashorn.internal.scripts.Script$Recompilation$13957$1366$processQueue.L:1#L:1-5#l(com.enonic.app.crawler:/lib/appCrawler/processQueue.js:1)
    at jdk.nashorn.internal.scripts.Script$Recompilation$13850$1311AAA$main.L:1#L:1-6(com.enonic.app.crawler:/main.js:1)
    at jdk.nashorn.internal.scripts.Script$Recompilation$13849$139I$main.L:1#L:1-1#t(com.enonic.app.crawler:/main.js:1)
    at jdk.nashorn.internal.scripts.Script$Recompilation$13848$116A$main.:scopeCall(com.enonic.app.crawler:/main.js)
    at jdk.nashorn.internal.scripts.Script$Recompilation$13848$116A$main.L:1#L:1-1(com.enonic.app.crawler:/main.js:1)
    at jdk.nashorn.internal.scripts.Script$Recompilation$13847$54AAAAAA$main.L:1(com.enonic.app.crawler:/main.js:1)
    at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:649)
    at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
    at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
    at jdk.nashorn.api.scripting.ScriptObjectMirror.call(ScriptObjectMirror.java:117)
    at com.enonic.xp.script.impl.executor.ScriptExecutorImpl.executeRequire(ScriptExecutorImpl.java:218)
    ... 16 common frames omitted
rymsha commented 4 years ago

This one happens when old app instance is in stopped state but still tries to use its BundleContext to call OSGi services. __dispose must be used to avoid error __dispose() {stopped = true;} and check stopped before calling lib methods. Or just ignore this exception because it is harmless - it just says that old instance can't do anything anymore.

I will keep this issue open for now because exception message may be improved.

rymsha commented 4 years ago

while(true) will never finish and must not be used anywhere.

8114 prevents event listeners from being executed on stopped application, so magic with __dispose is no longer necessary for listeners starting from 7.3.

There is still a chance to see "Invalid BundleContext" because execution of event listeners happens concurrently with potential application stop/uninstall.

ComLock commented 4 years ago

while(true) was a pseudocode example. I guess while(shouldHUP)is more explanatory.

rymsha commented 4 years ago

I have updated documentation for https://developer.enonic.com/docs/xp/stable/framework/app-controller Basically anything that can potentially block execution of main.js should be avoided. Before 7.3 it would stall entire XP instance event flow. 7.3 relaxed it to application's event flow.