有用过MATSIM做交通仿真的朋友应该都知道,在创建Scenario时,会默认加载matsim官网的netword的dtd文件,然后因为网络的问题,加载往往会报错,从而造成系统异常退出,如图所示:
根据日志提示,得知“罪魁祸首”就是MatsimXmlParser.java这个类中的第215行附近的代码,我们查找源码,找到了原因:
// try to get the dtd from the web log.info("Trying to load " + systemId + ". In some cases (e.g. network interface up but no connection), this may take a bit."); try { URL url = new URL(systemId); URLConnection urlConn = url.openConnection(); urlConn.setConnectTimeout(8000); urlConn.setReadTimeout(8000); urlConn.setAllowUserInteraction(false); InputStream is = urlConn.getInputStream(); /* If there was no exception until here, than the path is valid. * Return the opened stream as a source. If we would return null, then the SAX-Parser * would have to fetch the same file again, requiring two accesses to the webserver */ return new InputSource(is); } catch (IOException e) { // There was a problem getting the (remote) file, just show the error as information for the user log.error(e.toString() + ". May not be fatal." ) ; }
虽然从代码和注释上来看,似乎加载失败并不会对程序造成致命的影响,但是从现象上来看,的确导致了程序的异常退出,并且每次运行都要加载,耗费了时间,我们可以将这段代码注释掉,并修改log日志,验证是否生效:
// try to get the dtd from the web log.info("[SKIP] Trying to load " + systemId + ". In some cases (e.g. network interface up but no connection), this may take a bit."); // try { // URL url = new URL(systemId); // URLConnection urlConn = url.openConnection(); // urlConn.setConnectTimeout(8000); // urlConn.setReadTimeout(8000); // urlConn.setAllowUserInteraction(false); // // InputStream is = urlConn.getInputStream(); // /* If there was no exception until here, than the path is valid. // * Return the opened stream as a source. If we would return null, then the SAX-Parser // * would have to fetch the same file again, requiring two accesses to the webserver */ // return new InputSource(is); // } catch (IOException e) { // // There was a problem getting the (remote) file, just show the error as information for the user // log.error(e.toString() + ". May not be fatal." ) ; // }
注意,这个修改后class应该保持和源码结构中相同的包结构,在eclipse中,工程结构如图所示:
保存后再次运行matsim的应用程序,发现不会再加载dtd文件了,而且log日志也确实显示为我们修改后的日志了: