{"record":{"id":"562182d6288dcb05","repo":"code4craft/webmagic","slug":"java-io-ioexception","errorCode":null,"errorMessage":"java.io.IOException","messagePattern":"java\\.io\\.IOException","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"webmagic-scripts/src/main/java/us/codecraft/webmagic/scripts/ScriptProcessor.java","lineNumber":42,"sourceCode":"    private String defines;\n\n    private String script;\n\n    private final Language language;\n\n    private Site site = Site.me();\n\n    public ScriptProcessor(Language language, String script, int threadNum) {\n        if (language == null || script == null) {\n            throw new IllegalArgumentException(\"language and script must not be null!\");\n        }\n        this.language = language;\n        enginePool = new ScriptEnginePool(language, threadNum);\n        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(language.getDefineFile());\n        try {\n            defines = IOUtils.toString(resourceAsStream, Charset.defaultCharset());\n        } catch (IOException e) {\n            throw new IllegalArgumentException(e);\n        }\n        this.script = script;\n    }\n\n    @Override\n    public void process(Page page) {\n        ScriptEngine engine = enginePool.getEngine();\n        try {\n            ScriptContext context = engine.getContext();\n            context.setAttribute(\"page\", page, ScriptContext.ENGINE_SCOPE);\n            context.setAttribute(\"config\", site, ScriptContext.ENGINE_SCOPE);\n            try {\n                this.language.process(engine, defines, script, page);\n            } catch (ScriptException e) {\n                e.printStackTrace();\n            }\n        } finally {\n            enginePool.release(engine);","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/code4craft/webmagic/blob/67816a19d68a4fec4657bf1336227e046e251df2/webmagic-scripts/src/main/java/us/codecraft/webmagic/scripts/ScriptProcessor.java#L24-L60","documentation":"During ScriptProcessor construction, the language's define file (language.getDefineFile()) is read from the classpath into a String with IOUtils.toString. If reading the stream throws IOException (stream closed/unreadable — and notably if getResourceAsStream returned null, NPE aside, or an I/O fault occurs), it is rethrown as IllegalArgumentException whose message is just \"java.io.IOException: ...\".","triggerScenarios":"new ScriptProcessor(language, script, threadNum) where the language's define file resource is missing from the classpath, unreadable, or the stream fails mid-read — e.g. a custom Language whose getDefineFile() points to a resource not on the classpath.","commonSituations":"Using a custom Language implementation without packaging its define file into the jar; fat-jar shading dropping resource files; classloader isolation (app-server/OSGi) hiding the resource; truncated/corrupt jar.","solutions":["Verify language.getDefineFile() exists on the runtime classpath (e.g. check ScriptProcessor.class.getClassLoader().getResource(defineFile) != null before constructing).","If using a custom Language, bundle its define file in src/main/resources and rebuild the jar.","Check the jar/classpath packaging (maven-shade/resources filtering) to ensure .txt/.js resource files are not filtered out.","Catch IllegalArgumentException during construction and log the cause's cause for the underlying stream problem."],"exampleFix":"// before\nInputStream in = getClass().getClassLoader().getResourceAsStream(language.getDefineFile());\nnew ScriptProcessor(language, script, 1);\n// after\nif (getClass().getClassLoader().getResource(language.getDefineFile()) == null) {\n    throw new IllegalStateException(\"Missing define file: \" + language.getDefineFile());\n}\nnew ScriptProcessor(language, script, 1);","handlingStrategy":"validation","validationCode":"String defFile = language.getDefineFile();\nif (ScriptProcessor.class.getClassLoader().getResource(defFile) == null) {\n    throw new IllegalStateException(\"Define file not on classpath: \" + defFile);\n}","typeGuard":null,"tryCatchPattern":"try {\n    processor = new ScriptProcessor(language, script, threadNum);\n} catch (IllegalArgumentException e) {\n    if (e.getCause() instanceof java.io.IOException) {\n        throw new IllegalStateException(\"Failed to read define file: \" + language.getDefineFile(), e);\n    }\n    throw e;\n}","preventionTips":["Ship each Language's define file in src/main/resources of the jar","Verify resources survive shade/fat-jar packaging (unzip the jar and check)","Check getResource(...) non-null before constructing the processor","Avoid custom Language implementations without their define resources"],"tags":["java","classpath","io","resource-loading"],"backgroundTag":"resource-not-found","analyzedSha":"67816a19d68a4fec4657bf1336227e046e251df2","analyzedAt":"2026-09-08T11:15:28.425Z","contentChangedAt":"2026-09-08T11:15:28.425Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}