在 Eclipse 中工作,而不是在 JAR 文件中 - Class.forName() 似乎没有抛出异常,但代码立即转移到finally块

问题描述 投票:0回答:1

首先,这在 Eclipse 中有效,但在运行生成的 JAR 文件时无效。当 JAR 运行时,它似乎没有生成任何异常,而是代码执行在 Class.forName() 调用处停止,并立即转移到finally 块。您可以在 System.out.println() 调用(或缺少)中看到这一点。

Eclipse 中的输出:

正在寻找班级... 正在获取日志人口的连接... 已连接到日志人口... 在最后块... 完成了。

JAR 文件运行时的输出:

C:\me\myProgram>java -cp MyJar.jar;mssql-jdbc-12.4.0.jre11.jar com.me.myProgram.Main
Finding class...
In finally block...
Exception in thread "main" java.lang.NullPointerException
        at com.me.myProgram.logResults(Comparison.java:449)
        at com.me.myProgram.run(Comparison.java:547)
        at com.me.myProgram.Main.main(Main.java:13)

我知道这不是找不到类的问题(或者至少看起来不像),因为如果我更改为 Class.forName("com.microsoft.sqlserver.jdbc.blahblah");然后我得到:

D:\me\myProgram>java -cp MyJar.jar;mssql-jdbc-12.4.0.jre11.jar com.me.myProgram.Main
Finding class...
com.microsoft.sqlserver.jdbc.SQLServerDrive
java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDrive
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:264)
        at com.me.myProgram.Comparison.logResults(Comparison.java:392)
        at com.me.myProgram.Comparison.run(Comparison.java:547)
        at com.me.myProgram.Main.main(Main.java:13)
In finally block...
Exception in thread "main" java.lang.NullPointerException
        at com.me.myProgram.Comparison.logResults(Comparison.java:449)
        at com.me.myProgram.Comparison.run(Comparison.java:547)
        at com.me.myProgram.Main.main(Main.java:13)

代码(第449行是con.close()):

public void logResults(){
        Connection con = null;      
        Boolean success = isJobRowCountMatch && isEntryCountMatch && isExtractCountMatch && (isDeltaPresent || isFullPresent);
        String informationalString = getInformationalString(), issueString = getIssueString(), badEntriesString = 
                getBadEntriesString();
        try {           
            System.out.println("Finding class...");
            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
            System.out.println("Getting connection for log population...");
            fw.write("Getting connection for log population..." + System.lineSeparator());
            con = DriverManager.getConnection(connectionString);
            System.out.println("Got connection for log population...");
            PreparedStatement st = con.prepareStatement(logPreparedStatement);
            java.sql.Timestamp ts = Timestamp.valueOf(d);
            st.setTimestamp(1, ts);
            st.setBoolean(2, success);
            st.setNString(3, informationalString);
            st.setNString(4, issueString);
            st.setNString(5, badEntriesString);
            fw.write("Inserting log entry..." + System.lineSeparator());
            if(outputLogFile.createNewFile() || outputLogFile.exists()) {
                fw.write("Job timestamp: " + month + "-" + day + 
                        "-" + year + " " + hour + ":" + minute + ":" + second + System.getProperty("line.separator"));
                fw.write("Informational entries: " + informationalString + System.getProperty("line.separator"));
                fw.write("Issue entries: " + issueString + System.getProperty("line.separator"));
                fw.write("Non-matching list entries: " + badEntriesString + System.getProperty("line.separator"));
            }
            else {
                throw new RuntimeException("Can't create log file " + outputLogFile.getAbsolutePath());
            }
            int resultCount = st.executeUpdate();
            if(resultCount == 0) {
                throw new RuntimeException("Log entry couldn't be inserted to the database for some reason.");
            }
            fw.write("Log entry inserted." + System.lineSeparator());
        }
        catch(Exception e) {
            System.out.println(e.getMessage());
            throw new RuntimeException("Problem inserting log entry into database: " + e.getMessage());
        }
        finally {
            System.out.println("In finally block...");
            try {
                con.close();  //NPE happens here
            }
            catch(java.sql.SQLException sqle) {             
                sqle.printStackTrace();
            }
        }       
    }
    
    private void loadProps() {
        java.util.Properties props = null;
        try{
            File dir = new File(AccuityComparison.class.getProtectionDomain().getCodeSource().getLocation().
                    getPath());
            
            java.io.InputStream stream = new java.io.FileInputStream(
                    dir.getParentFile().getAbsolutePath() + File.separator + "config.properties");
            props = new java.util.Properties();
            props.load(stream);
            stream.close();
        }
        catch(java.io.FileNotFoundException fnfe) {
            fnfe.printStackTrace();
            try {
                fw.write(fnfe.getMessage());
                fw.close();
            }
            catch(java.io.IOException ioe) {
                ioe.printStackTrace();
            }
            throw new RuntimeException("Could not find properties file \"config.properties\": " +
                    fnfe.getMessage());
        }
        catch(java.io.IOException ioe) {
            ioe.printStackTrace();
            try {
                fw.write(ioe.getMessage());
                fw.close();
            }
            catch(java.io.IOException ioe2) {
                ioe2.printStackTrace();
            }
            throw new RuntimeException("Unable to read from properties file \"config.properties\": " +
                    ioe.getMessage());
        }
        logPreparedStatement = props.getProperty("logPreparedStatement");
        extractSummaryDir = props.getProperty("extractSummaryDir");
        archiveDir = props.getProperty("archiveDir");
        connectionString = props.getProperty("connectionString");
        jobCountQueryDelta = props.getProperty("jobCountQueryDelta");
        jobCountQueryFull = props.getProperty("jobCountQueryFull");
        dbEntryCountQueryFull = props.getProperty("dbEntryCountQueryFull");
        dbEntryCountQueryDelta = props.getProperty("dbEntryCountQueryDelta");
        dbEntriesQueryFull = props.getProperty("dbEntriesQueryFull");
        dbEntriesQueryDelta = props.getProperty("dbEntriesQueryDelta"); 
        dbConnStringPwd = new String(Base64.getDecoder().decode(props.getProperty("connectionStringPwd")), StandardCharsets.UTF_8);
        connectionString += dbConnStringPwd;
        System.out.println("Conn string = " + connectionString);
    };
    
    public void run(){
        Long start = System.currentTimeMillis();
        System.out.println("Starting...");
        try{
            fw = new java.io.FileWriter(outputLogFile);         
            fw.write("Thread starting..." + System.lineSeparator());
            loadProps();
            fullFile = new java.io.File(archiveDir + "Full_" + month + "-" + day + "-" + year + ".xml");
            deltaFile = new java.io.File(archiveDir + "Delta_" + month + "-" + day + "-" + year + ".xml");
            if(fullFile.exists()) {
                isFullPresent = true;
                type = "Full";
                populateSetFromListFile();
                runCount();
            }
            else {
                fw.write("Full file: " + fullFile + " not present." + System.lineSeparator());
                informational.add("Full list file not present.");
            }
            listSet.clear();
            if(deltaFile.exists()) {
                isDeltaPresent = true;
                type = "Delta";
                populateSetFromListFile();
                runCount();
            }       
            else {
                fw.write("Delta file: " + deltaFile + " not present." + System.lineSeparator());
                informational.add("Delta list file not present.");
            }                       
            String exceptionText = (!isJobRowCountMatch ? "There is a count mismatch between the list file (" + listSet.size() + ")" + 
                    " and the job row count in WLF_JOBS_log (" + jobRowCount + ").  " : "") + 
                    (!isExtractCountMatch ? " There is a mismatch between the list entries (" + listSet.size() + 
                        ") and the extract summary file count (" + extractCount + ").  ": "") +
                    (!isEntryCountMatch ? " There is a mistmatch between the filtered list entries (" + filteredListCount +  
                    ") and the database entry count in WLF_LATEST_LIST_ENTRIES (" + dbEntryCount + ").  " : "" + 
                    (badEntries.size() > 0 ? "One or more list entries does not seem to be fully intact." : ""));
            if(exceptionText.length() > 0 && (isDeltaPresent || isFullPresent))
                issues.add(exceptionText);
            logResults();                   
            fw.write("Program finished." + System.lineSeparator() + "Program executed in " + (System.currentTimeMillis() - start) + " milliseconds.");
            fw.close();
            if((isDeltaPresent || isFullPresent) && (!isJobRowCountMatch || !isExtractCountMatch || !isEntryCountMatch || (badEntries.size() > 0)))
                throw new RuntimeException(exceptionText);
        }
        catch(java.io.IOException ioe) {
            System.out.println(ioe.getMessage());
            ioe.printStackTrace();
            try {
                fw.write(ioe.getMessage());
                fw.close();
            }
            catch(java.io.IOException ioe2) {
                ioe2.printStackTrace();
            }
        }           
        System.out.println("Finished.");
    }   
}

想法?

java eclipse jar
1个回答
0
投票

希望这对将来的人有帮助。我删除了finally块,然后出现了异常:

Exception in thread "main" java.lang.UnsupportedClassVersionError: com/microsoft/sqlserver/jdbc/SQLServerDriver has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0

我忘记了由于我们的生产设备上的 Java 版本较低,我已经降级了 Eclipse 项目中的编译器合规版本。司机的奇怪行为当然让我摸不着头脑,直到移除最后一个块才明显。现在要使用 JRE8 版本的 MSSQL JDBC 驱动程序。

© www.soinside.com 2019 - 2024. All rights reserved.