30

I have a small java program that connects to a mysql db and reads data from it. I am able to run it successfully using java -cp but when I try to run it using mvn exec:java I get this exception after the program has finished:

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

Why is this happening and how can I fix this? Here is my code in case it is needed:

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;
        }
    }
}
1

3 Answers 3

44

Try this in the exec maven plugin

<configuration>
       <mainClass>com.test.Startup</mainClass>
       <cleanupDaemonThreads>false</cleanupDaemonThreads>
</configuration>
3
  • 6
    thanks Francisco this does work! Instead of adding this to the pom.xml I added it to the command line like this: mvn exec:java -Dexec.mainClass="com.mycompany.mydivision.App" -Dexec.cleanupDaemonThreads=false
    – morpheus
    Commented Nov 1, 2015 at 18:06
  • 1
    It works, yes, but where OP has daemon threads in the code? Why this should be necessary?
    – LEQADA
    Commented Jul 20, 2020 at 2:15
  • 1
    @LEQADA You see from the stacktrace/errors that it is the MySQL libs that create the daemon threads to monitor the execution of statements. Since Maven invokes the class, it will implicitly create these daemon threads.
    – oligofren
    Commented Mar 8, 2021 at 8:53
13

I found a slightly different solution. I had a similar error and I'm guessing changing the Maven configuration would fix it, but I wanted to see if I could fix the error itself first ;). Turns out, all I needed was to call System.exit(status) at the end of my main method and that solved the problem. I guess the exec plugin needs an explicit call to System.exit (and similar on other active threads) to behave properly.

5
  • 4
    I can confirm this. We use System.exit(0) and the end of main.
    – karlihnos
    Commented Sep 6, 2017 at 7:43
  • I tried using System.exit(0) first and it didn't work, while the accepted answer did.
    – Raibaz
    Commented Apr 25, 2019 at 19:31
  • I can Confirm this for my project as well.
    – ssavva05
    Commented Sep 25, 2020 at 8:03
  • This works for me too.
    – White_King
    Commented Feb 10, 2022 at 6:29
  • According to the error message that I got, my four (daemon) threads "…did not finish despite being asked to via interruption." Since my daemon threads don't shut down when interrupted, this make sense. (This doesn't explain why System.exit(0) didn't work) Commented Jul 19, 2023 at 5:18
7

Use System.exit(0); explicitly in the last line of the program to solve this issue.

2
  • 1
    Far better answer than the accepted one ! Commented Mar 26, 2021 at 13:38
  • It will stop the maven process even if there would be other steps to complete. The cleanupDaemonThreads method works in this case too.
    – fillumina
    Commented Aug 27, 2021 at 19:30

Not the answer you're looking for? Browse other questions tagged or ask your own question.