【问题标题】:Neo4j - Lucene - maven shade plugin - Works fine through the Netbeans but doesnt work as jarNeo4j - Lucene - maven shade 插件 - 通过 Netbeans 可以正常工作,但不能作为 jar 工作
【发布时间】:2017-09-03 09:57:57
【问题描述】:

我创建了一个 maven java 应用程序来执行一些 neo4j 查询。我有一个类正在执行 neo4j 查询,还有一个类我用 Swing 制作了一个 gui,因此我可以使用按钮执行查询并在 textArea 中显示结果。如果我在 Netbeans 中运行该项目,一切正常,但是当我使用 maven shade 插件创建该项目的胖 jar 时,会发生一些事情并且 neo4j 命令不起作用。我认为问题出在 lucene jars(来自 apache 文件夹和 neo4j 文件夹)所以我在 pom.xml 文件中使用了一些代码来修复它,但没有运气。可能问题是因为类路径中的相同类名冲突。

myJFrame.java

package com.mycompany.neo4jqueries;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;

/**
 *
 * @author Dar309
 */
public class myJFrame extends JPanel {

    private JComboBox firstComboBox;
    private JTextArea queryTextArea, resultTextArea, infoTextArea;
    private String[] comboBoxItems, queryList;
    private JButton executeButton;
    private Font monosSpacedFont = new Font("monospaced", Font.PLAIN, 12);
    private JProgressBar progressBar;
    private Task myTask;
    private long miliBeforeExec = 0, miliAfterExec = 0, execTime = 0;

    public myJFrame() {
        super(new BorderLayout());

        JPanel firstPanel = new JPanel();
        BorderLayout fpL = new BorderLayout();
        firstPanel.setLayout(fpL);

        JPanel topPanel = new JPanel();
        topPanel.setLayout(new BorderLayout());

        JPanel topPanel1 = new JPanel();
        topPanel1.setLayout(new FlowLayout(FlowLayout.CENTER));

        comboBoxItems = new String[]{"1",
            "The Top 10 Stack Overflow Users",
            "The Top 5 tags That Jon Skeet Used in Asking Questions"};

        queryList = new String[]{"match (n) \nreturn head(labels(n)) as label, count(*)",
            "match (u:User) \nwith u,size( (u)-[:POSTED]->()) as posts order by posts desc limit 10 \nreturn u.name, posts",
            "match (u:User)-[:POSTED]->()-[:HAS_TAG]->(t:Tag) \nwhere u.name = 'Jon Skeet' \nreturn t,count(*) as posts order by posts desc limit 5"};

        firstComboBox = new JComboBox(comboBoxItems);

        firstComboBox.setSelectedIndex(0);
        firstComboBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                queryTextArea.setText(queryList[firstComboBox.getSelectedIndex()]);

            }
        });

        topPanel1.add(firstComboBox);

        JPanel topPanel2 = new JPanel();
        topPanel2.setLayout(new FlowLayout());

        queryTextArea = new JTextArea();
        queryTextArea.setText(queryList[0]);
        queryTextArea.setFont(monosSpacedFont);
        queryTextArea.setEditable(false);

        JScrollPane queryScrollPane = new JScrollPane(queryTextArea);
        queryScrollPane.setPreferredSize(new Dimension(450, 110));

        topPanel2.add(queryScrollPane);

        JPanel topPanel3 = new JPanel();
        topPanel3.setLayout(new FlowLayout());

        progressBar = new JProgressBar(0, 100);
        progressBar.setValue(0);
        progressBar.setString("No progress yet");
        progressBar.setStringPainted(true);

        executeButton = new JButton("Execute");
        executeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                executeButton.setEnabled(false);
                progressBar.setIndeterminate(true);
                firstComboBox.setEnabled(false);
                progressBar.setString("Loading...");
                setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

                miliBeforeExec = System.currentTimeMillis();

                //Instances of javax.swing.SwingWorker are not reusuable, so
                //we create new instances as needed.
                myTask = new Task();
                myTask.addPropertyChangeListener(new PropertyChangeListener() {
                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        if ("progress" == evt.getPropertyName()) {
//                            int progress = (Integer) evt.getNewValue();
//                            progressBar.setValue(progress);
                        }
                    }
                });
                myTask.execute();
            }
        });

        topPanel3.add(progressBar);
        topPanel3.add(executeButton);

        topPanel.add(topPanel1, BorderLayout.NORTH);
        topPanel.add(topPanel2, BorderLayout.CENTER);
        topPanel.add(topPanel3, BorderLayout.SOUTH);

        firstPanel.add(topPanel, BorderLayout.NORTH);

        JPanel resultPanel = new JPanel();
        resultPanel.setLayout(new BorderLayout());

        resultTextArea = new JTextArea();
        resultTextArea.setFont(monosSpacedFont);
        resultTextArea.setText("");
        resultTextArea.setEditable(false);

        JScrollPane centerScrollPane = new JScrollPane(resultTextArea);
        centerScrollPane.setPreferredSize(new Dimension(550, 200));
        centerScrollPane.setBorder(BorderFactory.createEmptyBorder(5, 0, 10, 0));
        resultPanel.add(centerScrollPane, BorderLayout.CENTER);

        infoTextArea = new JTextArea();
        infoTextArea.setRows(2);
        infoTextArea.setFont(monosSpacedFont);
        infoTextArea.setEditable(false);

        resultPanel.add(infoTextArea, BorderLayout.SOUTH);

        firstPanel.add(resultPanel, BorderLayout.CENTER);

        add(firstPanel, BorderLayout.CENTER);
        setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
    }

    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame();
//        frame.setSize(650, 550);
        frame.setSize(Toolkit.getDefaultToolkit().getScreenSize().width / 2,Toolkit.getDefaultToolkit().getScreenSize().height / 2);
        frame.setMinimumSize(new Dimension(frame.getWidth(), frame.getHeight()));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Execute your Neo4j queries");

        Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (int) ((dimension.getWidth() - frame.getWidth()) / 2);
        int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);
        frame.setLocation(x, y);

        //Create and set up the content pane.
        JComponent newContentPane = new myJFrame();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    class Task extends SwingWorker<Void, Void> {

        /*
         * Main task. Executed in background thread.
         */
        @Override
        public Void doInBackground() {
//            Random random = new Random();
//            int progress = 0;
            //Initialize progress property.
            setProgress(0);

            System.out.println("popo");
            resultTextArea.append("popo");
            myQuery mq = new myQuery();
            mq.run(myJFrame.this);
            resultTextArea.append("metaaaa");
            System.out.println("metaaa");

//            setProgress(Math.min(progress, 100));
            return null;
        }

        /*
         * Executed in event dispatching thread
         */
        @Override
        public void done() {
            Toolkit.getDefaultToolkit().beep();
            progressBar.setIndeterminate(false);
            executeButton.setEnabled(true);
            firstComboBox.setEnabled(true);
//            resultTextArea.setCaretPosition(resultTextArea.getText().length());
            setCursor(null); //turn off the wait cursor

            miliAfterExec = System.currentTimeMillis();
            execTime = miliAfterExec - miliBeforeExec;
//            execTime += 11140000;

            if (execTime < 60 * 1000) {
                infoTextArea.setText("Total time: " + (double) (execTime / 1000.000) + "s");
            }          
//            else if(execTime >= (60 * 1000) && execTime < (3600 * 1000) ){
            else if (execTime >= (60 * 1000)) {
                long temp = execTime;
                for (long i = 0; i < execTime / (60 * 1000); i++) {
                    temp -= (60 * 1000);
                }
                infoTextArea.setText("Total time: " + (execTime / (60 * 1000)) + ":" + (double) (temp / 1000.000) + "s");
            }
            Date date = new Date();
            infoTextArea.append("\nFinished at: " + date.toString());

            progressBar.setString("Done!");
        }
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }

    public JTextArea getResultTextArea() {
        return resultTextArea;
    }

    public JTextArea getQueryTextArea() {
        return queryTextArea;
    }

}

myQuery.java

    /*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mycompany.neo4jqueries;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.JFrame;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Result;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.helpers.collection.Iterators;

/**
 *
 * @author Dar309
 */
public class myQuery {

    private static final File DB_PATH = new File("D:/IU/Διπλωματική/neo4j-community-3.1.2/data/databases/graph.db");
    String resultString;
    String columnsString;
    String nodeResult;
    String rows = "";


    void run(myJFrame myFrame) {
        GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);

        myFrame.getResultTextArea().append("sdadsdsadsads");
        System.out.println("naiiiii");
        try (Transaction ignored = db.beginTx();
//                Result result = db.execute("match (u:User) with u,size( (u)-[:POSTED]->()) as posts order by posts desc limit 10 return u.name, posts")) {
                Result result = db.execute(myFrame.getQueryTextArea().getText() ) ) {

            // START SNIPPET: columns
            List<String> columns = result.columns();
            // END SNIPPET: columns

            columnsString = columns.toString();
//            resultString = db.execute( "match (u:User) with u,size( (u)-[:POSTED]->()) as posts order by posts desc limit 10 return u.name, posts" ).resultAsString();
            resultString = result.resultAsString();
            System.out.println("\n\ncolumnsString\n------------------------------------------");
            System.out.println(columnsString);

            System.out.println("\n\nresultString\n------------------------------------------");
            System.out.println(resultString);
            myFrame.getResultTextArea().append(resultString);

            try {
                PrintWriter writer = new PrintWriter("the-file-name.txt", "UTF-8");
                writer.print(resultString);
                writer.close();
            } catch (IOException e) {
                // do something
            }
        }

        db.shutdown();
    }

}

pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mycompany</groupId>
    <artifactId>Neo4jQueries</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.neo4j</groupId>
            <artifactId>neo4j</artifactId>
            <version>3.1.2</version>
        </dependency>
    </dependencies>
    <name>neo4jQueries</name>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <shadedArtifactAttached>true</shadedArtifactAttached>
                            <shadedClassifierName>shaded</shadedClassifierName>
                            <createDependencyReducedPom>false</createDependencyReducedPom>
                            <relocations>
                                <relocation>
                                    <pattern>org.apache.lucene</pattern>
                                    <shadedPattern>shaded_lucene_5_5_0.org.apache.lucene</shadedPattern>
                                </relocation>
                                <relocation>
                                    <pattern>org.neo4j</pattern>
                                    <shadedPattern>shaded_neo4j.org.neo4j</shadedPattern>
                                </relocation>
                            </relocations>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.mycompany.neo4jqueries.myJFrame</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>neo4j-repo</id>
            <name>Neo4j Repository</name>
            <url>http://m2.neo4j.org/content/repositories/releases</url>
        </repository>
    </repositories>

</project>

当我双击 jar 时,我看到 gui 并且一切正常,直到调用 myQuery 类,然后没有执行 neo4j 命令但没有显示错误消息。

有人可以帮我解决这个问题吗?

【问题讨论】:

    标签: java maven netbeans neo4j lucene


    【解决方案1】:

    您的程序硬编码了 neo4j 数据库的路径。

    因此,如果您没有在开发代码的同一台机器上运行 jar 文件,它将无法找到数据库并引发异常。

    但是,正如InvokeLater 的文档所说,如果您将Runnable 传递给它:

    抛出一个未捕获的异常,事件调度线程将展开 (不是当前线程)

    这意味着除非您明确告诉 Swing 使用您提供的异常处理程序,否则您的线程将永远不会看到任何未捕获的异常。请参阅this question 及其 2 个得分最高的答案,了解如何做到这一点(取决于您使用的 Java 版本)。

    【讨论】:

    • 我没有得到你的答案,不过我会搜索一下。顺便说一句,我解决了这个问题。我只是安装了 Eclipse,不再使用 Netbeans。在 Eclipse 中有一个将项目导出到文件的选项,所以我选择将我的项目导出到可执行 jar 文件,所有包含的包都打包在新 jar 中。(它是可执行 jar 选项中三个选项中的第二个选择)所以现在我有一个可执行的 jar 并且一切正常,因为问题是同一个类名冲突。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 2012-09-05
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多