如何避免Java可执行jar中的NullPointerException? [英] How to avoid NullPointerException in Java executable jar?

查看:93
本文介绍了如何避免Java可执行jar中的NullPointerException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最小化应用程序以重现错误.我使用 Java 8 和 IntelliJ Swing Designer 来制作这个最小的 GUI 应用程序.

public class MyGui {私有 JList文档列表;私人 JPanel 主面板;private DefaultListModel列表文档模型;公共 MyGui(){listDocModel = new DefaultListModel<>();尝试 (InputStream 资源 = MyGui.class.getResourceAsStream("/data.csv");BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource, StandardCharsets.UTF_8))) {字符串行 = "";while ((line = bufferedReader.readLine()) != null) {listDocModel.addElement(line);}} catch (IOException e) {System.out.println(e.getMessage());}docList.setModel(listDocModel);//我没有初始化 docList.但它在从 IDE 运行时有效.}公共静态无效主(字符串 [] args){JFrame frame = new JFrame("MyGui");frame.setContentPane(new MyGui().mainPanel);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setPreferredSize(new Dimension(800, 800));框架.pack();frame.setVisible(true);}}

后来我用 maven-assembly-plugin 做了一个 jar.当我以 java -jar myap.jar

运行应用程序时

我得到了这个空指针异常:-

线程异常

main"java.lang.NullPointerException在 org.example.MyGui.(MyGui.java:30)在 org.example.MyGui.main(MyGui.java:38)

第 30 行是 docList.setModel(listDocModel); 所以我的问题是如何在 IDE 中工作,但在 jar 中不起作用.通过 IDE,我的列表中填充了以下数据:-

为了解决这个问题,我尝试了以下更新:-

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

此后,我的列表为空,不再有数据:-

那么我如何用数据制作我的列表并制作一个可执行的jar?

更新完整项目:-

最后一点:在评论中,文件加载很好".这是将其从示例中分解出来并使用如下硬编码数据的好时机.下面的 MRE 就是这样做的——所以任何人都可以运行它来查看它的工作(或失败).准备并发布一个像这样的最小可重现示例,以最快速度获得最佳帮助.

import java.awt.*;导入 javax.swing.*;公共类 MyGui {//IDE 中发生的事情无关紧要,这需要实例化私有 JListdocList = new JList<>();//.. 也是这样private JPanel mainPanel = new JPanel(new BorderLayout());private DefaultListModel列表文档模型;//如果问题与 I/O 无关,则通过硬编码数据将其分解私有字符串[] 数据 = {苹果,很脆",橙子,是,橙子",香蕉,是,弯曲",};公共 MyGui() {listDocModel = new DefaultListModel<>();for(字符串行:数据){listDocModel.addElement(line);}//我没有初始化 docList.但它在从 IDE 运行时有效.//那么 IDE 就是问题所在.可能通过清洁和构建"进行修复.docList.setModel(listDocModel);//现在将列表添加到面板中!mainPanel.add(new JScrollPane(docList));}公共静态无效主(字符串 [] args){JFrame frame = new JFrame("MyGui");frame.setContentPane(new MyGui().mainPanel);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//避免猜测,pack 将产生显示 GUI 所需的最小尺寸//frame.setPreferredSize(new Dimension(..));框架.pack();frame.setVisible(true);}}

I minimize the application to reproduce the error. I used Java 8 and IntelliJ Swing Designer to make this minimum GUI app.

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. When I run the app as java -jar myap.jar

I got this null pointer exception :-

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); So my question how come that work by IDE but doesn't work form jar. By the IDE my list is filled with data as:-

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?

Update full project:-

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. Possibly doing a 'clean and build' will shake the gremlins out, but I can't provide support for IDEs.

The docList (mainPanel etc.) all need to be instantiated before use.

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).

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). 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);
    }
}

这篇关于如何避免Java可执行jar中的NullPointerException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆