我的Java EE应用程序使用crawler4j,它使用以下代码开始抓取:
CrawlConfig config = new CrawlConfig();
config.setCrawlStorageFolder("C:/crawler4j_storage");
PageFetcher pageFetcher = new PageFetcher(config);
RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);
CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer);
controller.start(Crawler.class, 1);
EJB是在Crawler.class中注入的:
@Stateless
@LocalBean
public class Crawler extends WebCrawler {
@Inject private SeedFacadeLocal seedEJB;
public void doSomething () {
seedEJB.findAll(); // gives the NullPointerException
}
我的猜测是它与Crawler.class作为参数传递的方式有关。 SeedFacadeLocal是一个@Local bean接口,它有一个@Stateless bean实现。我在很多其他地方注入了这个bean,它运行正常。
我认为通过使用“controller.start(Crawler.class,1)”开始爬网会导致Crawler.class成为POJO而不是EJB。因此忽略Crawler.class中的注释。
答案 0 :(得分:1)
CrawlController
使用简单的newInstance
调用创建抓取工具的实例:
这不会进行任何类型的注入,因此您的爬虫注入的字段将为空。
如果您想使用注入的抓取工具,则需要控制CrawlController
创建抓取工具的方式。但是,没有明显的方法可以做到这一点;从这个角度来看,它的设计相当糟糕。
您可能需要做的是从爬虫类中分离出您的域逻辑(您在EJB中编写的内容),并编写一个简单的newInstance-able爬虫类,在适当的时候调用EJB。 EJB本身不是一个爬虫。您可以使用JNDI获取对EJB的引用。