如何避免Java可执行jar中的NullPointerException? [英] How to avoid NullPointerException in Java executable jar?
问题描述
我最小化应用程序以重现错误.我使用 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屋!