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

46

Try this in the exec maven plugin

<configuration>
       <mainClass>com.test.Startup</mainClass>
       <cleanupDaemonThreads>false</cleanupDaemonThreads>
</configuration>
Sign up to request clarification or add additional context in comments.

3 Comments

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
It works, yes, but where OP has daemon threads in the code? Why this should be necessary?
@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.
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 Comments

I can confirm this. We use System.exit(0) and the end of main.
I tried using System.exit(0) first and it didn't work, while the accepted answer did.
I can Confirm this for my project as well.
This works for me too.
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)
9

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

2 Comments

Far better answer than the accepted one !
It will stop the maven process even if there would be other steps to complete. The cleanupDaemonThreads method works in this case too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.