stanfordnlp/CoreNLP · critical · RuntimeException
can't open file
Error message
can't open file: ${e.getMessage()} What it means
The private CtbDict constructor loads the Chinese Treebank dictionary file from a hardcoded path on the NLP group's machines (/u/nlp/data/pos-tagger/dictionary). If that file cannot be read, the IOException is wrapped in a RuntimeException with the underlying message. This means the Chinese dictionary feature is unavailable in your environment.
Solutions
- Create the directory /u/nlp/data/pos-tagger/dictionary and place the CTB dictionary file (defaultFilename) there, or symlink it to where your data lives
- Retrain/run the tagger without Chinese dictionary features (do not enable dictionary-based extractors) so CtbDict is never instantiated
- Patch readCtbDict to load the dictionary from a configurable path or classpath resource instead of the hardcoded absolute path
- Check file permissions on the dictionary file so the JVM user can read it
Example fix
// before: hardcoded path fails
private CtbDict() {
try {
readCtbDict("/u/nlp/data/pos-tagger/dictionary" + '/' + defaultFilename);
} catch(IOException e) {
throw new RuntimeException("can't open file: " + e.getMessage());
}
}
// after: configurable path with classpath fallback
private CtbDict() {
String dir = System.getProperty("ctbDictPath", "/u/nlp/data/pos-tagger/dictionary");
try {
readCtbDict(dir + '/' + defaultFilename);
} catch(IOException e) {
throw new RuntimeException("can't open file: " + dir + '/' + defaultFilename, e);
}
} Defensive patterns
Strategy: validation
Validate before calling
File dict = new File("/u/nlp/data/pos-tagger/dictionary/ChineseDictionary.txt");
if (!dict.canRead()) {
throw new IllegalStateException("CTB dictionary missing/unreadable: " + dict);
} Try / catch
try {
CtbDict.getInstance();
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("can't open file:")) {
// disable Chinese dictionary features or supply the dictionary
} else { throw e; }
} Prevention
- Provision the hardcoded /u/nlp dictionary path (or symlink) before enabling Chinese dictionary features
- Only enable Chinese dictionary extractors when you know the data files exist
- Check file readability of the dictionary under the JVM's user account
- Prefer a patched build that loads dictionaries from a configurable location
When it happens
Trigger: Instantiating the singleton CtbDict (via CtbDict.getInstance()) when readCtbDict() fails to open the hardcoded dictionary path, e.g. the file does not exist or is unreadable on a machine outside the Stanford NLP network.
Common situations: Running the POS tagger with Chinese dictionary features on a server/cluster that lacks /u/nlp/data; a Stanford-internal path that external users never have; permission problems on the data directory.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Couldn't load classifier from
- File not found. Filename = " + filename
- Could not find inside
- Couldn't read function word file
- File not found:
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/ba623eeff61d8d42.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/tagger/maxent/CtbDict.java:30
public class CtbDict {
private static final String defaultFilename = "ctb_dict.txt";
private static CtbDict ctbDictSingleton;
private static synchronized CtbDict getInstance() {
if (ctbDictSingleton == null) {
ctbDictSingleton = new CtbDict();
}
return ctbDictSingleton;
}
private CtbDict() {
try {
readCtbDict("/u/nlp/data/pos-tagger/dictionary" + '/' + defaultFilename);
} catch(IOException e) {
throw new RuntimeException("can't open file: " + e.getMessage());
/* java sucks */
}
}
public Map <String, Set <String>> ctb_pre_dict;
public Map <String, Set <String>> ctb_suf_dict;
private void readCtbDict(String filename) throws IOException {
BufferedReader ctbDetectorReader = new BufferedReader(new InputStreamReader(new FileInputStream(filename), "GB18030"));
String ctbDetectorLine;
ctb_pre_dict = Generics.newHashMap();
ctb_suf_dict = Generics.newHashMap();
while ((ctbDetectorLine = ctbDetectorReader.readLine()) != null) {
String[] fields = ctbDetectorLine.split(" ");View on GitHub (pinned to 1b7edd19c4)