This commit is contained in:
温少
2012-04-12 16:02:35 +08:00
13 changed files with 72 additions and 1516 deletions
+13 -19
View File
@@ -99,6 +99,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<encoding>UTF-8</encoding>
<source>1.6</source>
@@ -153,7 +154,7 @@
</links>
</configuration>
</plugin>
<!--
<plugin>
<artifactId>maven-gpg-plugin</artifactId>
<executions>
@@ -166,9 +167,11 @@
</execution>
</executions>
</plugin>
-->
</plugins>
</build>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
@@ -186,25 +189,10 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.ibatis</groupId>
<artifactId>ibatis-sqlmap</artifactId>
<version>2.3.4.726</version>
<scope>test</scope>
</dependency>
<!--
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
@@ -311,6 +299,12 @@
<version>0.7.1-rc2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jolbox</groupId>
<artifactId>bonecp-test-commons</artifactId>
<version>0.7.1-rc2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>proxool</groupId>
@@ -332,4 +326,4 @@
<scope>test</scope>
</dependency>
</dependencies>
</project>
</project>
@@ -714,14 +714,20 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
}
public JdbcSqlStat createSqlStat(StatementProxy statement, String sql) {
sql = mergeSql(sql);
return dataSourceStat.createSqlStat(sql);
}
public JdbcSqlStat getSqlCounter(String sql) {
sql = mergeSql(sql); //mergeSql
return getSqlStat(sql);
}
public JdbcSqlStat getSqlStat(String sql) {
sql = mergeSql(sql);
return dataSourceStat.getSqlStat(sql);
}
@@ -1,148 +0,0 @@
package com.alibaba.druid.pool.console;
import java.io.Console;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.ObjectName;
public class DruidConsole {
private ProxyClient proxy;
private Console console;
private PrintWriter out;
private List<DataSourceEntry> entries = new ArrayList<DataSourceEntry>();
private DruidConsole(){
console = System.console();
out = console.writer();
}
public void run() throws Exception {
proxy = ProxyClient.getProxyClient("10.20.133.134", 9006, null, null);
proxy.connect();
for (;;) {
String line = console.readLine();
if ("exit".equals(line)) {
break;
}
if ("ls".equals(line)) {
ls(line);
}
if ("desc".equals(line)) {
desc(line);
}
if (line.startsWith("show ")) {
show(line);
}
}
}
public void show(String line) throws Exception {
String[] items = line.split(" ");
DataSourceEntry current;
{
String arg = items[1];
int index = Integer.parseInt(arg);
current = entries.get(index);
}
long interval = 0;
{
String tmp = items[2];
interval = Long.parseLong(tmp);
}
String[] attributes = new String[] { "CreateCount", "DestroyCount", "ActivePeak", "ActiveCount", "PoolingCount", "CommitCount", "RollbackCount" };
String[] titles = attributes;
for (int i = 0; i < titles.length; ++i) {
if (i != 0) {
out.print("\t\t");
}
out.print(titles[i]);
}
out.println();
for (int i = 0; i < 10; ++i) {
AttributeList values = proxy.getAttributes(current.getObjectName(), attributes);
for (int j = 0; j < attributes.length; ++j) {
Attribute attribute = (Attribute) values.get(j);
if (j != 0) {
out.print("\t\t");
}
out.print(attribute.getValue());
}
out.println();
Thread.sleep(interval);
}
}
public void ls(String line) throws Exception {
entries.clear();
Map<ObjectName, MBeanInfo> beans = proxy.getMBeans(null);
for (Map.Entry<ObjectName, MBeanInfo> entry : beans.entrySet()) {
if ("com.alibaba.druid.pool.DruidDataSource".equals(entry.getValue().getClassName())) {
entries.add(new DataSourceEntry(entry.getKey(), entry.getValue()));
}
}
for (int i = 0; i < entries.size(); ++i) {
out.println(i + " : " + entries.get(i).getObjectName());
}
}
public void desc(String line) throws Exception {
String arg = line.substring("desc ".length());
int index = Integer.parseInt(arg);
DataSourceEntry current = entries.get(index);
MBeanInfo mbeanInfo = current.getMbeanInfo();
String[] attributes = new String[mbeanInfo.getAttributes().length];
for (int i = 0; i < attributes.length; ++i) {
MBeanAttributeInfo attr = mbeanInfo.getAttributes()[i];
attributes[i] = attr.getName();
}
AttributeList values = proxy.getAttributes(current.getObjectName(), attributes);
for (int i = 0; i < attributes.length; ++i) {
out.println("\t" + attributes[i] + " : " + values.get(i));
}
}
public static void main(String[] args) throws Exception {
DruidConsole console = new DruidConsole();
console.run();
}
static class DataSourceEntry {
private final ObjectName objectName;
private final MBeanInfo mbeanInfo;
public DataSourceEntry(ObjectName objectName, MBeanInfo mbeanInfo){
super();
this.objectName = objectName;
this.mbeanInfo = mbeanInfo;
}
public ObjectName getObjectName() {
return objectName;
}
public MBeanInfo getMbeanInfo() {
return mbeanInfo;
}
}
}
@@ -1,90 +0,0 @@
package com.alibaba.druid.pool.console;
import java.beans.PropertyChangeListener;
import javax.management.MBeanServerConnection;
/**
* {@code JConsoleContext} represents a JConsole connection to a target
* application.
* <p>
* {@code JConsoleContext} notifies any {@code PropertyChangeListeners}
* about the {@linkplain #CONNECTION_STATE_PROPERTY <i>ConnectionState</i>}
* property change to {@link ConnectionState#CONNECTED CONNECTED} and
* {@link ConnectionState#DISCONNECTED DISCONNECTED}.
* The {@code JConsoleContext} instance will be the source for
* any generated events.
* <p>
*
* @since 1.6
*/
public interface JConsoleContext {
/**
* The {@link ConnectionState ConnectionState} bound property name.
*/
public static String CONNECTION_STATE_PROPERTY = "connectionState";
/**
* Values for the {@linkplain #CONNECTION_STATE_PROPERTY
* <i>ConnectionState</i>} bound property.
*/
public enum ConnectionState {
/**
* The connection has been successfully established.
*/
CONNECTED,
/**
* No connection present.
*/
DISCONNECTED,
/**
* The connection is being attempted.
*/
CONNECTING
}
/**
* Returns the {@link MBeanServerConnection MBeanServerConnection} for the
* connection to an application. The returned
* {@code MBeanServerConnection} object becomes invalid when
* the connection state is changed to the
* {@link ConnectionState#DISCONNECTED DISCONNECTED} state.
*
* @return the {@code MBeanServerConnection} for the
* connection to an application.
*/
public MBeanServerConnection getMBeanServerConnection();
/**
* Returns the current connection state.
* @return the current connection state.
*/
public ConnectionState getConnectionState();
/**
* Add a {@link java.beans.PropertyChangeListener PropertyChangeListener}
* to the listener list.
* The listener is registered for all properties.
* The same listener object may be added more than once, and will be called
* as many times as it is added.
* If {@code listener} is {@code null}, no exception is thrown and
* no action is taken.
*
* @param listener The {@code PropertyChangeListener} to be added
*/
public void addPropertyChangeListener(PropertyChangeListener listener);
/**
* Removes a {@link java.beans.PropertyChangeListener PropertyChangeListener}
* from the listener list. This
* removes a {@code PropertyChangeListener} that was registered for all
* properties. If {@code listener} was added more than once to the same
* event source, it will be notified one less time after being removed. If
* {@code listener} is {@code null}, or was never added, no exception is
* thrown and no action is taken.
*
* @param listener the {@code PropertyChangeListener} to be removed
*/
public void removePropertyChangeListener(PropertyChangeListener listener);
}
@@ -1,252 +0,0 @@
package com.alibaba.druid.pool.console;
/*
* %W% %E%
*
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import sun.jvmstat.monitor.HostIdentifier;
import sun.jvmstat.monitor.MonitorException;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredVm;
import sun.jvmstat.monitor.MonitoredVmUtil;
import sun.jvmstat.monitor.VmIdentifier;
import sun.management.ConnectorAddressLink;
import com.sun.tools.attach.AgentInitializationException;
import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
@SuppressWarnings("restriction")
public class LocalVirtualMachine {
private String address;
private String commandLine;
private String displayName;
private int vmid;
private boolean isAttachSupported;
public LocalVirtualMachine(int vmid, String commandLine, boolean canAttach, String connectorAddress){
this.vmid = vmid;
this.commandLine = commandLine;
this.address = connectorAddress;
this.isAttachSupported = canAttach;
this.displayName = getDisplayName(commandLine);
}
private static String getDisplayName(String commandLine) {
// trim the pathname of jar file if it's a jar
String[] res = commandLine.split(" ", 2);
if (res[0].endsWith(".jar")) {
File jarfile = new File(res[0]);
String displayName = jarfile.getName();
if (res.length == 2) {
displayName += " " + res[1];
}
return displayName;
}
return commandLine;
}
public int vmid() {
return vmid;
}
public boolean isManageable() {
return (address != null);
}
public boolean isAttachable() {
return isAttachSupported;
}
public void startManagementAgent() throws IOException {
if (address != null) {
// already started
return;
}
if (!isAttachable()) {
throw new IOException("This virtual machine \"" + vmid + "\" does not support dynamic attach.");
}
loadManagementAgent();
// fails to load or start the management agent
if (address == null) {
// should never reach here
throw new IOException("Fails to find connector address");
}
}
public String connectorAddress() {
// return null if not available or no JMX agent
return address;
}
public String displayName() {
return displayName;
}
public String toString() {
return commandLine;
}
// This method returns the list of all virtual machines currently
// running on the machine
public static Map<Integer, LocalVirtualMachine> getAllVirtualMachines() {
Map<Integer, LocalVirtualMachine> map = new HashMap<Integer, LocalVirtualMachine>();
getMonitoredVMs(map);
getAttachableVMs(map);
return map;
}
private static void getMonitoredVMs(Map<Integer, LocalVirtualMachine> map) {
MonitoredHost host;
Set<?> vms;
try {
host = MonitoredHost.getMonitoredHost(new HostIdentifier((String) null));
vms = host.activeVms();
} catch (java.net.URISyntaxException sx) {
throw new InternalError(sx.getMessage());
} catch (MonitorException mx) {
throw new InternalError(mx.getMessage());
}
for (Object vmid : vms) {
if (vmid instanceof Integer) {
int pid = ((Integer) vmid).intValue();
String name = vmid.toString(); // default to pid if name not available
boolean attachable = false;
String address = null;
try {
MonitoredVm mvm = host.getMonitoredVm(new VmIdentifier(name));
// use the command line as the display name
name = MonitoredVmUtil.commandLine(mvm);
attachable = MonitoredVmUtil.isAttachable(mvm);
address = ConnectorAddressLink.importFrom(pid);
mvm.detach();
} catch (Exception x) {
// ignore
}
map.put((Integer) vmid, new LocalVirtualMachine(pid, name, attachable, address));
}
}
}
private static final String LOCAL_CONNECTOR_ADDRESS_PROP = "com.sun.management.jmxremote.localConnectorAddress";
private static void getAttachableVMs(Map<Integer, LocalVirtualMachine> map) {
List<VirtualMachineDescriptor> vms = VirtualMachine.list();
for (VirtualMachineDescriptor vmd : vms) {
try {
Integer vmid = Integer.valueOf(vmd.id());
if (!map.containsKey(vmid)) {
boolean attachable = false;
String address = null;
try {
VirtualMachine vm = VirtualMachine.attach(vmd);
attachable = true;
Properties agentProps = vm.getAgentProperties();
address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
vm.detach();
} catch (AttachNotSupportedException x) {
// not attachable
} catch (IOException x) {
// ignore
}
map.put(vmid, new LocalVirtualMachine(vmid.intValue(), vmd.displayName(), attachable, address));
}
} catch (NumberFormatException e) {
// do not support vmid different than pid
}
}
}
public static LocalVirtualMachine getLocalVirtualMachine(int vmid) {
Map<Integer, LocalVirtualMachine> map = getAllVirtualMachines();
LocalVirtualMachine lvm = map.get(vmid);
if (lvm == null) {
// Check if the VM is attachable but not included in the list
// if it's running with a different security context.
// For example, Windows services running
// local SYSTEM account are attachable if you have Adminstrator
// privileges.
boolean attachable = false;
String address = null;
String name = String.valueOf(vmid); // default display name to pid
try {
VirtualMachine vm = VirtualMachine.attach(name);
attachable = true;
Properties agentProps = vm.getAgentProperties();
address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
vm.detach();
lvm = new LocalVirtualMachine(vmid, name, attachable, address);
} catch (AttachNotSupportedException x) {
// not attachable
x.printStackTrace();
} catch (IOException x) {
// ignore
x.printStackTrace();
}
}
return lvm;
}
// load the management agent into the target VM
private void loadManagementAgent() throws IOException {
VirtualMachine vm = null;
String name = String.valueOf(vmid);
try {
vm = VirtualMachine.attach(name);
} catch (AttachNotSupportedException x) {
IOException ioe = new IOException(x.getMessage());
ioe.initCause(x);
throw ioe;
}
String home = vm.getSystemProperties().getProperty("java.home");
// Normally in ${java.home}/jre/lib/management-agent.jar but might
// be in ${java.home}/lib in build environments.
String agent = home + File.separator + "jre" + File.separator + "lib" + File.separator + "management-agent.jar";
File f = new File(agent);
if (!f.exists()) {
agent = home + File.separator + "lib" + File.separator + "management-agent.jar";
f = new File(agent);
if (!f.exists()) {
throw new IOException("Management agent not found");
}
}
agent = f.getCanonicalPath();
try {
vm.loadAgent(agent, "com.sun.management.jmxremote");
} catch (AgentLoadException x) {
IOException ioe = new IOException(x.getMessage());
ioe.initCause(x);
throw ioe;
} catch (AgentInitializationException x) {
IOException ioe = new IOException(x.getMessage());
ioe.initCause(x);
throw ioe;
}
// get the connector address
Properties agentProps = vm.getAgentProperties();
address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
vm.detach();
}
}
@@ -1,993 +0,0 @@
package com.alibaba.druid.pool.console;
/*
* %W% %E%
*
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
import static java.lang.management.ManagementFactory.CLASS_LOADING_MXBEAN_NAME;
import static java.lang.management.ManagementFactory.COMPILATION_MXBEAN_NAME;
import static java.lang.management.ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE;
import static java.lang.management.ManagementFactory.MEMORY_MXBEAN_NAME;
import static java.lang.management.ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME;
import static java.lang.management.ManagementFactory.RUNTIME_MXBEAN_NAME;
import static java.lang.management.ManagementFactory.THREAD_MXBEAN_NAME;
import static java.lang.management.ManagementFactory.newPlatformMXBeanProxy;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.lang.management.ClassLoadingMXBean;
import java.lang.management.CompilationMXBean;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RemoteObject;
import java.rmi.server.RemoteObjectInvocationHandler;
import java.rmi.server.RemoteRef;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.rmi.RMIConnector;
import javax.management.remote.rmi.RMIServer;
import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.swing.event.SwingPropertyChangeSupport;
import sun.rmi.server.UnicastRef2;
import sun.rmi.transport.LiveRef;
import com.sun.management.HotSpotDiagnosticMXBean;
@SuppressWarnings("restriction")
public class ProxyClient implements JConsoleContext {
private ConnectionState connectionState = ConnectionState.DISCONNECTED;
// The SwingPropertyChangeSupport will fire events on the EDT
private SwingPropertyChangeSupport propertyChangeSupport = new SwingPropertyChangeSupport(
this,
true);
private static Map<String, ProxyClient> cache = Collections.synchronizedMap(new HashMap<String, ProxyClient>());
private volatile boolean isDead = true;
private String hostName = null;
private int port = 0;
private String userName = null;
private String password = null;
private boolean hasPlatformMXBeans = false;
private boolean hasHotSpotDiagnosticMXBean = false;
private boolean hasCompilationMXBean = false;
private boolean supportsLockUsage = false;
// REVISIT: VMPanel and other places relying using getUrl().
// set only if it's created for local monitoring
private LocalVirtualMachine lvm;
// set only if it's created from a given URL via the Advanced tab
private String advancedUrl = null;
private JMXServiceURL jmxUrl = null;
private MBeanServerConnection mbsc = null;
private SnapshotMBeanServerConnection server = null;
private JMXConnector jmxc = null;
private RMIServer stub = null;
private static final SslRMIClientSocketFactory sslRMIClientSocketFactory = new SslRMIClientSocketFactory();
private String registryHostName = null;
private int registryPort = 0;
private boolean vmConnector = false;
private boolean sslRegistry = false;
private boolean sslStub = false;
final private String connectionName;
final private String displayName;
private ClassLoadingMXBean classLoadingMBean = null;
private CompilationMXBean compilationMBean = null;
private MemoryMXBean memoryMBean = null;
private OperatingSystemMXBean operatingSystemMBean = null;
private RuntimeMXBean runtimeMBean = null;
private ThreadMXBean threadMBean = null;
private com.sun.management.OperatingSystemMXBean sunOperatingSystemMXBean = null;
private HotSpotDiagnosticMXBean hotspotDiagnosticMXBean = null;
private List<GarbageCollectorMXBean> garbageCollectorMBeans = null;
final static private String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME = "com.sun.management:type=HotSpotDiagnostic";
private ProxyClient(String hostName, int port, String userName, String password) throws IOException{
this.connectionName = getConnectionName(hostName, port, userName);
this.displayName = connectionName;
if (hostName.equals("localhost") && port == 0) {
// Monitor self
this.hostName = hostName;
this.port = port;
} else {
// Create an RMI connector client and connect it to
// the RMI connector server
final String urlPath = "/jndi/rmi://" + hostName + ":" + port + "/jmxrmi";
JMXServiceURL url = new JMXServiceURL("rmi", "", 0, urlPath);
setParameters(url, userName, password);
vmConnector = true;
registryHostName = hostName;
registryPort = port;
checkSslConfig();
}
}
private ProxyClient(String url, String userName, String password) throws IOException{
this.advancedUrl = url;
this.connectionName = getConnectionName(url, userName);
this.displayName = connectionName;
setParameters(new JMXServiceURL(url), userName, password);
}
private ProxyClient(LocalVirtualMachine lvm) throws IOException{
this.lvm = lvm;
this.connectionName = getConnectionName(lvm);
this.displayName = "pid: " + lvm.vmid() + " " + lvm.displayName();
}
private void setParameters(JMXServiceURL url, String userName, String password) {
this.jmxUrl = url;
this.hostName = jmxUrl.getHost();
this.port = jmxUrl.getPort();
this.userName = userName;
this.password = password;
}
private static void checkStub(Remote stub, Class<? extends Remote> stubClass) {
// Check remote stub is from the expected class.
//
if (stub.getClass() != stubClass) {
if (!Proxy.isProxyClass(stub.getClass())) {
throw new SecurityException("Expecting a " + stubClass.getName() + " stub!");
} else {
InvocationHandler handler = Proxy.getInvocationHandler(stub);
if (handler.getClass() != RemoteObjectInvocationHandler.class) {
throw new SecurityException("Expecting a dynamic proxy instance with a "
+ RemoteObjectInvocationHandler.class.getName()
+ " invocation handler!");
} else {
stub = (Remote) handler;
}
}
}
// Check RemoteRef in stub is from the expected class
// "sun.rmi.server.UnicastRef2".
//
RemoteRef ref = ((RemoteObject) stub).getRef();
if (ref.getClass() != UnicastRef2.class) {
throw new SecurityException("Expecting a " + UnicastRef2.class.getName() + " remote reference in stub!");
}
// Check RMIClientSocketFactory in stub is from the expected class
// "javax.rmi.ssl.SslRMIClientSocketFactory".
//
LiveRef liveRef = ((UnicastRef2) ref).getLiveRef();
RMIClientSocketFactory csf = liveRef.getClientSocketFactory();
if (csf == null || csf.getClass() != SslRMIClientSocketFactory.class) {
throw new SecurityException("Expecting a " + SslRMIClientSocketFactory.class.getName()
+ " RMI client socket factory in stub!");
}
}
private static final String rmiServerImplStubClassName = "javax.management.remote.rmi.RMIServerImpl_Stub";
private static final Class<? extends Remote> rmiServerImplStubClass;
static {
// FIXME: RMIServerImpl_Stub is generated at build time
// after jconsole is built. We need to investigate if
// the Makefile can be fixed to build jconsole in the
// right order. As a workaround for now, we dynamically
// load RMIServerImpl_Stub class instead of statically
// referencing it.
Class<? extends Remote> serverStubClass = null;
try {
serverStubClass = Class.forName(rmiServerImplStubClassName).asSubclass(Remote.class);
} catch (ClassNotFoundException e) {
// should never reach here
throw (InternalError) new InternalError(e.getMessage()).initCause(e);
}
rmiServerImplStubClass = serverStubClass;
}
private void checkSslConfig() throws IOException {
// Get the reference to the RMI Registry and lookup RMIServer stub
//
Registry registry;
try {
registry = LocateRegistry.getRegistry(registryHostName, registryPort, sslRMIClientSocketFactory);
try {
stub = (RMIServer) registry.lookup("jmxrmi");
} catch (NotBoundException nbe) {
throw (IOException) new IOException(nbe.getMessage()).initCause(nbe);
}
sslRegistry = true;
} catch (IOException e) {
registry = LocateRegistry.getRegistry(registryHostName, registryPort);
try {
stub = (RMIServer) registry.lookup("jmxrmi");
} catch (NotBoundException nbe) {
throw (IOException) new IOException(nbe.getMessage()).initCause(nbe);
}
sslRegistry = false;
}
// Perform the checks for secure stub
//
try {
checkStub(stub, rmiServerImplStubClass);
sslStub = true;
} catch (SecurityException e) {
sslStub = false;
}
}
/**
* Returns true if the underlying RMI registry is SSL-protected.
*
* @exception UnsupportedOperationException If this {@code ProxyClient} does not denote a JMX connector for a JMX VM
* agent.
*/
public boolean isSslRmiRegistry() {
// Check for VM connector
//
if (!isVmConnector()) {
throw new UnsupportedOperationException("ProxyClient.isSslRmiRegistry() is only supported if this "
+ "ProxyClient is a JMX connector for a JMX VM agent");
}
return sslRegistry;
}
/**
* Returns true if the retrieved RMI stub is SSL-protected.
*
* @exception UnsupportedOperationException If this {@code ProxyClient} does not denote a JMX connector for a JMX VM
* agent.
*/
public boolean isSslRmiStub() {
// Check for VM connector
//
if (!isVmConnector()) {
throw new UnsupportedOperationException("ProxyClient.isSslRmiStub() is only supported if this "
+ "ProxyClient is a JMX connector for a JMX VM agent");
}
return sslStub;
}
/**
* Returns true if this {@code ProxyClient} denotes a JMX connector for a JMX VM agent.
*/
public boolean isVmConnector() {
return vmConnector;
}
private void setConnectionState(ConnectionState state) {
ConnectionState oldState = this.connectionState;
this.connectionState = state;
propertyChangeSupport.firePropertyChange(CONNECTION_STATE_PROPERTY, oldState, state);
}
public ConnectionState getConnectionState() {
return this.connectionState;
}
void flush() {
if (server != null) {
server.flush();
}
}
void connect() {
setConnectionState(ConnectionState.CONNECTING);
try {
tryConnect();
setConnectionState(ConnectionState.CONNECTED);
} catch (Exception e) {
e.printStackTrace();
setConnectionState(ConnectionState.DISCONNECTED);
}
}
private void tryConnect() throws IOException {
if (jmxUrl == null && "localhost".equals(hostName) && port == 0) {
// Monitor self
this.jmxc = null;
this.mbsc = ManagementFactory.getPlatformMBeanServer();
this.server = Snapshot.newSnapshot(mbsc);
} else {
// Monitor another process
if (lvm != null) {
if (!lvm.isManageable()) {
lvm.startManagementAgent();
if (!lvm.isManageable()) {
// FIXME: what to throw
throw new IOException(lvm + "not manageable");
}
}
if (this.jmxUrl == null) {
this.jmxUrl = new JMXServiceURL(lvm.connectorAddress());
}
}
// Need to pass in credentials ?
if (userName == null && password == null) {
if (isVmConnector()) {
// Check for SSL config on reconnection only
if (stub == null) {
checkSslConfig();
}
this.jmxc = new RMIConnector(stub, null);
jmxc.connect();
} else {
this.jmxc = JMXConnectorFactory.connect(jmxUrl);
}
} else {
Map<String, String[]> env = new HashMap<String, String[]>();
env.put(JMXConnector.CREDENTIALS, new String[] { userName, password });
if (isVmConnector()) {
// Check for SSL config on reconnection only
if (stub == null) {
checkSslConfig();
}
this.jmxc = new RMIConnector(stub, null);
jmxc.connect(env);
} else {
this.jmxc = JMXConnectorFactory.connect(jmxUrl, env);
}
}
this.mbsc = jmxc.getMBeanServerConnection();
this.server = Snapshot.newSnapshot(mbsc);
}
this.isDead = false;
try {
ObjectName on = new ObjectName(THREAD_MXBEAN_NAME);
this.hasPlatformMXBeans = server.isRegistered(on);
this.hasHotSpotDiagnosticMXBean = server.isRegistered(new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME));
// check if it has 6.0 new APIs
if (this.hasPlatformMXBeans) {
MBeanOperationInfo[] mopis = server.getMBeanInfo(on).getOperations();
// look for findDeadlockedThreads operations;
for (MBeanOperationInfo op : mopis) {
if (op.getName().equals("findDeadlockedThreads")) {
this.supportsLockUsage = true;
break;
}
}
on = new ObjectName(COMPILATION_MXBEAN_NAME);
this.hasCompilationMXBean = server.isRegistered(on);
}
} catch (MalformedObjectNameException e) {
// should not reach here
throw new InternalError(e.getMessage());
} catch (IntrospectionException e) {
InternalError ie = new InternalError(e.getMessage());
ie.initCause(e);
throw ie;
} catch (InstanceNotFoundException e) {
InternalError ie = new InternalError(e.getMessage());
ie.initCause(e);
throw ie;
} catch (ReflectionException e) {
InternalError ie = new InternalError(e.getMessage());
ie.initCause(e);
throw ie;
}
if (hasPlatformMXBeans) {
// WORKAROUND for bug 5056632
// Check if the access role is correct by getting a RuntimeMXBean
getRuntimeMXBean();
}
}
/**
* Gets a proxy client for a given local virtual machine.
*/
public static ProxyClient getProxyClient(LocalVirtualMachine lvm) throws IOException {
final String key = getCacheKey(lvm);
ProxyClient proxyClient = cache.get(key);
if (proxyClient == null) {
proxyClient = new ProxyClient(lvm);
cache.put(key, proxyClient);
}
return proxyClient;
}
public static String getConnectionName(LocalVirtualMachine lvm) {
return Integer.toString(lvm.vmid());
}
private static String getCacheKey(LocalVirtualMachine lvm) {
return Integer.toString(lvm.vmid());
}
/**
* Gets a proxy client for a given JMXServiceURL.
*/
public static ProxyClient getProxyClient(String url, String userName, String password) throws IOException {
final String key = getCacheKey(url, userName, password);
ProxyClient proxyClient = cache.get(key);
if (proxyClient == null) {
proxyClient = new ProxyClient(url, userName, password);
cache.put(key, proxyClient);
}
return proxyClient;
}
public static String getConnectionName(String url, String userName) {
if (userName != null && userName.length() > 0) {
return userName + "@" + url;
} else {
return url;
}
}
private static String getCacheKey(String url, String userName, String password) {
return (url == null ? "" : url) + ":" + (userName == null ? "" : userName) + ":"
+ (password == null ? "" : password);
}
/**
* Gets a proxy client for a given "hostname:port".
*/
public static ProxyClient getProxyClient(String hostName, int port, String userName, String password)
throws IOException {
final String key = getCacheKey(hostName, port, userName, password);
ProxyClient proxyClient = cache.get(key);
if (proxyClient == null) {
proxyClient = new ProxyClient(hostName, port, userName, password);
cache.put(key, proxyClient);
}
return proxyClient;
}
public static String getConnectionName(String hostName, int port, String userName) {
String name = hostName + ":" + port;
if (userName != null && userName.length() > 0) {
return userName + "@" + name;
} else {
return name;
}
}
private static String getCacheKey(String hostName, int port, String userName, String password) {
return (hostName == null ? "" : hostName) + ":" + port + ":" + (userName == null ? "" : userName) + ":"
+ (password == null ? "" : password);
}
public String connectionName() {
return connectionName;
}
public String getDisplayName() {
return displayName;
}
public String toString() {
if (!isConnected()) {
return displayName + " (disconnected)";
} else {
return displayName;
}
}
public MBeanServerConnection getMBeanServerConnection() {
return mbsc;
}
public SnapshotMBeanServerConnection getSnapshotMBeanServerConnection() {
return server;
}
public String getUrl() {
return advancedUrl;
}
public String getHostName() {
return hostName;
}
public int getPort() {
return port;
}
public int getVmid() {
return (lvm != null) ? lvm.vmid() : 0;
}
public String getUserName() {
return userName;
}
public String getPassword() {
return password;
}
public void disconnect() {
// Reset remote stub
stub = null;
// Close MBeanServer connection
if (jmxc != null) {
try {
jmxc.close();
} catch (IOException e) {
// Ignore ???
}
}
// Reset platform MBean references
classLoadingMBean = null;
compilationMBean = null;
memoryMBean = null;
operatingSystemMBean = null;
runtimeMBean = null;
threadMBean = null;
sunOperatingSystemMXBean = null;
garbageCollectorMBeans = null;
// Set connection state to DISCONNECTED
if (!isDead) {
isDead = true;
setConnectionState(ConnectionState.DISCONNECTED);
}
}
/**
* Returns the list of domains in which any MBean is currently registered.
*/
public String[] getDomains() throws IOException {
return server.getDomains();
}
/**
* Returns a map of MBeans with ObjectName as the key and MBeanInfo value of a given domain. If domain is
* <tt>null</tt>, all MBeans are returned. If no MBean found, an empty map is returned.
*/
public Map<ObjectName, MBeanInfo> getMBeans(String domain) throws IOException {
ObjectName name = null;
if (domain != null) {
try {
name = new ObjectName(domain + ":*");
} catch (MalformedObjectNameException e) {
// should not reach here
assert (false);
}
}
Set<ObjectName> mbeans = server.queryNames(name, null);
Map<ObjectName, MBeanInfo> result = new HashMap<ObjectName, MBeanInfo>(mbeans.size());
Iterator<ObjectName> iterator = mbeans.iterator();
while (iterator.hasNext()) {
Object object = iterator.next();
if (object instanceof ObjectName) {
ObjectName o = (ObjectName) object;
try {
MBeanInfo info = server.getMBeanInfo(o);
result.put(o, info);
} catch (IntrospectionException e) {
// TODO: should log the error
} catch (InstanceNotFoundException e) {
// TODO: should log the error
} catch (ReflectionException e) {
// TODO: should log the error
}
}
}
return result;
}
/**
* Returns a list of attributes of a named MBean.
*/
public AttributeList getAttributes(ObjectName name, String[] attributes) throws IOException {
AttributeList list = null;
try {
list = server.getAttributes(name, attributes);
} catch (InstanceNotFoundException e) {
// TODO: A MBean may have been unregistered.
// need to set up listener to listen for MBeanServerNotification.
} catch (ReflectionException e) {
// TODO: should log the error
}
return list;
}
/**
* Set the value of a specific attribute of a named MBean.
*/
public void setAttribute(ObjectName name, Attribute attribute) throws InvalidAttributeValueException,
MBeanException, IOException {
try {
server.setAttribute(name, attribute);
} catch (InstanceNotFoundException e) {
// TODO: A MBean may have been unregistered.
} catch (AttributeNotFoundException e) {
assert (false);
} catch (ReflectionException e) {
// TODO: should log the error
}
}
/**
* Invokes an operation of a named MBean.
*
* @throws MBeanException Wraps an exception thrown by the MBean's invoked method.
*/
public Object invoke(ObjectName name, String operationName, Object[] params, String[] signature)
throws IOException,
MBeanException {
Object result = null;
try {
result = server.invoke(name, operationName, params, signature);
} catch (InstanceNotFoundException e) {
// TODO: A MBean may have been unregistered.
} catch (ReflectionException e) {
// TODO: should log the error
}
return result;
}
public synchronized ClassLoadingMXBean getClassLoadingMXBean() throws IOException {
if (hasPlatformMXBeans && classLoadingMBean == null) {
classLoadingMBean = newPlatformMXBeanProxy(server, CLASS_LOADING_MXBEAN_NAME, ClassLoadingMXBean.class);
}
return classLoadingMBean;
}
public synchronized CompilationMXBean getCompilationMXBean() throws IOException {
if (hasCompilationMXBean && compilationMBean == null) {
compilationMBean = newPlatformMXBeanProxy(server, COMPILATION_MXBEAN_NAME, CompilationMXBean.class);
}
return compilationMBean;
}
public synchronized Collection<GarbageCollectorMXBean> getGarbageCollectorMXBeans() throws IOException {
// TODO: How to deal with changes to the list??
if (garbageCollectorMBeans == null) {
ObjectName gcName = null;
try {
gcName = new ObjectName(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",*");
} catch (MalformedObjectNameException e) {
// should not reach here
assert (false);
}
Set<ObjectName> mbeans = server.queryNames(gcName, null);
if (mbeans != null) {
garbageCollectorMBeans = new ArrayList<GarbageCollectorMXBean>();
Iterator<ObjectName> iterator = mbeans.iterator();
while (iterator.hasNext()) {
ObjectName on = (ObjectName) iterator.next();
String name = GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",name=" + on.getKeyProperty("name");
GarbageCollectorMXBean mBean = newPlatformMXBeanProxy(server, name, GarbageCollectorMXBean.class);
garbageCollectorMBeans.add(mBean);
}
}
}
return garbageCollectorMBeans;
}
public synchronized MemoryMXBean getMemoryMXBean() throws IOException {
if (hasPlatformMXBeans && memoryMBean == null) {
memoryMBean = newPlatformMXBeanProxy(server, MEMORY_MXBEAN_NAME, MemoryMXBean.class);
}
return memoryMBean;
}
public synchronized RuntimeMXBean getRuntimeMXBean() throws IOException {
if (hasPlatformMXBeans && runtimeMBean == null) {
runtimeMBean = newPlatformMXBeanProxy(server, RUNTIME_MXBEAN_NAME, RuntimeMXBean.class);
}
return runtimeMBean;
}
public synchronized ThreadMXBean getThreadMXBean() throws IOException {
if (hasPlatformMXBeans && threadMBean == null) {
threadMBean = newPlatformMXBeanProxy(server, THREAD_MXBEAN_NAME, ThreadMXBean.class);
}
return threadMBean;
}
public synchronized OperatingSystemMXBean getOperatingSystemMXBean() throws IOException {
if (hasPlatformMXBeans && operatingSystemMBean == null) {
operatingSystemMBean = newPlatformMXBeanProxy(server, OPERATING_SYSTEM_MXBEAN_NAME,
OperatingSystemMXBean.class);
}
return operatingSystemMBean;
}
public synchronized com.sun.management.OperatingSystemMXBean getSunOperatingSystemMXBean() throws IOException {
try {
ObjectName on = new ObjectName(OPERATING_SYSTEM_MXBEAN_NAME);
if (sunOperatingSystemMXBean == null) {
if (server.isInstanceOf(on, "com.sun.management.OperatingSystemMXBean")) {
sunOperatingSystemMXBean = newPlatformMXBeanProxy(server, OPERATING_SYSTEM_MXBEAN_NAME,
com.sun.management.OperatingSystemMXBean.class);
}
}
} catch (InstanceNotFoundException e) {
return null;
} catch (MalformedObjectNameException e) {
return null; // should never reach here
}
return sunOperatingSystemMXBean;
}
public synchronized HotSpotDiagnosticMXBean getHotSpotDiagnosticMXBean() throws IOException {
if (hasHotSpotDiagnosticMXBean && hotspotDiagnosticMXBean == null) {
hotspotDiagnosticMXBean = newPlatformMXBeanProxy(server, HOTSPOT_DIAGNOSTIC_MXBEAN_NAME,
HotSpotDiagnosticMXBean.class);
}
return hotspotDiagnosticMXBean;
}
public <T> T getMXBean(ObjectName objName, Class<T> interfaceClass) throws IOException {
return newPlatformMXBeanProxy(server, objName.toString(), interfaceClass);
}
// Return thread IDs of deadlocked threads or null if any.
// It finds deadlocks involving only monitors if it's a Tiger VM.
// Otherwise, it finds deadlocks involving both monitors and
// the concurrent locks.
public long[] findDeadlockedThreads() throws IOException {
ThreadMXBean tm = getThreadMXBean();
if (supportsLockUsage && tm.isSynchronizerUsageSupported()) {
return tm.findDeadlockedThreads();
} else {
return tm.findMonitorDeadlockedThreads();
}
}
public synchronized void markAsDead() {
disconnect();
}
public boolean isDead() {
return isDead;
}
boolean isConnected() {
return !isDead();
}
boolean hasPlatformMXBeans() {
return this.hasPlatformMXBeans;
}
boolean hasHotSpotDiagnosticMXBean() {
return this.hasHotSpotDiagnosticMXBean;
}
boolean isLockUsageSupported() {
return supportsLockUsage;
}
public boolean isRegistered(ObjectName name) throws IOException {
return server.isRegistered(name);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
public void addWeakPropertyChangeListener(PropertyChangeListener listener) {
if (!(listener instanceof WeakPCL)) {
listener = new WeakPCL(listener);
}
propertyChangeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
if (!(listener instanceof WeakPCL)) {
// Search for the WeakPCL holding this listener (if any)
for (PropertyChangeListener pcl : propertyChangeSupport.getPropertyChangeListeners()) {
if (pcl instanceof WeakPCL && ((WeakPCL) pcl).get() == listener) {
listener = pcl;
break;
}
}
}
propertyChangeSupport.removePropertyChangeListener(listener);
}
/**
* The PropertyChangeListener is handled via a WeakReference so as not to pin down the listener.
*/
private class WeakPCL extends WeakReference<PropertyChangeListener> implements PropertyChangeListener {
WeakPCL(PropertyChangeListener referent){
super(referent);
}
public void propertyChange(PropertyChangeEvent pce) {
PropertyChangeListener pcl = get();
if (pcl == null) {
// The referent listener was GC'ed, we're no longer
// interested in PropertyChanges, remove the listener.
dispose();
} else {
pcl.propertyChange(pce);
}
}
private void dispose() {
removePropertyChangeListener(this);
}
}
//
// Snapshot MBeanServerConnection:
//
// This is an object that wraps an existing MBeanServerConnection and adds
// caching to it, as follows:
//
// - The first time an attribute is called in a given MBean, the result is
// cached. Every subsequent time getAttribute is called for that attribute
// the cached result is returned.
//
// - Before every call to VMPanel.update() or when the Refresh button in the
// Attributes table is pressed down the attributes cache is flushed. Then
// any subsequent call to getAttribute will retrieve all the values for
// the attributes that are known to the cache.
//
// - The attributes cache uses a learning approach and only the attributes
// that are in the cache will be retrieved between two subsequent updates.
//
public interface SnapshotMBeanServerConnection extends MBeanServerConnection {
/**
* Flush all cached values of attributes.
*/
public void flush();
}
public static class Snapshot {
private Snapshot(){
}
public static SnapshotMBeanServerConnection newSnapshot(MBeanServerConnection mbsc) {
final InvocationHandler ih = new SnapshotInvocationHandler(mbsc);
return (SnapshotMBeanServerConnection) Proxy.newProxyInstance(Snapshot.class.getClassLoader(),
new Class[] { SnapshotMBeanServerConnection.class },
ih);
}
}
static class SnapshotInvocationHandler implements InvocationHandler {
private final MBeanServerConnection conn;
private Map<ObjectName, NameValueMap> cachedValues = newMap();
private Map<ObjectName, Set<String>> cachedNames = newMap();
@SuppressWarnings("serial")
private static final class NameValueMap extends HashMap<String, Object> {
}
SnapshotInvocationHandler(MBeanServerConnection conn){
this.conn = conn;
}
synchronized void flush() {
cachedValues = newMap();
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
final String methodName = method.getName();
if (methodName.equals("getAttribute")) {
return getAttribute((ObjectName) args[0], (String) args[1]);
} else if (methodName.equals("getAttributes")) {
return getAttributes((ObjectName) args[0], (String[]) args[1]);
} else if (methodName.equals("flush")) {
flush();
return null;
} else {
try {
return method.invoke(conn, args);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
}
private Object getAttribute(ObjectName objName, String attrName) throws MBeanException,
InstanceNotFoundException,
AttributeNotFoundException,
ReflectionException, IOException {
final NameValueMap values = getCachedAttributes(objName, Collections.singleton(attrName));
Object value = values.get(attrName);
if (value != null || values.containsKey(attrName)) {
return value;
}
// Not in cache, presumably because it was omitted from the
// getAttributes result because of an exception. Following
// call will probably provoke the same exception.
return conn.getAttribute(objName, attrName);
}
private AttributeList getAttributes(ObjectName objName, String[] attrNames) throws InstanceNotFoundException,
ReflectionException, IOException {
final NameValueMap values = getCachedAttributes(objName, new TreeSet<String>(Arrays.asList(attrNames)));
final AttributeList list = new AttributeList();
for (String attrName : attrNames) {
final Object value = values.get(attrName);
if (value != null || values.containsKey(attrName)) {
list.add(new Attribute(attrName, value));
}
}
return list;
}
private synchronized NameValueMap getCachedAttributes(ObjectName objName, Set<String> attrNames)
throws InstanceNotFoundException,
ReflectionException,
IOException {
NameValueMap values = cachedValues.get(objName);
if (values != null && values.keySet().containsAll(attrNames)) {
return values;
}
attrNames = new TreeSet<String>(attrNames);
Set<String> oldNames = cachedNames.get(objName);
if (oldNames != null) {
attrNames.addAll(oldNames);
}
values = new NameValueMap();
final AttributeList attrs = conn.getAttributes(objName, attrNames.toArray(new String[attrNames.size()]));
for (Attribute attr : attrs.asList()) {
values.put(attr.getName(), attr.getValue());
}
cachedValues.put(objName, values);
cachedNames.put(objName, attrNames);
return values;
}
// See http://www.artima.com/weblogs/viewpost.jsp?thread=79394
private static <K, V> Map<K, V> newMap() {
return new HashMap<K, V>();
}
}
}
@@ -503,9 +503,11 @@ public class Lexer {
token = LITERAL_CHARS;
break;
} else {
System.arraycopy(buf, np + 1, sbuf, 0, sp);
hasSpecial = true;
putChar('\'');
if (!hasSpecial) {
System.arraycopy(buf, np + 1, sbuf, 0, sp);
hasSpecial = true;
}
putChar('\'');
continue;
}
}
@@ -34,18 +34,18 @@ public class ParameterizedOutputVisitorUtils {
public static SQLASTOutputVisitor createParameterizedOutputVisitor(Appendable out, String dbType) {
if (JdbcUtils.ORACLE.equals(dbType)) {
return new OracleParameterizedOutputVisitor();
return new OracleParameterizedOutputVisitor(out);
}
if (JdbcUtils.MYSQL.equals(dbType)) {
return new MySqlParameterizedOutputVisitor();
return new MySqlParameterizedOutputVisitor(out);
}
if (JdbcUtils.POSTGRESQL.equals(dbType)) {
return new PGParameterizedOutputVisitor();
return new PGParameterizedOutputVisitor(out);
}
return new ParameterizedOutputVisitor();
return new ParameterizedOutputVisitor(out);
}
public static boolean visit(SQLASTOutputVisitor v, SQLInListExpr x) {
@@ -16,6 +16,7 @@
package com.alibaba.druid.stat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -41,7 +42,7 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
private final JdbcResultSetStat resultSetStat = new JdbcResultSetStat();
private final JdbcStatementStat statementStat = new JdbcStatementStat();
private int maxSize = 1000 * 10;
private int maxSize = 1000 * 1;
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final LinkedHashMap<String, JdbcSqlStat> sqlStatMap = new LinkedHashMap<String, JdbcSqlStat>(
@@ -62,14 +63,21 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
connectionStat.reset();
statementStat.reset();
resultSetStat.reset();
lock.readLock().lock();
lock.writeLock().lock();
try {
for (JdbcSqlStat stat : sqlStatMap.values()) {
stat.reset();
}
Iterator<Map.Entry<String, JdbcSqlStat>> iter = sqlStatMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, JdbcSqlStat> entry = iter.next();
JdbcSqlStat stat = entry.getValue();
if (stat.getExecuteCount() == 0) {
iter.remove();
} else {
stat.reset();
}
}
} finally {
lock.readLock().unlock();
lock.writeLock().unlock();
}
for (JdbcConnectionStat.Entry connectionStat : connections.values()) {
@@ -1,5 +1,6 @@
druid.filters.default=com.alibaba.druid.filter.stat.StatFilter
druid.filters.stat=com.alibaba.druid.filter.stat.StatFilter
druid.filters.mergeStat=com.alibaba.druid.filter.stat.MergeStatFilter
druid.filters.counter=com.alibaba.druid.filter.stat.StatFilter
druid.filters.encoding=com.alibaba.druid.filter.encoding.EncodingConvertFilter
druid.filters.log4j=com.alibaba.druid.filter.logging.Log4jFilter
@@ -38,6 +38,7 @@ public class OracleSelectTest34 extends OracleTest {
OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
statemen.accept(visitor);
System.out.println("Tables : " + visitor.getTables());
System.out.println("fields : " + visitor.getColumns());
@@ -27,4 +27,6 @@ public class OracleTest extends TestCase {
}
System.out.println(text);
}
}
@@ -28,4 +28,29 @@ public class SQLLexerTest2 extends TestCase {
}
}
}
public void test_lexer2() throws Exception {
String sql = "SELECT substr('''a''bc',0,3) FROM dual";
Lexer lexer = new Lexer(sql);
for (;;) {
lexer.nextToken();
Token tok = lexer.token();
if (tok == Token.IDENTIFIER) {
System.out.println(tok.name() + "\t\t" + lexer.stringVal());
} else if (tok == Token.LITERAL_INT) {
System.out.println(tok.name() + "\t\t" + lexer.numberString());
} else if (tok == Token.LITERAL_CHARS) {
System.out.println(tok.name() + "\t\t" + lexer.stringVal());
}
else {
System.out.println(tok.name() + "\t\t\t" + tok.name);
}
if (tok == Token.EOF) {
break;
}
}
}
}