JavaFX 和 Lucene

JavaFX and Lucene

我正在创建一个搜索引擎类型的项目,我必须在 JavaFX 中创建一个 UI 并使用 Apache Lucene 进行查询。我正处于 JavaFX 中的 UI 独立运行的阶段(无需调用任何 Lucene 方法),并且 Lucene 的查询也可以独立运行(在单独的 java 项目中)。当我尝试通过创建一个 Lucene 对象将两者结合到我按下 ENTER 按钮时执行的操作中时,它会严重崩溃并且异常不会混淆。

我正在为我的 Window 和我的 LuceneTester classes 和抛出的异常提供代码。

主要class:

public class Main extends Application {
    
    @Override
    public void start(Stage primaryStage) {
        new Window(primaryStage);
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}

Window class

public class Window{

    public Window(Stage primaryStage) {
        VBox root = new VBox();
        root.getChildren().addAll(setSearch(), setBody());
        
        Scene scene = new Scene(root);
        primaryStage.setTitle("The Reuters Search Assistant");
        primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("icon.png")));
        primaryStage.requestFocus();
        primaryStage.setMinWidth(1280);
        primaryStage.setMinHeight(720);
        primaryStage.setResizable(false);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    
    private VBox setSearch() {
        Label search = new Label("Search");
        search.setFont(new Font("arial", 30));
        search.setPadding(new Insets(5.0, 5.0, 5.0, 5.0));
        search.setAlignment(Pos.CENTER_LEFT);
        search.setTextAlignment(TextAlignment.LEFT);
        
        TextField searchBar = new TextField();
        searchBar.setFont(new Font("arial", 14));
        searchBar.setPromptText("type here");
        searchBar.setAlignment(Pos.CENTER_LEFT);
        searchBar.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.ENTER) {
                searchAction(searchBar.getText());
            }
        });
        
        Separator separator = new Separator();
        separator.setOrientation(Orientation.HORIZONTAL);
        separator.setPadding(new Insets(5.0, 0, 0, 0));
        
        VBox searchPanel = new VBox();
        searchPanel.setAlignment(Pos.TOP_LEFT);
        searchPanel.setPadding(new Insets(5.0, 5.0, 0 ,5.0));
        searchPanel.setSpacing(5.0);
        searchPanel.fillWidthProperty();
        searchPanel.getChildren().addAll(search, searchBar, separator);
        return searchPanel;
    }
    
    private HBox setBody() {
        Button addBtn = new Button("Add Article");
        addBtn.setFont(new Font("arial", 20));
        addBtn.setMinWidth(170);
        addBtn.setOnMouseClicked(e -> {
            addArticleAction();
        });
        
        Button editBtn = new Button("Edit Article");
        editBtn.setFont(new Font("arial", 20));
        editBtn.setMinWidth(170);
        editBtn.setOnMouseClicked(e -> {
            editArticleAction();
        });
        
        Button delBtn = new Button("Delete Article");
        delBtn.setFont(new Font("arial", 20));
        delBtn.setMinWidth(170);
        delBtn.setOnMouseClicked(e -> {
            delArticleAction();
        });
        
        VBox buttonsBox = new VBox();
        buttonsBox.setAlignment(Pos.TOP_CENTER);
        buttonsBox.setMinWidth(200);
        buttonsBox.setPadding(new Insets(15.0, 5.0, 5.0, 5.0));
        buttonsBox.setSpacing(20.0);
        buttonsBox.getChildren().addAll(addBtn, editBtn, delBtn);
        
        Separator separator = new Separator();
        separator.setOrientation(Orientation.VERTICAL);
        
        ListView listView = new ListView();
        listView.setMinWidth(1050);
        listView.setMinHeight(574);
        
        VBox listViewBox = new VBox();
        listViewBox.setPadding(new Insets(5.0, 0, 0, 1.0));
        listViewBox.getChildren().add(listView);
        
        HBox bodyPanel = new HBox();
        bodyPanel.getChildren().addAll(buttonsBox, separator, listViewBox);
        return bodyPanel;
    }
    
    private void searchAction(String searchString) {
        System.out.println("Searching for : " + searchString);
        // Here is where the exception occurs.
        LuceneTester search = new LuceneTester(searchString);
    }
    
    private void addArticleAction() {
        System.out.println("add article");
    }
    
    private void editArticleAction() {
        System.out.println("edit article");
    }
    
    private void delArticleAction() {
        System.out.println("delete article");
    }
}

LuceneTester class

public class LuceneTester {
    
    String indexDir = "C:\Users\stefa\eclipse-workspace\TReSA\index";
    String dataDir = "C:\Users\stefa\eclipse-workspace\TReSA\data";
    Indexer indexer;
    Searcher searcher;
    
    public LuceneTester(String searchString) {
        try {
            this.createIndex();
            this.search(searchString);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
    
    private void createIndex() throws IOException {
        indexer = new Indexer(indexDir);
        int numIndexed;
        long startTime = System.currentTimeMillis();
        numIndexed = indexer.createIndex(dataDir, new TextFileFilter());
        long endTime = System.currentTimeMillis();
        indexer.close();
        System.out.println(numIndexed + " File(s) indexed, time taken: " + (endTime-startTime) + " ms");
    }
    
    private void search(String searchQuery) throws IOException, ParseException {
        searcher = new Searcher(indexDir);
        long startTime = System.currentTimeMillis();
        TopDocs hits = searcher.search(searchQuery);
        long endTime = System.currentTimeMillis();
        System.out.println(hits.totalHits +" found. Time : " + (endTime - startTime) + " ms");
        for(ScoreDoc scoreDoc : hits.scoreDocs) {
            Document doc = searcher.getDocument(scoreDoc);
            System.out.println("File: " + doc.get(LuceneConstants.FILE_PATH));
        }
    }
}

异常

Exception in thread "JavaFX Application Thread" java.lang.NoClassDefFoundError: org/apache/lucene/queryparser/classic/ParseException
    at com.TReSA.main.Window.searchAction(Window.java:116)
    at com.TReSA.main.Window.lambda[=13=](Window.java:52)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Scene$KeyHandler.process(Scene.java:4105)
    at javafx.graphics/javafx.scene.Scene.processKeyEvent(Scene.java:2156)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2630)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:218)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:150)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent(GlassViewEventHandler.java:250)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:249)
    at javafx.graphics/com.sun.glass.ui.View.handleKeyEvent(View.java:548)
    at javafx.graphics/com.sun.glass.ui.View.notifyKey(View.java:972)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop(WinApplication.java:184)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.ClassNotFoundException: org.apache.lucene.queryparser.classic.ParseException
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    ... 29 more

提前致谢。

ClassNotFoundException: org.apache.lucene.queryparser.classic.ParseException 表示缺少 Lucene 的依赖项,因此您应该检查您的构建工具设置。

但这也意味着发生了异常,因此您可能需要仔细检查 Lucene only 代码是否真的有效。