【发布时间】:2014-12-02 06:49:54
【问题描述】:
我很确定这对于专家来说是非常基本的东西,但对我来说,作为一个新手,这让我很难过。
我有 3 个解析器,每个都有自己的功能,将来会有更多的解析器。现在我想做的是:我希望我的应用程序在运行时根据要出现的页面选择正确的解析器。
为了实现这一点,我做了以下事情:我有一个接口(IWebParser):
public interface IWebParser {
public abstract Object execute(String page, URL url);
public abstract List<SimpleWebPosting> parse(String page, URL url, List<String> tokens);
public abstract Boolean canExecute(URL url);
}
我的每个解析器都实现了这个接口。我有另一个名为 ParserControl 的类,其中有一个方法 submit(String page, URL url) - 这是我的程序总是调用的方法,只要有要解析的页面。此类 ParserControl 从 xml 文件中获取可用的解析器,并尝试(在 while 语句中)是否有任何解析器可以解析有问题的页面。这是通过 canExecute(URL url) 方法完成的。现在,在 canExecute 上收到 true 后,我想执行那个特定的解析器。
我的 ParserControl 类如下所示:
public class ParserControl {
private static final Logger logger = Logger.getLogger("de.comlineag.snc.parser.ParserControl");
// the list of operational web parser as taken from the properties file is stored within this structure
private static List<IWebParser> webParser;
// the ParserControl instance - used during instantiation of the class and later to retrieve the list
private static ParserControl pc = null;
// ParserControl is not to be directly instantiated by other classes
private ParserControl() {
try {
webParser = getAllParser();
} catch (XPathExpressionException | IOException
| ParserConfigurationException | SAXException e) {
logger.error("EXCEPTION :: error during parser execution " + e.getMessage());
e.printStackTrace();
}
};
// Static 'instance' method - this method is called every time
// the submit method is called but can also be called implicitely to get
// an instance of ParserControl
public static ParserControl getInstance() throws XPathExpressionException, ParserConfigurationException, SAXException, IOException {
if (pc == null) {pc = new ParserControl();}
return pc;
}
public static List<SimpleWebPosting> submit(String page, URL url, ArrayList<String> tTerms) throws XPathExpressionException, ParserConfigurationException, SAXException, IOException{
logger.trace("ParserControl called");
pc = getInstance();
while (pc.webParser.iterator().hasNext()) {
logger.trace("trying parser " + pc.webParser.iterator().getClass().getSimpleName().toString());
if (((IWebParser) pc.webParser.iterator().getClass().getClassLoader()).canExecute(url)) {
return ((IWebParser) pc.webParser.iterator().getClass().getClassLoader()).parse(page, url, tTerms);
} else {
logger.trace("parser " + pc.webParser.iterator().getClass().getSimpleName().toString() + " returned false to canExecute()" );
}
}
return null;
}
// retrieves all configured parser from the properties file and creates the parser list
@SuppressWarnings("unchecked")
private <T> ArrayList<T> getAllParser() throws IOException, ParserConfigurationException, SAXException, XPathExpressionException {
String fileName = "webapp/WEB-INF/properties/webparser.xml";
ArrayList<T> ar = new ArrayList<T>();
File file = new File(fileName);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
String expression = "//parser[@type='webparser']/value";
NodeList nodeList= (NodeList) xpath.compile(expression).evaluate(doc, XPathConstants.NODESET);
for (int i = 0 ; i < nodeList.getLength() ; i++) {
ar.add((T) nodeList.item(i).getTextContent());
logger.trace("found parser " + nodeList.item(i).getTextContent().toString() + " in configuration file " + fileName);
}
return ar;
}
}
现在,经过冗长的介绍,我的问题是:执行此操作时,我无法实例化解析器类,而是得到一个 NullPointerException。 logger.trace 在 while 循环中返回:
TRACE ParserControl - trying parser Itr <--- I would expect the class name here!!!
ERROR SimpleWebCrawler - WEBCRAWLER-Crawler Exception java.lang.NullPointerException
谁能告诉我,我在这里做错了什么???
【问题讨论】:
-
NPE 在哪一行被抛出?
-
在 if 语句的 while (pc.webParser.iterator().hasNext()) 循环内: if (((IWebParser) pc.webParser.iterator().getClass(). getClassLoader()).canExecute(url)) {
标签: java parsing dynamic reflection classloader