{"record":{"id":"0e08cb2ef19320ce","repo":"flowable/flowable-engine","slug":"invalid-scriptenginefactory","errorCode":null,"errorMessage":"Invalid ScriptEngineFactory: ","messagePattern":"Invalid ScriptEngineFactory: ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"modules/flowable-osgi/src/main/java/org/flowable/osgi/Extender.java","lineNumber":381,"sourceCode":"            if (reg != null) {\n                reg.unregister();\n            }\n        }\n\n        @SuppressWarnings({\"rawtypes\"})\n        @Override\n        public ScriptEngine resolveScriptEngine(String name) {\n            try {\n                String className;\n                try (InputStream input = configFile.openStream()) {\n                    className = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)).lines()\n                            .map(line -> line.split(\"#\", 2)[0].trim())\n                            .filter(Predicate.not(String::isBlank))\n                            .findFirst().orElse(null);\n                }\n                Class<?> cls = bundle.loadClass(className);\n                if (!ScriptEngineFactory.class.isAssignableFrom(cls)) {\n                    throw new IllegalStateException(\"Invalid ScriptEngineFactory: \" + cls.getName());\n                }\n                ScriptEngineFactory factory = (ScriptEngineFactory) cls.getConstructor().newInstance();\n                List<String> names = factory.getNames();\n                for (String test : names) {\n                    if (test.equals(name)) {\n                        ClassLoader old = Thread.currentThread().getContextClassLoader();\n                        ScriptEngine engine;\n                        try {\n                            // JRuby seems to require the correct TCCL to call\n                            // getScriptEngine\n                            Thread.currentThread().setContextClassLoader(factory.getClass().getClassLoader());\n                            engine = factory.getScriptEngine();\n                        } finally {\n                            Thread.currentThread().setContextClassLoader(old);\n                        }\n                        LOGGER.trace(\"Resolved ScriptEngineFactory: {} for expected name: {}\", engine, name);\n                        return engine;\n                    }","sourceCodeStart":363,"sourceCodeEnd":399,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-osgi/src/main/java/org/flowable/osgi/Extender.java#L363-L399","documentation":"Extender.resolveScriptEngine loads the class named in a script engine factory descriptor inside an OSGi bundle and validates that it implements javax.script.ScriptEngineFactory. If the loaded class does not implement that interface, it throws IllegalStateException('Invalid ScriptEngineFactory: <class name>'). This protects the subsequent cast and instantiation from a ClassCastException.","triggerScenarios":"A bundle's script-engine registration file (e.g. META-INF/services or the OSGi launcher config) lists a className that resolves via bundle.loadClass to a class that is not a ScriptEngineFactory, during resolveScriptEngine (called from resolvedEngine).","commonSituations":"Typo'd or wrong class name in the engine factory descriptor; a class was renamed/refactored across Flowable or script engine versions; wrong bundle's classloader resolving an unrelated class with the same name.","solutions":["Correct the factory class name in the script engine descriptor to a class implementing ScriptEngineFactory","Verify the bundle exporting the script engine factory is deployed and its class is public with a no-arg constructor","Check for version mismatches between the script engine library and the descriptor file","Rebuild/redeploy the bundle if the class was recently renamed"],"exampleFix":"// before (descriptor content)\ncom.example.MyEngineImpl   // does not implement ScriptEngineFactory\n// after\ncom.example.MyEngineFactory // implements javax.script.ScriptEngineFactory","handlingStrategy":"validation","validationCode":"Class<?> cls = bundle.loadClass(factoryClassName);\nif (!javax.script.ScriptEngineFactory.class.isAssignableFrom(cls)) {\n    throw new IllegalArgumentException(factoryClassName + \" does not implement ScriptEngineFactory\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    ScriptEngine engine = scriptEngine.getEngineByName(language);\n} catch (FlowableException e) {\n    if (e.getMessage().startsWith(\"problem resolving scripting engine\")) {\n        logger.error(\"Script engine resolution failed for {}: {}\", language, e.getCause().getMessage());\n    }\n    throw e;\n}","preventionTips":["Keep engine factory descriptor files in sync with actual class names after refactors","Test each registered script engine factory instantiates at bundle start","Pin script engine library versions and regenerate descriptors on upgrades"],"tags":["osgi","scripting","classloading"],"backgroundTag":"invalid-argument-value","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}