diff --git a/pom.xml b/pom.xml
index e950290e56..9cf18e9825 100644
--- a/pom.xml
+++ b/pom.xml
@@ -170,6 +170,50 @@
+
+
+ default-profile
+
+ true
+
+ ${java.home}/../lib/jconsole.jar
+
+
+
+ ${java.home}/../lib/jconsole.jar
+
+
+
+
+ com.alibaba
+ jconsole
+ 1.6.0
+ system
+ ${jconsolejar}
+ true
+
+
+
+
+ mac-profile
+
+ false
+
+ ${java.home}/../Classes/jconsole.jar
+
+
+
+
+ com.alibaba
+ jconsole
+ 1.6.0
+ system
+ ${java.home}/../Classes/jconsole.jar
+
+
+
+
+
javax.servlet
diff --git a/src/main/java/com/alibaba/druid/filter/logging/LogFilter.java b/src/main/java/com/alibaba/druid/filter/logging/LogFilter.java
index 1562177d21..c5499fda17 100644
--- a/src/main/java/com/alibaba/druid/filter/logging/LogFilter.java
+++ b/src/main/java/com/alibaba/druid/filter/logging/LogFilter.java
@@ -21,6 +21,8 @@ import java.sql.Types;
import com.alibaba.druid.filter.FilterChain;
import com.alibaba.druid.filter.FilterEventAdapter;
+import com.alibaba.druid.pool.DruidDataSource;
+import com.alibaba.druid.pool.DruidPooledConnection;
import com.alibaba.druid.proxy.jdbc.CallableStatementProxy;
import com.alibaba.druid.proxy.jdbc.ConnectionProxy;
import com.alibaba.druid.proxy.jdbc.DataSourceProxy;
@@ -298,7 +300,7 @@ public abstract class LogFilter extends FilterEventAdapter implements LogFilterM
super.connection_commit(chain, connection);
if (connectionCommitAfterLogEnable && isConnectionLogEnabled()) {
- connectionLog("connect commited. id " + connection.getId());
+ connectionLog("connect committed. id " + connection.getId());
}
}
@@ -306,7 +308,7 @@ public abstract class LogFilter extends FilterEventAdapter implements LogFilterM
public void connection_setAutoCommit(FilterChain chain, ConnectionProxy connection, boolean autoCommit)
throws SQLException {
- connectionLog("connect setAutoComment " + autoCommit + ". id " + connection.getId());
+ connectionLog("connect setAutoCommit " + autoCommit + ". id " + connection.getId());
chain.connection_setAutoCommit(connection, autoCommit);
}
@@ -578,5 +580,34 @@ public abstract class LogFilter extends FilterEventAdapter implements LogFilterM
}
}
}
+
+ @Override
+ public void dataSource_releaseConnection(FilterChain chain, DruidPooledConnection conn) throws SQLException {
+ long connectionId = -1;
+
+ if (conn.getConnectionHolder() != null) {
+ ConnectionProxy connection = (ConnectionProxy) conn.getConnectionHolder().getConnection();
+ connectionId = connection.getId();
+ }
+
+ chain.dataSource_recycle(conn);
+
+ if (connectionCloseAfterLogEnable && isConnectionLogEnabled()) {
+ connectionLog("{conn-" + connectionId + "} pool-recycle");
+ }
+ }
+
+ @Override
+ public DruidPooledConnection dataSource_getConnection(FilterChain chain, DruidDataSource dataSource, long maxWaitMillis) throws SQLException {
+ DruidPooledConnection conn = chain.dataSource_connect(dataSource, maxWaitMillis);
+
+ ConnectionProxy connection = (ConnectionProxy) conn.getConnectionHolder().getConnection();
+
+ if (connectionConnectAfterLogEnable && isConnectionLogEnabled()) {
+ connectionLog("{conn-" + connection.getId() + "} pool-connect");
+ }
+
+ return conn;
+ }
}
diff --git a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java
index c475aa61a1..2ffd9e4e89 100644
--- a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java
+++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java
@@ -312,7 +312,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
@Override
protected void statementExecuteUpdateAfter(StatementProxy statement, String sql, int updateCount) {
- internalAfterStatementExecute(statement, updateCount);
+ internalAfterStatementExecute(statement, false, updateCount);
}
@Override
@@ -322,7 +322,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
@Override
protected void statementExecuteQueryAfter(StatementProxy statement, String sql, ResultSetProxy resultSet) {
- internalAfterStatementExecute(statement);
+ internalAfterStatementExecute(statement, true);
}
@Override
@@ -331,8 +331,8 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
}
@Override
- protected void statementExecuteAfter(StatementProxy statement, String sql, boolean result) {
- internalAfterStatementExecute(statement);
+ protected void statementExecuteAfter(StatementProxy statement, String sql, boolean firstResult) {
+ internalAfterStatementExecute(statement, firstResult);
}
@Override
@@ -341,7 +341,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
final int batchSize = statement.getBatchSqlList().size();
JdbcSqlStat sqlStat = statement.getSqlStat();
- if (sqlStat == null) {
+ if (sqlStat == null || sqlStat.isRemoved()) {
sqlStat = createSqlStat(statement, sql);
statement.setSqlStat(sqlStat);
}
@@ -356,7 +356,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
@Override
protected void statementExecuteBatchAfter(StatementProxy statement, int[] result) {
- internalAfterStatementExecute(statement, result);
+ internalAfterStatementExecute(statement, false, result);
}
@@ -380,7 +380,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
// //////////SQL
JdbcSqlStat sqlStat = statement.getSqlStat();
- if (sqlStat == null) {
+ if (sqlStat == null || sqlStat.isRemoved()) {
sqlStat = createSqlStat(statement, sql);
statement.setSqlStat(sqlStat);
}
@@ -406,7 +406,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
}
}
- private final void internalAfterStatementExecute(StatementProxy statement, int... updateCountArray) {
+ private final void internalAfterStatementExecute(StatementProxy statement, boolean firstResult, int... updateCountArray) {
final JdbcStatementStat.Entry entry = getStatementInfo(statement);
@@ -426,7 +426,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
}
sqlStat.decrementRunningCount();
- sqlStat.addExecuteTime(statement.getLastExecuteType(), nanoSpan);
+ sqlStat.addExecuteTime(statement.getLastExecuteType(), firstResult, nanoSpan);
statement.setLastExecuteTimeNano(nanoSpan);
if ((!statement.isFirstResultSet()) && statement.getLastExecuteType() == StatementExecuteType.Execute) {
try {
@@ -525,7 +525,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
if (sqlStat != null) {
sqlStat.error(error);
- sqlStat.addExecuteTime(statement.getLastExecuteType(), nanoSpan);
+ sqlStat.addExecuteTime(statement.getLastExecuteType(), statement.isFirstResultSet(), nanoSpan);
statement.setLastExecuteTimeNano(nanoSpan);
}
diff --git a/src/main/java/com/alibaba/druid/mock/MockDriver.java b/src/main/java/com/alibaba/druid/mock/MockDriver.java
index 7c3447d95c..c4e99d5061 100644
--- a/src/main/java/com/alibaba/druid/mock/MockDriver.java
+++ b/src/main/java/com/alibaba/druid/mock/MockDriver.java
@@ -235,12 +235,12 @@ public class MockDriver implements Driver, MockDriverMBean {
return true;
}
- protected ResultSet executeQuery(MockStatement stmt, String sql) throws SQLException {
+ public ResultSet executeQuery(MockStatementBase stmt, String sql) throws SQLException {
if (logExecuteQueryEnable && LOG.isDebugEnabled()) {
LOG.debug("executeQuery " + sql);
}
- MockConnection conn = stmt.getMockConnection();
+ MockConnection conn = stmt.getConnection();
long idleTimeMillis = System.currentTimeMillis() - conn.getLastActiveTimeMillis();
if (idleTimeMillis >= this.idleTimeCount) {
diff --git a/src/main/java/com/alibaba/druid/mock/MockPreparedStatement.java b/src/main/java/com/alibaba/druid/mock/MockPreparedStatement.java
index aac0e05575..ff69946319 100644
--- a/src/main/java/com/alibaba/druid/mock/MockPreparedStatement.java
+++ b/src/main/java/com/alibaba/druid/mock/MockPreparedStatement.java
@@ -21,7 +21,7 @@ import java.sql.SQLException;
import com.alibaba.druid.util.jdbc.PreparedStatementBase;
-public class MockPreparedStatement extends PreparedStatementBase implements PreparedStatement {
+public class MockPreparedStatement extends PreparedStatementBase implements MockStatementBase, PreparedStatement {
private final String sql;
diff --git a/src/main/java/com/alibaba/druid/mock/MockStatement.java b/src/main/java/com/alibaba/druid/mock/MockStatement.java
index 3ff6c4c592..6bbf5394d1 100644
--- a/src/main/java/com/alibaba/druid/mock/MockStatement.java
+++ b/src/main/java/com/alibaba/druid/mock/MockStatement.java
@@ -22,7 +22,7 @@ import java.sql.Statement;
import com.alibaba.druid.util.jdbc.StatementBase;
-public class MockStatement extends StatementBase implements Statement {
+public class MockStatement extends StatementBase implements MockStatementBase, Statement {
public final static String ERROR_SQL = "THROW ERROR";
@@ -46,7 +46,7 @@ public class MockStatement extends StatementBase implements Statement {
}
}
- public MockConnection getMockConnection() {
+ public MockConnection getConnection() {
return mockConnection;
}
diff --git a/src/main/java/com/alibaba/druid/mock/MockStatementBase.java b/src/main/java/com/alibaba/druid/mock/MockStatementBase.java
new file mode 100644
index 0000000000..93fa75f6e6
--- /dev/null
+++ b/src/main/java/com/alibaba/druid/mock/MockStatementBase.java
@@ -0,0 +1,9 @@
+package com.alibaba.druid.mock;
+
+import java.sql.SQLException;
+import java.sql.Statement;
+
+
+public interface MockStatementBase extends Statement {
+ MockConnection getConnection() throws SQLException;
+}
diff --git a/src/main/java/com/alibaba/druid/mock/handler/MockExecuteHandler.java b/src/main/java/com/alibaba/druid/mock/handler/MockExecuteHandler.java
index 2d225ea02a..ffd2f67345 100644
--- a/src/main/java/com/alibaba/druid/mock/handler/MockExecuteHandler.java
+++ b/src/main/java/com/alibaba/druid/mock/handler/MockExecuteHandler.java
@@ -3,9 +3,9 @@ package com.alibaba.druid.mock.handler;
import java.sql.ResultSet;
import java.sql.SQLException;
-import com.alibaba.druid.mock.MockStatement;
+import com.alibaba.druid.mock.MockStatementBase;
public interface MockExecuteHandler {
- ResultSet executeQuery(MockStatement statement, String sql) throws SQLException;
+ ResultSet executeQuery(MockStatementBase statement, String sql) throws SQLException;
}
diff --git a/src/main/java/com/alibaba/druid/mock/handler/MySqlMockExecuteHandlerImpl.java b/src/main/java/com/alibaba/druid/mock/handler/MySqlMockExecuteHandlerImpl.java
index 03d27b5121..14d348acf9 100644
--- a/src/main/java/com/alibaba/druid/mock/handler/MySqlMockExecuteHandlerImpl.java
+++ b/src/main/java/com/alibaba/druid/mock/handler/MySqlMockExecuteHandlerImpl.java
@@ -8,7 +8,7 @@ import java.util.List;
import com.alibaba.druid.mock.MockResultSet;
import com.alibaba.druid.mock.MockResultSetMetaData;
-import com.alibaba.druid.mock.MockStatement;
+import com.alibaba.druid.mock.MockStatementBase;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
@@ -35,7 +35,7 @@ import com.alibaba.druid.util.jdbc.ResultSetMetaDataBase.ColumnMetaData;
public class MySqlMockExecuteHandlerImpl implements MockExecuteHandler {
@Override
- public ResultSet executeQuery(MockStatement statement, String sql) throws SQLException {
+ public ResultSet executeQuery(MockStatementBase statement, String sql) throws SQLException {
SQLStatementParser parser = new MySqlStatementParser(sql);
List stmtList = parser.parseStatementList(); //
@@ -67,7 +67,7 @@ public class MySqlMockExecuteHandlerImpl implements MockExecuteHandler {
throw new SQLException("TODO");
}
- public ResultSet executeQuery(MockStatement statement, SQLSelectQueryBlock query) throws SQLException {
+ public ResultSet executeQuery(MockStatementBase statement, SQLSelectQueryBlock query) throws SQLException {
SQLTableSource from = query.getFrom();
if (from instanceof SQLExprTableSource) {
@@ -87,7 +87,7 @@ public class MySqlMockExecuteHandlerImpl implements MockExecuteHandler {
}
}
- public ResultSet showStatus(MockStatement statement) throws SQLException {
+ public ResultSet showStatus(MockStatementBase statement) throws SQLException {
MockResultSet rs = new MockResultSet(statement);
MockResultSetMetaData metaData = rs.getMockMetaData();
@@ -102,7 +102,7 @@ public class MySqlMockExecuteHandlerImpl implements MockExecuteHandler {
return rs;
}
- public ResultSet executeQueryFromDual(MockStatement statement, SQLSelectQueryBlock query) throws SQLException {
+ public ResultSet executeQueryFromDual(MockStatementBase statement, SQLSelectQueryBlock query) throws SQLException {
MockResultSet rs = new MockResultSet(statement);
MockResultSetMetaData metaData = rs.getMockMetaData();
diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java
index d83f8e8b9a..f29afaa9af 100644
--- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java
+++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java
@@ -72,7 +72,7 @@ import com.alibaba.druid.util.JdbcUtils;
*/
public class DruidDataSource extends DruidAbstractDataSource implements DruidDataSourceMBean, ManagedDataSource, Referenceable, Closeable, Cloneable, ConnectionPoolDataSource {
- private final static Log LOG = LogFactory.getLog(DruidDataSource.class);
+ public final static Log LOG = LogFactory.getLog(DruidDataSource.class);
private static final long serialVersionUID = 1L;
@@ -274,6 +274,26 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
if (this.driverClass != null) {
this.driverClass = driverClass.trim();
}
+
+ if (isTestOnBorrow() || isTestOnReturn() || isTestWhileIdle()) {
+ if (this.getValidationQuery() == null || this.getValidationQuery().length() == 0) {
+ String errorMessage = "";
+
+ if (isTestOnBorrow()) {
+ errorMessage += "testOnBorrow is true, ";
+ }
+
+ if (isTestOnReturn()) {
+ errorMessage += "testOnReturn is true, ";
+ }
+
+ if (isTestWhileIdle()) {
+ errorMessage += "testWhileIdle is true, ";
+ }
+
+ LOG.error(errorMessage + "validationQuery not set");
+ }
+ }
if (this.jdbcUrl != null) {
this.jdbcUrl = this.jdbcUrl.trim();
@@ -281,6 +301,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
if (jdbcUrl.startsWith(DruidDriver.DEFAULT_PREFIX)) {
DataSourceProxyConfig config = DruidDriver.parseConfig(jdbcUrl, null);
this.driverClass = config.getRawDriverClassName();
+
+ LOG.error("error url : '" + jdbcUrl + "', it should be : '" + config.getRawUrl() + "'");
+
this.jdbcUrl = config.getRawUrl();
if (this.name == null) {
this.name = config.getName();
@@ -343,6 +366,12 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} else if (realDriverClassName.equals("com.alibaba.druid.mock.MockDriver")) {
this.exceptionSorter = new MockExceptionSorter();
}
+
+ if (realDriverClassName.equals("com.mysql.jdbc.Driver")) {
+ if (this.isPoolPreparedStatements()) {
+ LOG.error("mysql should not use 'PoolPreparedStatements'");
+ }
+ }
dataSourceStat = new JdbcDataSourceStat(this.name, this.jdbcUrl, this.dbType);
diff --git a/src/main/java/com/alibaba/druid/pool/ha/MultiDataSourcePreparedStatement.java b/src/main/java/com/alibaba/druid/pool/ha/MultiDataSourcePreparedStatement.java
index 89c5e3a7bd..13b4995ba2 100644
--- a/src/main/java/com/alibaba/druid/pool/ha/MultiDataSourcePreparedStatement.java
+++ b/src/main/java/com/alibaba/druid/pool/ha/MultiDataSourcePreparedStatement.java
@@ -26,10 +26,11 @@ public class MultiDataSourcePreparedStatement extends PreparedStatementProxyImpl
FilterChain chain = createChain();
if (chain.getFilterSize() == 0) {
- return this.statement.execute();
+ firstResultSet = this.statement.execute();
+ } else {
+ firstResultSet = chain.preparedStatement_execute(this);
}
- firstResultSet = chain.preparedStatement_execute(this);
return firstResultSet;
}
diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/PreparedStatementProxyImpl.java b/src/main/java/com/alibaba/druid/proxy/jdbc/PreparedStatementProxyImpl.java
index 37b373e975..ad26d7b631 100644
--- a/src/main/java/com/alibaba/druid/proxy/jdbc/PreparedStatementProxyImpl.java
+++ b/src/main/java/com/alibaba/druid/proxy/jdbc/PreparedStatementProxyImpl.java
@@ -40,7 +40,6 @@ import java.util.Map;
import java.util.TreeMap;
import com.alibaba.druid.proxy.jdbc.JdbcParameter.TYPE;
-import com.alibaba.druid.stat.JdbcSqlStat;
/**
* @author wenshao
@@ -94,6 +93,7 @@ public class PreparedStatementProxyImpl extends StatementProxyImpl implements Pr
@Override
public ResultSet executeQuery() throws SQLException {
+ firstResultSet = true;
updateCount = null;
lastExecuteType = StatementExecuteType.ExecuteQuery;
return createChain().preparedStatement_executeQuery(this);
@@ -101,6 +101,7 @@ public class PreparedStatementProxyImpl extends StatementProxyImpl implements Pr
@Override
public int executeUpdate() throws SQLException {
+ firstResultSet = false;
lastExecuteType = StatementExecuteType.ExecuteUpdate;
updateCount = createChain().preparedStatement_executeUpdate(this);
return updateCount;
@@ -466,13 +467,4 @@ public class PreparedStatementProxyImpl extends StatementProxyImpl implements Pr
return super.unwrap(iface);
}
-
- public JdbcSqlStat getSqlStat() {
- if (sqlStat != null && sqlStat.isRemoved()) {
- JdbcSqlStat sqlStat = this.getConnectionProxy().getDirectDataSource().getDataSourceStat().createSqlStat(sql);
- sqlStat.setDbType(this.sqlStat.getDbType());
- this.sqlStat = sqlStat;
- }
- return sqlStat;
- }
}
diff --git a/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxyImpl.java b/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxyImpl.java
index 1908704e2d..4eeba26887 100644
--- a/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxyImpl.java
+++ b/src/main/java/com/alibaba/druid/proxy/jdbc/StatementProxyImpl.java
@@ -141,6 +141,7 @@ public class StatementProxyImpl extends WrapperProxyImpl implements StatementPro
@Override
public int[] executeBatch() throws SQLException {
+ firstResultSet = false;
lastExecuteType = StatementExecuteType.ExecuteBatch;
int[] updateCounts = createChain().statement_executeBatch(this);
@@ -153,6 +154,7 @@ public class StatementProxyImpl extends WrapperProxyImpl implements StatementPro
@Override
public ResultSet executeQuery(String sql) throws SQLException {
+ firstResultSet = true;
updateCount = null;
lastExecuteSql = sql;
lastExecuteType = StatementExecuteType.ExecuteQuery;
@@ -161,6 +163,7 @@ public class StatementProxyImpl extends WrapperProxyImpl implements StatementPro
@Override
public int executeUpdate(String sql) throws SQLException {
+ firstResultSet = false;
lastExecuteSql = sql;
lastExecuteType = StatementExecuteType.ExecuteUpdate;
updateCount = createChain().statement_executeUpdate(this, sql);
@@ -169,6 +172,7 @@ public class StatementProxyImpl extends WrapperProxyImpl implements StatementPro
@Override
public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+ firstResultSet = false;
lastExecuteSql = sql;
lastExecuteType = StatementExecuteType.ExecuteUpdate;
updateCount = createChain().statement_executeUpdate(this, sql, autoGeneratedKeys);
@@ -177,6 +181,7 @@ public class StatementProxyImpl extends WrapperProxyImpl implements StatementPro
@Override
public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
+ firstResultSet = false;
lastExecuteSql = sql;
lastExecuteType = StatementExecuteType.ExecuteUpdate;
updateCount = createChain().statement_executeUpdate(this, sql, columnIndexes);
@@ -185,6 +190,7 @@ public class StatementProxyImpl extends WrapperProxyImpl implements StatementPro
@Override
public int executeUpdate(String sql, String[] columnNames) throws SQLException {
+ firstResultSet = false;
lastExecuteSql = sql;
lastExecuteType = StatementExecuteType.ExecuteUpdate;
updateCount = createChain().statement_executeUpdate(this, sql, columnNames);
diff --git a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java
index fe6dd287f8..f48d4dbbdf 100644
--- a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java
+++ b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java
@@ -336,8 +336,8 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
return executeSuccessCount.get();
}
- public void addExecuteTime(StatementExecuteType executeType, long nanoSpan) {
- if (StatementExecuteType.ExecuteQuery != executeType) {
+ public void addExecuteTime(StatementExecuteType executeType, boolean firstResultSet, long nanoSpan) {
+ if (StatementExecuteType.ExecuteQuery != executeType && !firstResultSet) {
executeAndResultHoldTimeHistogram.record((nanoSpan) / 1000 / 1000);
}
addExecuteTime(nanoSpan);
diff --git a/src/main/java/com/alibaba/druid/support/jconsole/DruidDataSourcePanel.java b/src/main/java/com/alibaba/druid/support/jconsole/DruidDataSourcePanel.java
new file mode 100644
index 0000000000..d9d8345043
--- /dev/null
+++ b/src/main/java/com/alibaba/druid/support/jconsole/DruidDataSourcePanel.java
@@ -0,0 +1,7 @@
+package com.alibaba.druid.support.jconsole;
+
+public class DruidDataSourcePanel extends DruidPanel {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/src/main/java/com/alibaba/druid/support/jconsole/DruidDriverPanel.java b/src/main/java/com/alibaba/druid/support/jconsole/DruidDriverPanel.java
new file mode 100644
index 0000000000..81a2fc6685
--- /dev/null
+++ b/src/main/java/com/alibaba/druid/support/jconsole/DruidDriverPanel.java
@@ -0,0 +1,7 @@
+package com.alibaba.druid.support.jconsole;
+
+public class DruidDriverPanel extends DruidPanel {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/src/main/java/com/alibaba/druid/support/jconsole/DruidPanel.java b/src/main/java/com/alibaba/druid/support/jconsole/DruidPanel.java
new file mode 100644
index 0000000000..8f1b2e4bf3
--- /dev/null
+++ b/src/main/java/com/alibaba/druid/support/jconsole/DruidPanel.java
@@ -0,0 +1,21 @@
+package com.alibaba.druid.support.jconsole;
+
+import javax.management.MBeanServerConnection;
+import javax.swing.JPanel;
+
+import com.sun.tools.jconsole.JConsoleContext;
+
+public class DruidPanel extends JPanel {
+
+ private static final long serialVersionUID = 1L;
+
+ protected Object doInBackground(JConsoleContext context) throws Exception {
+ doInBackground(context.getMBeanServerConnection());
+
+ return null;
+ }
+
+ protected void doInBackground(MBeanServerConnection conn) throws Exception {
+ System.out.println("doInBackground");
+ }
+}
diff --git a/src/main/java/com/alibaba/druid/support/jconsole/DruidPlugin.java b/src/main/java/com/alibaba/druid/support/jconsole/DruidPlugin.java
new file mode 100644
index 0000000000..80b7f9e73d
--- /dev/null
+++ b/src/main/java/com/alibaba/druid/support/jconsole/DruidPlugin.java
@@ -0,0 +1,47 @@
+package com.alibaba.druid.support.jconsole;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import javax.swing.JPanel;
+import javax.swing.SwingWorker;
+
+import com.sun.tools.jconsole.JConsolePlugin;
+
+public class DruidPlugin extends JConsolePlugin {
+
+ private final Map tabs = new LinkedHashMap();
+
+ public DruidPlugin(){
+ tabs.put("Druid-Driver", new DruidDriverPanel());
+ tabs.put("Druid-DataSource", new DruidDataSourcePanel());
+ tabs.put("Druid-SQL", new DruidSQLPanel());
+ }
+
+ @Override
+ public Map getTabs() {
+ return tabs;
+ }
+
+ @Override
+ public SwingWorker, ?> newSwingWorker() {
+ SwingWorker, ?> worer = new SwingWorker