简体   繁体   English

如何避免 Java 可执行文件 jar 中的 NullPointerException?

[英]How to avoid NullPointerException in Java executable jar?

I minimize the application to reproduce the error.我最小化应用程序以重现错误。 I used Java 8 and IntelliJ Swing Designer to make this minimum GUI app.我使用 Java 8 和 IntelliJ Swing Designer 来制作这个最小的 GUI 应用程序。

public class MyGui {
private JList<String> docList;
private JPanel mainPanel;
private DefaultListModel<String> listDocModel;

public MyGui(){

    listDocModel = new DefaultListModel<>();

    try (InputStream resource = MyGui.class.getResourceAsStream("/data.csv");
         BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource, StandardCharsets.UTF_8))) {
        String line = "";
        while ((line = bufferedReader.readLine()) != null) {
            listDocModel.addElement(line);
        }
    } catch (IOException e) {
        System.out.println(e.getMessage());
    }
    docList.setModel(listDocModel); // I didn't initialize docList. But it works when run from the IDE.  
}

public static void main(String[] args) {
    JFrame frame = new JFrame("MyGui");
    frame.setContentPane(new MyGui().mainPanel);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setPreferredSize( new Dimension( 800, 800));
    frame.pack();
    frame.setVisible(true);
}
}

Later I made a jar using maven-assembly-plugin.后来我用maven-assembly-plugin做了一个jar。 When I run the app as java -jar myap.jar当我以java -jar myap.jar运行应用程序时

I got this null pointer exception:-我得到了这个 null 指针异常:-

Exception in thread线程异常

"main" java.lang.NullPointerException
        at org.example.MyGui.<init>(MyGui.java:30)
        at org.example.MyGui.main(MyGui.java:38)

Line 30 is docList.setModel(listDocModel);第 30 行是docList.setModel(listDocModel); So my question how come that work by IDE but doesn't work form jar.所以我的问题是 IDE 怎么能工作,但不能从 jar 工作。 By the IDE my list is filled with data as:-通过 IDE 我的列表中填充了以下数据:-

在此处输入图像描述

To fix this I tried following update:-为了解决这个问题,我尝试了以下更新:-

   docList = new JList<>(listDocModel);
   mainPanel = new JPanel();
   mainPanel.add(docList);

After this my list is empty no more data:-在此之后,我的列表为空,不再有数据:-

在此处输入图像描述

So how do I make my list with data and make an executable jar ?那么如何使用数据制作我的列表并制作可执行的jar

Update full project:-更新完整项目:-

https://github.com/masiboo/SwingGui https://github.com/masiboo/SwingGui

// I didn't initialize docList. But it works when run from the IDE.

In that case, it is the IDE that is the problem.在这种情况下,问题出在 IDE 上。 Possibly doing a 'clean and build' will shake the gremlins out, but I can't provide support for IDEs.可能进行“清理和构建”会动摇小精灵,但我无法为 IDE 提供支持。

The docList ( mainPanel etc.) all need to be instantiated before use. docListmainPanel等)需要在使用前进行实例化。

In addition to that, the list needs to be put on a container that is visible on the GUI, preferably wrapped in a scroll pane (as this example does).除此之外,需要将列表放在 GUI 上可见的容器上,最好包裹在滚动窗格中(如本示例所示)。

在此处输入图像描述

Final note: It got to the point in comments, that the 'file loading was fine'.最后一点:评论中的重点是“文件加载很好”。 That's a good time to factor it out of the example and use hard coded data as below.这是将其从示例中剔除并使用硬编码数据的好时机,如下所示。 The MRE below does that - so anyone can run it to see it work (or fail).下面的 MRE 就是这样做的——所以任何人都可以运行它来查看它的工作(或失败)。 Prepare and post a minimal reproducible example like this for the best help fastest.准备并发布一个像这样的最小可重复示例,以获得最快的帮助。

import java.awt.*;
import javax.swing.*;

public class MyGui {

    // what happens in the IDE is irrelevant, this needs to be instantiated
    private JList<String> docList = new JList<>();
    // .. as does this
    private JPanel mainPanel = new JPanel(new BorderLayout());
    private DefaultListModel<String> listDocModel;
    // if the problem is not I/O related, factor it out by hard coding data
    private String[] data = {
        "Apples,are,Crunchy",
        "Oranges,are,Orange",
        "Bananas,are,Bent",};

    public MyGui() {
        listDocModel = new DefaultListModel<>();

        for (String line : data) {
            listDocModel.addElement(line);
        }
        // I didn't initialize docList. But it works when run from the IDE.
        // THEN THE IDE IS THE PROBLEM. Possibly fixed with a 'clean and build'.
        docList.setModel(listDocModel); 
        
        // now add the list to the panel! 
        mainPanel.add(new JScrollPane(docList));
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("MyGui");
        frame.setContentPane(new MyGui().mainPanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // Avoid guesses, pack will produce the min size needed to display GUI
        //frame.setPreferredSize(new Dimension(..));
        frame.pack();
        frame.setVisible(true);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM