代码之家  ›  专栏  ›  技术社区  ›  Simon

Java程序在eclipse中运行。作为可运行Jar失败

  •  0
  • Simon  · 技术社区  · 6 年前

    我已经编写了一个Java应用程序,在Eclipse上运行时效果很好 编译器JDK是1.8,JRE是jdk1附带的。8.0\u 172 Eclipse正在以正常的64位模式运行,JDK是64位版本

    我需要能够从运行应用程序。bat或。cmd文件:

    jre8\bin\java.exe -jar ClientNavigator.jar
    pause
    

    路径指的是JRE的一个副本,我将用runnable绑定到安装程序中。罐子

    正在运行。bat文件导致此错误:

    jre8\bin\java.exe -jar ClientNavigator.jar
    java.lang.NullPointerException
            at ClientNavigator.<init>(ClientNavigator.java:50)
            at ClientNavigator.main(ClientNavigator.java:61)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
    

    当我使用eclipse将应用程序导出为可运行时。jar我选择“将所需库打包到生成的jar中”

    下面是我的大部分Java代码。

    /*
     * Last edit: 5/9/2018 - Simon
    */
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.URI;
    import java.net.URISyntaxException;
    import java.util.Scanner;
    
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.events.KeyAdapter;
    import org.eclipse.swt.events.KeyEvent;
    import org.eclipse.swt.events.MouseAdapter;
    import org.eclipse.swt.events.MouseEvent;
    import org.eclipse.swt.events.SelectionAdapter;
    import org.eclipse.swt.events.SelectionEvent;
    import org.eclipse.swt.graphics.Point;
    import org.eclipse.swt.layout.FillLayout;
    import org.eclipse.swt.widgets.Button;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.Label;
    import org.eclipse.swt.widgets.List;
    import org.eclipse.swt.widgets.Shell;
    import org.eclipse.swt.widgets.Text;
    import org.eclipse.ui.forms.events.HyperlinkEvent;
    import org.eclipse.ui.forms.events.IHyperlinkListener;
    import org.eclipse.ui.forms.widgets.FormToolkit;
    import org.eclipse.ui.forms.widgets.Hyperlink;
    import org.eclipse.wb.swt.SWTResourceManager;
    
    public class ClientNavigator {
    
        protected Shell shlClientNavigator; // This is the main window
        private Text nameBox;
        private Text serverBox;
        private Text portBox;
        private final FormToolkit formToolkit = new FormToolkit(Display.getDefault());
        private String dataPath = ClientNavigator.class.getResource("BMCliDat.csv").toString().substring(5);
        public String dataFile = dataPath; // this is the data file. It's .csv for
                                            // easy export and edit
    
        /**
         * Launch the application.
         * 
         * @param args
         */
        public static void main(String[] args) {
            try {
                ClientNavigator window = new ClientNavigator();
                window.open();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * Open the window.
         */
        public void open() {
            Display display = Display.getDefault();
            createContents();
            shlClientNavigator.open();
            shlClientNavigator.layout();
            while (!shlClientNavigator.isDisposed()) {
                if (!display.readAndDispatch()) {
                    display.sleep();
                }
            }
        }
    
        /**
         * Create contents of the window.
         */
        protected void createContents() {
            shlClientNavigator = new Shell();
            String imgPath = ClientNavigator.class.getResource("BMInstaller.png").toString().substring(5);
            shlClientNavigator.setImage(SWTResourceManager.getImage(imgPath)); // non-essential
            shlClientNavigator.setMinimumSize(new Point(500, 500)); // prevent squishing
            shlClientNavigator.setSize(500, 500); // due to layout there is no benefit to stretching
            shlClientNavigator.setText("Client Navigator");
            // Style: try to keep all elements 10px apart
            Label lblName = new Label(shlClientNavigator, SWT.NONE);
            lblName.setBounds(10, 10, 60, 30);
            lblName.setText("Title:");
    
            Label lblName_1 = new Label(shlClientNavigator, SWT.NONE);
            lblName_1.setText("Server:");
            lblName_1.setBounds(10, 46, 60, 30);
    
            Label lblName_2 = new Label(shlClientNavigator, SWT.NONE);
            lblName_2.setText("Port:");
            lblName_2.setBounds(10, 81, 60, 30);
    
            final Label lblErrLabel = new Label(shlClientNavigator, SWT.WRAP | SWT.SHADOW_NONE);
            lblErrLabel.setTouchEnabled(true);
            lblErrLabel.setToolTipText("Error Bar");
            lblErrLabel.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
            lblErrLabel.setBounds(10, 365, 458, 27);
            formToolkit.adapt(lblErrLabel, true, true);
    
            nameBox = new Text(shlClientNavigator, SWT.BORDER);
            nameBox.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.keyCode == 13) { // keyCode 13 on Windows is [Enter]. 9 is [Tab]
                        bmConnect(serverBox.getText().trim(), portBox.getText().trim(), nameBox.getText().trim());
                    }
                }
            });
            nameBox.setToolTipText("Connection name");
            nameBox.setBounds(76, 10, 239, 30);
    
            serverBox = new Text(shlClientNavigator, SWT.BORDER);
            serverBox.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.keyCode == 13) { // keyCode 13 on Windows is [Enter]
                        bmConnect(serverBox.getText().trim(), portBox.getText().trim(), nameBox.getText().trim());
                    }
                }
            });
            serverBox.setToolTipText("Server name");
            serverBox.setBounds(76, 46, 239, 30);
    
            portBox = new Text(shlClientNavigator, SWT.BORDER);
            portBox.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) { // keyCode 13 on Windows is [Enter]
                    if (e.keyCode == 13) {
                        bmConnect(serverBox.getText().trim(), portBox.getText().trim(), nameBox.getText().trim());
                    }
                }
            });
            portBox.setToolTipText("Port number");
            portBox.setBounds(76, 82, 239, 30);
            // The list is merely a display and does not hold any connection info
            final List list = new List(shlClientNavigator, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
            list.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.keyCode == 13) { // keyCode 13 on Windows is [Enter]
                        bmConnect(serverBox.getText().trim(), portBox.getText().trim(), nameBox.getText().trim());
                    } else if (e.keyCode == 127) { // keyCode 127 on Windows is [Delete]
                        // fast delete with delete key - bad idea?
                        deleteData(nameBox.getText());
                        // repopulate the list
                        fillList(list);
                    }
                }
            });
            list.addSelectionListener(new SelectionAdapter() {
                /*
                 * What happens here: The SelectionEvent does not contain the info we need to
                 * populate the textBoxes However, due to how the list is populated - see
                 * fillList() - the SelectionIndecies match perfectly with the line numbers in
                 * the .csv
                 * 
                 * So, the bufferedReader cycles down until the index of the selected item ==
                 * the current .csv line number being read the line is then parsed and used to
                 * populate the textBoxes
                 */
                @Override
                public void widgetSelected(SelectionEvent e) {
                    int lineNum = 0;
                    String currLine;
                    try {
                        FileReader fileReader = new FileReader(dataFile);
                        BufferedReader bufferedReader = new BufferedReader(fileReader);
                        while ((currLine = bufferedReader.readLine()) != null) {
                            String[] record = currLine.split(",");
                            if (lineNum == list.getSelectionIndex()) {
                                serverBox.setText(record[0]);
                                portBox.setText(record[1]);
                                nameBox.setText(record[2]);
                            }
                            lineNum++;
                        }
                        bufferedReader.close();
                    } catch (FileNotFoundException ex) {
                        makeErrBar("Unable to open file '" + dataFile + "'", lblErrLabel);
                    } catch (IOException ex) {
                        makeErrBar("Error reading file '" + dataFile + "'", lblErrLabel);
                    }
                }
            });
            list.setBounds(10, 125, 458, 234);
            // initial list population
            fillList(list);
            formToolkit.adapt(list, true, true);
    
            Button btnGo = new Button(shlClientNavigator, SWT.CENTER);
            btnGo.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseDown(MouseEvent e) {
                    if (hasMissing((serverBox.getText().trim() + "," + portBox.getText().trim() + ","
                            + nameBox.getText().trim()))) {
                        makeErrBar("All fields are required", lblErrLabel);
                        return;
                    }
                    bmConnect(serverBox.getText().trim(), portBox.getText().trim(), nameBox.getText().trim());
                }
            });
            btnGo.setToolTipText("Establish connection");
            btnGo.setBounds(321, 9, 147, 52);
            btnGo.setText("Connect");
    
            Button btnSave = new Button(shlClientNavigator, SWT.CENTER);
            btnSave.setToolTipText("Save by title");
            btnSave.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseDown(MouseEvent e) {
                    String recordSave = (serverBox.getText().trim() + "," + portBox.getText().trim() + ","
                            + nameBox.getText().trim());
                    if (hasMissing(recordSave)) {
                        makeErrBar("All fields are required", lblErrLabel);
                    } else {
                        // see saveData() for more info on how this works
                        saveData(recordSave);
                        // repopulate the list
                        fillList(list);
                    }
                }
            });
            btnSave.setText("Save");
            btnSave.setBounds(321, 67, 147, 52);
    
            Button btnDelete = new Button(shlClientNavigator, SWT.CENTER);
            btnDelete.setToolTipText("Remove saved connection");
            btnDelete.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    // Clicking the delete button spawns a new shell with a prompt to prevent
                    // accidental deletions
                    if (nameBox.getText().trim().length() < 1) {
                        makeErrBar("Title required", lblErrLabel);
                        return;
                    } else {
                        final Shell shlDelDiag = new Shell();
                        shlDelDiag.setText("Delete " + nameBox.getText() + "?");
                        shlDelDiag.setSize(300, 200);
    
                        Label lblDiagLabel = new Label(shlDelDiag, SWT.WRAP);
                        // has enough space for substantially sized names but may not be enough
                        lblDiagLabel.setBounds(10, 10, 258, 77);
                        lblDiagLabel.setText("Are you sure you want to delete: " + nameBox.getText());
    
                        Button btnYes = new Button(shlDelDiag, SWT.NONE);
                        btnYes.addMouseListener(new MouseAdapter() {
                            @Override
                            public void mouseDown(MouseEvent e) {
                                // see deleteData for more info
                                deleteData(nameBox.getText());
                                // repopulate the list
                                fillList(list);
                                // dialogue box no longer needed
                                shlDelDiag.dispose();
                            }
                        });
                        btnYes.setBounds(163, 99, 105, 35);
                        btnYes.setText("Yes");
    
                        Button btnNo = new Button(shlDelDiag, SWT.NONE);
                        btnNo.addMouseListener(new MouseAdapter() {
                            @Override
                            public void mouseDown(MouseEvent e) {
                                // dialogue box no longer needed
                                shlDelDiag.dispose();
                            }
                        });
                        btnNo.setBounds(10, 99, 105, 35);
                        btnNo.setText("No");
                        shlDelDiag.open();
                        shlDelDiag.layout();
                        // possibly redundant?
                        fillList(list);
                    }
                }
            });
            btnDelete.setText("Delete");
            btnDelete.setBounds(367, 398, 101, 36);
        }
    
        private void fillList(List list) {
            // fill out list w/ info
            String currLine = null;
            list.removeAll();
            try {
                // FileReader reads text files in the default encoding.
                FileReader fileReader = new FileReader(dataFile);
                BufferedReader bufferedReader = new BufferedReader(fileReader);
                while ((currLine = bufferedReader.readLine()) != null) {
                    // use comma as separator
                    String[] record = currLine.split(",");
                    if (hasMissing(currLine)) {
                        continue;
                    }
                    list.add(record[2].toString()); // save by title
                }
                // Close files.
                bufferedReader.close();
            } catch (FileNotFoundException ex) {
                makeErrBar("Unable to open file '" + dataFile + "'", null);
            } catch (IOException ex) {
                makeErrBar("Error reading file '" + dataFile + "'", null);
            }
        }
    
        // This method creates a label containing relevant error messages
        private void makeErrBar(String error, Label lblErrLabel) {
            // If the error message is too large to fit spawn a new window.
            // The general idea here is that the smaller messages should be meaningful to
            // the end users while the larger messages are for debugging or tech support
            if (error.length() > 40 || lblErrLabel == null) {
                final Shell shlErrDiag = new Shell();
                shlErrDiag.setText("Error");
                shlErrDiag.setSize(300, 200);
                shlErrDiag.setLayout(new FillLayout(SWT.HORIZONTAL));
                Label lblDErrLabel = new Label(shlErrDiag, SWT.WRAP | SWT.SHADOW_NONE);
                lblDErrLabel.setTouchEnabled(true);
                lblDErrLabel.setToolTipText("Error Bar");
                lblDErrLabel.setText(error);
                lblDErrLabel.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
                formToolkit.adapt(lblDErrLabel, true, true);
                shlErrDiag.open();
                shlErrDiag.layout();
            } else {
                lblErrLabel.setText(error);
                lblErrLabel.redraw();
                formToolkit.adapt(lblErrLabel, true, true);
                lblErrLabel.redraw();
            }
            // note that once the user triggers an error only another error will remove the
            // error label. Change?
        }
    
        private void saveData(String record) {
            String[] target = record.split(",");
            // This step is to prevent the creation of duplicates
            deleteData(target[2]); // 3rd index (target[2]) holds the name. delete by name
            try {
                FileWriter fileWriter = new FileWriter(dataFile, true);
                BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
                bufferedWriter.write(record);
                bufferedWriter.newLine();
                bufferedWriter.close();
            } catch (IOException ex) {
                makeErrBar("Error writing to file '" + dataFile + "'", null);
            }
        }
    
        // shortcut method to check for incomplete records in the .csv
        private boolean hasMissing(String rec) {
            if (rec.substring(0, 1).equals(",") || rec.substring(rec.length() - 1).equals(",") || rec.contains(",,")) {
                return true;
            }
            return false;
        }
    
        private void deleteData(String target) {
            File dFile = new File(dataFile);
            File tempFile = new File("temp.csv");
            try {
                // deletion is performed by writing a second file which excludes target
                BufferedReader reader = new BufferedReader(new FileReader(dFile));
                BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));
                String currentLine;
                while ((currentLine = reader.readLine()) != null) {
                    if (hasMissing(currentLine)) { // clean up blanks
                        continue;
                    }
                    String[] record = currentLine.split(",");
                    if (record[2].equals(target))
                        continue;
                    writer.write(record[0] + "," + record[1] + "," + record[2]);
                    writer.newLine();
                }
                writer.close();
                reader.close();
                // delete original file
                dFile.delete();
                // temp takes it's name
                tempFile.renameTo(dFile);
                // temp file is deleted
                tempFile.delete();
            } catch (Exception e) {
                makeErrBar(e.toString(), null);
            }
        }
    
        @SuppressWarnings("resource")
        public void bmConnect(String server, String port, String title) {
            if (hasMissing(server + "," + port + "," + title)) {
                makeErrBar("All fields are required", null);
                return;
            } else {
                String bmConnectPath = ClientNavigator.class.getResource("bmConnect.bat").toString().substring(5);
                ProcessBuilder pb = new ProcessBuilder(bmConnectPath, title, server, port);
                Process process;
                try {
                    process = pb.start();
                    int errCode = process.waitFor();
                    if (errCode != 0) {
                        InputStream errStream = process.getErrorStream();
                        Scanner errScan = new Scanner(errStream).useDelimiter("\\A");
                        String errMsg = errScan.hasNext() ? errScan.next() : "";
                        errScan.close();
                        errStream.close();
                        makeErrBar(errMsg, null);
                    }
                } catch (IOException e) {
                    makeErrBar(e.toString(), null);
                } catch (InterruptedException e) {
                    makeErrBar(e.toString(), null);
                }
            }
        }
    }
    

    我需要更改什么才能运行。我可以将哪些Jar与jre打包在一起?

    我的代码有问题吗?它在Eclipse中编译得很好。

    我构建项目的方式是否有问题?

    我意识到我的代码严重依赖于组织。eclipse库。这就是问题所在吗?如果是这样,我应该怎么做来补救?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Simon    6 年前

    Eclipse的导出不会将其他文件打包到中。罐子

    正如一些用户指出的,错误是指

    private String dataPath = ClientNavigator.class.getResource("BMCliDat.csv").toString().substring(5);
    

    BMCliDat公司。csv不存在。

    解决方案是导出runnable。然后手动将所需的其他文件添加到。Jar住在里面。将它们直接添加到。Jar不工作。

    幸亏 Andres 谢谢你的帮助!