尝试从 maven 运行 java 程序时出现异常

Posted

技术标签:

【中文标题】尝试从 maven 运行 java 程序时出现异常【英文标题】:Exception while trying to run java program from maven 【发布时间】:2016-02-01 14:25:29 【问题描述】:

我有一个连接到 mysql 数据库并从中读取数据的小型 Java 程序。我可以使用java -cp 成功运行它,但是当我尝试使用mvn exec:java 运行它时,程序完成后出现此异常:

[WARNING] thread Thread[MySQL Statement Cancellation Timer,5,com.mycompany.mydivision.App] was interrupted but is still alive after waiting at least 15000msecs
[WARNING] thread Thread[MySQL Statement Cancellation Timer,5,com.mycompany.mydivision.App] will linger despite being asked to die via interruption
[WARNING] NOTE: 1 thread(s) did not finish despite being asked to  via interruption. This is not a problem with exec:java, it is a problem with the running code. Although not serious, it should be remedied.
[WARNING] Couldn't destroy threadgroup org.codehaus.mojo.exec.ExecJavaMojo$IsolatedThreadGroup[name=com.mycompany.mydivision.App,maxpri=10]
java.lang.IllegalThreadStateException
    at java.lang.ThreadGroup.destroy(ThreadGroup.java:775)
    at org.codehaus.mojo.exec.ExecJavaMojo.execute(ExecJavaMojo.java:328)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:862)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:286)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:197)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)

为什么会发生这种情况,我该如何解决?这是我的代码,以备不时之需:

public class App 


    public static void main( String[] args )
    
        try (JdbcReader reader = new JdbcReader())
        
            reader.test();
        
        catch (SQLException ex) 
            // handle any errors
            System.out.println("SQLException: " + ex.getMessage());
            System.out.println("SQLState: " + ex.getSQLState());
            System.out.println("VendorError: " + ex.getErrorCode());
        
        catch (Exception e)
        
            e.printStackTrace();
        
    

package com.mycompany.mydivision;

import com.vividsolutions.jts.geom.Geometry;

import java.io.Closeable;
import java.io.InputStream;
import java.sql.*;

/**
 * 
 */
public class JdbcReader implements Closeable

    Connection conn;

    public JdbcReader() throws ClassNotFoundException, SQLException, IllegalAccessException, InstantiationException
    
        // The newInstance() call is a work around for some
        // broken Java implementations
        Class.forName("com.mysql.jdbc.Driver").newInstance();
        this.conn = DriverManager.getConnection("jdbc:mysql://localhost/mydb?user=guest");
    

    /**
     * https://dev.mysql.com/doc/connector-j/en/connector-j-usagenotes-statements.html
     */
    public void test() throws Exception
    
        Statement stmt = null;
        ResultSet rs = null;
        try 
            stmt = this.conn.createStatement();
            if (stmt.execute("SELECT * FROM mydb.my_table limit 20")) 
                rs = stmt.getResultSet();
                // Fetch each row from the result set
                while (rs.next()) 
                    String name = rs.getString("name");
                    String description = rs.getString("Descr");

                    System.out.printf("%s\t%s\n", name, description);
                
            
        
        finally 
            // it is a good idea to release
            // resources in a finally block
            // in reverse-order of their creation
            // if they are no-longer needed

            if (rs != null) 
                try 
                    System.out.println("closing ResultSet");
                    rs.close();
                 catch (SQLException sqlEx)   // ignore

                rs = null;
            

            if (stmt != null) 
                try 
                    System.out.println("closing Statement");
                    stmt.close();
                 catch (SQLException sqlEx)   // ignore

                stmt = null;
            
        
    

    public void close()
    
        if (conn != null)
        
            try 
                System.out.println("closing connection");
                conn.close();
            
            catch (SQLException ex)   // ignore
            conn = null;
        
    

【问题讨论】:

这是相关的,可能会有所帮助:***.com/questions/13471519/… 【参考方案1】:

在 exec maven 插件中试试这个

<configuration>
       <mainClass>com.test.Startup</mainClass>
       <cleanupDaemonThreads>false</cleanupDaemonThreads>
</configuration>

【讨论】:

感谢弗朗西斯科这确实有效!我没有将其添加到 pom.xml 中,而是将其添加到命令行中,如下所示: mvn exec:java -Dexec.mainClass="com.mycompany.mydivision.App" -Dexec.cleanupDaemonThreads=false 它可以工作,是的,但是 OP 在代码中哪里有守护线程?为什么这应该是必要的? @LEQADA 从堆栈跟踪/错误中可以看出,是 MySQL 库创建了守护线程来监视语句的执行。由于 Maven 调用该类,它会隐式创建这些守护线程。【参考方案2】:

我找到了一个稍微不同的解决方案。我有一个类似的错误,我猜更改 Maven 配置会修复它,但我想看看我是否可以先修复错误本身;)。事实证明,我只需要在我的 main 方法结束时调用 System.exit(status) 就可以解决问题。我猜 exec 插件需要显式调用 System.exit(在其他活动线程上类似)才能正常运行。

【讨论】:

我可以确认这一点。我们使用 System.exit(0) 和 main 的结尾。 我首先尝试使用 System.exit(0) 并没有用,而接受的答案却可以。 我也可以为我的项目确认这一点。【参考方案3】:

在程序的最后一行显式使用System.exit(0); 来解决这个问题。

【讨论】:

比接受的答案要好得多! 即使还有其他步骤要完成,它也会停止 maven 进程。 cleanupDaemonThreads 方法也适用于这种情况。

以上是关于尝试从 maven 运行 java 程序时出现异常的主要内容,如果未能解决你的问题,请参考以下文章

从 Java 运行 AppleScript 时出现“不允许辅助访问”错误

从命令行运行声纳分析时出现链接错误(maven 项目)

为 rmiregistry 实例化服务器类时出现运行时异常

尝试运行 JAR 文件时出现 NoClassDefFoundError [重复]

从 Mac OS X 10.6 64 位 macbook 运行时出现 CORBA 异常

尝试从 Apache Beam 中的选项获取值时出现空指针异常