I just submitted a PR that adds a core feature for a JythonScriptEngineFactory and it would be great to have some testers! Basically, this will allow for the installation of Jython including the core and community helper libraries through Paper UI, once the PR is merged. If you’d like to test it, you’ll need to…
Have OH 2.5.x (S1778) or newer
Shutdown OH
Backup OH
Download the addon and copy to $OPENHAB_HOME/addons/ (see here for more details). The jar contains the core and community helper libraries, so there’s no need to copy them from the repo. However, the core scripts will need to be copied to /automation/jsr223/python/core/.
Restart OH and watch the logs
These instructions are very short and assume you are familiar with how to manually setup Jython and the HLs. Include step 7, but understand that the core libraries (/automation/lib/python/core) are included in theis bundle, so the ones you copy will be ignored. You will still need to setup the configuration.py. I’ll update the HL docs when the PR is approved. Steps 10 and 11 should be skipped. I’ll come back to answer questions and fill in some gaps!
If you already have Jython setup, stop OH, remove the Jython portion of your EXTRA_JAVA_OPTS, copy the jbeta Jython addon to /addons/, and start OH. The existing core and community libraries on your filesystem will be ignored.
To use external libraries, copy them into your $OPENHAB_CONF/automation/lib/python/personal/ directory. Alternatively, add the directories (separated with a colon for Linux and semicolon for Windows) containing the packages to the python.path in your EXTRA_JAVA_OPTS.
Thank you, @sihui… I really appreciate your testing this! The more positive responses I get, the sooner the PR may get merged. Just shout if you need any help!
With any luck, @kai will let this one slide in to 2.5!
Oops, as soon as the docker is stopped, the files disappeared from /var/lib/docker. I’m still trying to figure out where exactly it’s stored with docker
It sounds like you are looking in the wrong place. Just took a look and the directory structure is /openhab/runtime/. So, shell into your OH docker container and copy the core file to
14:33:22.488 [WARN ] [org.apache.felix.fileinstall ] - Error while starting bundle: file:/openhab/addons/org.openhab.core.automation.module.script.scriptenginefactory.jython-2.5.0-SNAPSHOT.jar
org.osgi.framework.BundleException: Could not resolve module: org.openhab.core.automation.module.script.scriptenginefactory.jython [204]
Unresolved requirement: Import-Package: org.openhab.core.automation.module.script; version="[2.5.0,3.0.0)"
at org.eclipse.osgi.container.Module.start(Module.java:444) ~[org.eclipse.osgi-3.12.100.jar:?]
at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:383) ~[org.eclipse.osgi-3.12.100.jar:?]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundle(DirectoryWatcher.java:1260) [bundleFile:3.6.4]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundles(DirectoryWatcher.java:1233) [bundleFile:3.6.4]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.startAllBundles(DirectoryWatcher.java:1221) [bundleFile:3.6.4]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.doProcess(DirectoryWatcher.java:515) [bundleFile:3.6.4]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:365) [bundleFile:3.6.4]
at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:316) [bundleFile:3.6.4]
The files are there, and I restarted openhab.
root@server:/openhab/runtime/system/org/openhab/core/bundles/org.openhab.core.automation.module.script/2.5.0.M5# ls -l
total 96
-rw-r--r-- 1 openhab openhab 45135 Dec 2 14:23 org.openhab.core.automation.module.script-2.5.0-SNAPSHOT.jar
-rw-r--r-- 1 openhab openhab 45135 Dec 2 14:23 org.openhab.core.automation.module.script-2.5.0.M5.jar.org
root@server:/openhab/addons# ls -l
total 40568
-rw-r--r-- 1 openhab openhab 41537918 Dec 2 14:27 org.openhab.core.automation.module.script.scriptenginefactory.jython-2.5.0-SNAPSHOT.jar
You cleared the cache, so the dependencies need to be resolved. This is normal. Follow the other setup instructions and it should start up and there will be additional logging (including the hello world). These files just eliminate the need to download the Jython jar, copy it in, setup the EXTRA_JAVA_OPTS, and setup the helper libraries. There is still setup needed.
I copied the two jar files, restarted openhab, installed NGRE addon via paperui, restarted openhab again. However there’s no OPENHAB_CONF/automation directory being created. Am I supposed to create it manually?
15:19:13.340 [INFO ] [port.shared.ScriptedAutomationManager] - removeAll added handlers
15:19:13.343 [INFO ] [ome.core.service.AbstractWatchService] - Loading script 'python/personal/hello_world.py'
15:19:14.177 [DEBUG] [ript.internal.ScriptEngineManagerImpl] - Added ScriptEngine for language 'py' with identifier: file:/openhab/conf/automation/jsr223/python/personal/hello_world.py
15:19:15.213 [ERROR] [org.openhab.core.ephemeris ] - bundle org.openhab.core.ephemeris:2.5.0.M5 (144)[org.openhab.ephemeris(69)] : The activate method has thrown an exception
java.lang.IllegalArgumentException: No enum constant java.time.DayOfWeek.SATURDAY,SUNDAY
at java.lang.Enum.valueOf(Enum.java:238) ~[?:1.8.0_222]
at java.time.DayOfWeek.valueOf(DayOfWeek.java:109) ~[?:1.8.0_222]
at org.eclipse.smarthome.core.ephemeris.internal.EphemerisManagerImpl.addDayset(EphemerisManagerImpl.java:330) ~[?:?]
at org.eclipse.smarthome.core.ephemeris.internal.EphemerisManagerImpl.lambda$2(EphemerisManagerImpl.java:151) ~[?:?]
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) ~[?:1.8.0_222]
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) ~[?:1.8.0_222]
at java.util.Iterator.forEachRemaining(Iterator.java:116) ~[?:1.8.0_222]
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) ~[?:1.8.0_222]
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) ~[?:1.8.0_222]
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) ~[?:1.8.0_222]
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) ~[?:1.8.0_222]
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) ~[?:1.8.0_222]
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:1.8.0_222]
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:485) ~[?:1.8.0_222]
at org.eclipse.smarthome.core.ephemeris.internal.EphemerisManagerImpl.modified(EphemerisManagerImpl.java:131) ~[?:?]
at org.eclipse.smarthome.core.ephemeris.internal.EphemerisManagerImpl.activate(EphemerisManagerImpl.java:126) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_222]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_222]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_222]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_222]
at org.apache.felix.scr.impl.inject.methods.BaseMethod.invokeMethod(BaseMethod.java:228) ~[?:?]
at org.apache.felix.scr.impl.inject.methods.BaseMethod.access$500(BaseMethod.java:41) ~[?:?]
at org.apache.felix.scr.impl.inject.methods.BaseMethod$Resolved.invoke(BaseMethod.java:664) ~[?:?]
at org.apache.felix.scr.impl.inject.methods.BaseMethod.invoke(BaseMethod.java:510) ~[?:?]
at org.apache.felix.scr.impl.inject.methods.ActivateMethod.invoke(ActivateMethod.java:317) ~[?:?]
at org.apache.felix.scr.impl.inject.methods.ActivateMethod.invoke(ActivateMethod.java:307) ~[?:?]
at org.apache.felix.scr.impl.manager.SingleComponentManager.createImplementationObject(SingleComponentManager.java:340) ~[?:?]
at org.apache.felix.scr.impl.manager.SingleComponentManager.createComponent(SingleComponentManager.java:114) ~[?:?]
at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:982) ~[?:?]
at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:955) ~[?:?]
at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:900) ~[?:?]
at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse$1.run(ServiceFactoryUse.java:212) ~[org.eclipse.osgi-3.12.100.jar:?]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_222]
at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse.factoryGetService(ServiceFactoryUse.java:210) ~[org.eclipse.osgi-3.12.100.jar:?]
at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse.getService(ServiceFactoryUse.java:111) ~[org.eclipse.osgi-3.12.100.jar:?]
at org.eclipse.osgi.internal.serviceregistry.ServiceConsumer$2.getService(ServiceConsumer.java:45) ~[org.eclipse.osgi-3.12.100.jar:?]
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.getService(ServiceRegistrationImpl.java:508) ~[org.eclipse.osgi-3.12.100.jar:?]
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.getService(ServiceRegistry.java:461) ~[org.eclipse.osgi-3.12.100.jar:?]
at org.eclipse.osgi.internal.framework.BundleContextImpl.getService(BundleContextImpl.java:624) ~[org.eclipse.osgi-3.12.100.jar:?]
at org.apache.felix.scr.impl.manager.SingleRefPair.getServiceObject(SingleRefPair.java:86) ~[?:?]
at org.apache.felix.scr.impl.inject.BindParameters.getServiceObject(BindParameters.java:47) ~[?:?]
at org.apache.felix.scr.impl.inject.methods.BindMethod.getServiceObject(BindMethod.java:664) ~[?:?]
at org.apache.felix.scr.impl.manager.DependencyManager.getServiceObject(DependencyManager.java:2308) ~[?:?]
at org.apache.felix.scr.impl.manager.DependencyManager$SingleStaticCustomizer.prebind(DependencyManager.java:1154) ~[?:?]
at org.apache.felix.scr.impl.manager.DependencyManager.prebind(DependencyManager.java:1568) ~[?:?]
at org.apache.felix.scr.impl.manager.AbstractComponentManager.collectDependencies(AbstractComponentManager.java:1029) ~[?:?]
at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:935) ~[?:?]
at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:900) ~[?:?]
at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse$1.run(ServiceFactoryUse.java:212) ~[org.eclipse.osgi-3.12.100.jar:?]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_222]
at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse.factoryGetService(ServiceFactoryUse.java:210) ~[org.eclipse.osgi-3.12.100.jar:?]
at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse.getService(ServiceFactoryUse.java:111) ~[org.eclipse.osgi-3.12.100.jar:?]
at org.eclipse.osgi.internal.serviceregistry.ServiceConsumer$2.getService(ServiceConsumer.java:45) ~[org.eclipse.osgi-3.12.100.jar:?]
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.getService(ServiceRegistrationImpl.java:508) ~[org.eclipse.osgi-3.12.100.jar:?]
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.getService(ServiceRegistry.java:461) ~[org.eclipse.osgi-3.12.100.jar:?]
at org.eclipse.osgi.internal.framework.BundleContextImpl.getService(BundleContextImpl.java:624) ~[org.eclipse.osgi-3.12.100.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_222]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_222]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_222]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_222]
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:188) ~[?:?]
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:206) ~[?:?]
at org.python.core.PyObject.__call__(PyObject.java:497) ~[?:?]
at org.python.core.PyObject.__call__(PyObject.java:501) ~[?:?]
at org.python.core.PyMethod.__call__(PyMethod.java:141) ~[?:?]
at core.osgi$py.find_services$2(/openhab/conf/automation/lib/python/core/osgi/__init__.py:55) ~[?:?]
at core.osgi$py.call_function(/openhab/conf/automation/lib/python/core/osgi/__init__.py) ~[?:?]
at org.python.core.PyTableCode.call(PyTableCode.java:171) ~[?:?]
at org.python.core.PyBaseCode.call(PyBaseCode.java:154) ~[?:?]
at org.python.core.PyFunction.__call__(PyFunction.java:423) ~[?:?]
at core.actions$py.f$0(/openhab/conf/automation/lib/python/core/actions.py:46) ~[?:?]
at core.actions$py.call_function(/openhab/conf/automation/lib/python/core/actions.py) ~[?:?]
at org.python.core.PyTableCode.call(PyTableCode.java:171) ~[?:?]
at org.python.core.PyCode.call(PyCode.java:18) ~[?:?]
at org.python.core.imp.createFromCode(imp.java:436) ~[?:?]
at org.python.core.imp.createFromPyClass(imp.java:237) ~[?:?]
at org.python.core.imp.createFromPyClass(imp.java:205) ~[?:?]
at org.python.core.imp.loadFromSource(imp.java:657) ~[?:?]
at org.python.core.imp.find_module(imp.java:551) ~[?:?]
at org.python.core.PyModule.impAttr(PyModule.java:111) ~[?:?]
at org.python.core.imp.import_next(imp.java:840) ~[?:?]
at org.python.core.imp.import_logic(imp.java:905) ~[?:?]
at org.python.core.imp.import_module_level(imp.java:970) ~[?:?]
at org.python.core.imp.importName(imp.java:1057) ~[?:?]
at org.python.core.ImportFunction.__call__(__builtin__.java:1280) ~[?:?]
at org.python.core.PyObject.__call__(PyObject.java:450) ~[?:?]
at org.python.core.__builtin__.__import__(__builtin__.java:1232) ~[?:?]
at org.python.core.imp.importFromAs(imp.java:1149) ~[?:?]
at org.python.core.imp.importFrom(imp.java:1124) ~[?:?]
at core.utils$py.f$0(/openhab/conf/automation/lib/python/core/utils.py:263) ~[?:?]
at core.utils$py.call_function(/openhab/conf/automation/lib/python/core/utils.py) ~[?:?]
at org.python.core.PyTableCode.call(PyTableCode.java:171) ~[?:?]
at org.python.core.PyCode.call(PyCode.java:18) ~[?:?]
at org.python.core.imp.createFromCode(imp.java:436) ~[?:?]
at org.python.core.imp.createFromPyClass(imp.java:237) ~[?:?]
at org.python.core.imp.createFromPyClass(imp.java:205) ~[?:?]
at org.python.core.imp.loadFromSource(imp.java:657) ~[?:?]
at org.python.core.imp.find_module(imp.java:551) ~[?:?]
at org.python.core.PyModule.impAttr(PyModule.java:111) ~[?:?]
at org.python.core.imp.import_next(imp.java:840) ~[?:?]
at org.python.core.imp.import_logic(imp.java:905) ~[?:?]
at org.python.core.imp.import_module_level(imp.java:970) ~[?:?]
at org.python.core.imp.importName(imp.java:1057) ~[?:?]
at org.python.core.ImportFunction.__call__(__builtin__.java:1280) ~[?:?]
at org.python.core.PyObject.__call__(PyObject.java:450) ~[?:?]
at org.python.core.__builtin__.__import__(__builtin__.java:1232) ~[?:?]
at org.python.core.imp.importFromAs(imp.java:1149) ~[?:?]
at org.python.core.imp.importFrom(imp.java:1124) ~[?:?]
at core.triggers$py.f$0(/openhab/conf/automation/lib/python/core/triggers.py:744) ~[?:?]
at core.triggers$py.call_function(/openhab/conf/automation/lib/python/core/triggers.py) ~[?:?]
at org.python.core.PyTableCode.call(PyTableCode.java:171) ~[?:?]
at org.python.core.PyCode.call(PyCode.java:18) ~[?:?]
at org.python.core.imp.createFromCode(imp.java:436) ~[?:?]
at org.python.core.imp.createFromPyClass(imp.java:237) ~[?:?]
at org.python.core.imp.createFromPyClass(imp.java:205) ~[?:?]
at org.python.core.imp.loadFromSource(imp.java:657) ~[?:?]
at org.python.core.imp.find_module(imp.java:551) ~[?:?]
at org.python.core.PyModule.impAttr(PyModule.java:111) ~[?:?]
at org.python.core.imp.import_next(imp.java:840) ~[?:?]
at org.python.core.imp.import_logic(imp.java:905) ~[?:?]
at org.python.core.imp.import_module_level(imp.java:970) ~[?:?]
at org.python.core.imp.importName(imp.java:1057) ~[?:?]
at org.python.core.ImportFunction.__call__(__builtin__.java:1280) ~[?:?]
at org.python.core.PyObject.__call__(PyObject.java:450) ~[?:?]
at org.python.core.__builtin__.__import__(__builtin__.java:1232) ~[?:?]
at org.python.core.imp.importFromAs(imp.java:1149) ~[?:?]
at org.python.core.imp.importFrom(imp.java:1124) ~[?:?]
at org.python.pycode._pyx24.f$0(<script>:8) ~[?:?]
at org.python.pycode._pyx24.call_function(<script>) ~[?:?]
at org.python.core.PyTableCode.call(PyTableCode.java:171) ~[?:?]
at org.python.core.PyCode.call(PyCode.java:18) ~[?:?]
at org.python.core.Py.runCode(Py.java:1614) ~[?:?]
at org.python.core.__builtin__.eval(__builtin__.java:497) ~[?:?]
at org.python.core.__builtin__.eval(__builtin__.java:501) ~[?:?]
at org.python.util.PythonInterpreter.eval(PythonInterpreter.java:259) ~[?:?]
at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:57) ~[?:?]
at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:64) ~[?:?]
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:249) ~[?:1.8.0_222]
at org.openhab.core.automation.module.script.internal.ScriptEngineManagerImpl.loadScript(ScriptEngineManagerImpl.java:155) ~[?:?]
at org.openhab.core.automation.module.script.rulesupport.internal.loader.ScriptFileWatcher.importFile(ScriptFileWatcher.java:176) ~[?:?]
at org.openhab.core.automation.module.script.rulesupport.internal.loader.ScriptFileWatcher.processWatchEvent(ScriptFileWatcher.java:143) ~[?:?]
at org.eclipse.smarthome.core.service.WatchQueueReader.lambda$3(WatchQueueReader.java:323) ~[?:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_222]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_222]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_222]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [?:1.8.0_222]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_222]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_222]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_222]
15:19:15.241 [ERROR] [ript.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/openhab/conf/automation/jsr223/python/personal/hello_world.py': AttributeError: 'NoneType' object has no attribute 'actionClass' in <script> at line number 6