In Visual Studio 2005 you may encounter this error when starting an ASP.NET 2.0 debugging session. Particularly you might encounter it if you are using the ASP.NET development server local web server running a local filesystem web site project.
Unable to attach. The binding handle is invalid.
Do you want to continue anyway?
Yes / No
To fix this error, go to Start Menu --> Administrative Tools --> Services
Select the Terminal Services service and make sure it is started.
I got this error because in my machine the Terminal services was disabled.
Tuesday, November 21, 2006
Thursday, November 16, 2006
huge file transfer over http (asp.net way)
/*
Here is a method which reads the contents of the file in chunks and sends it to the client. this way we avoid unnecessary reading of the full file into the memory
Courtesy: Microsoft website
*/
public void DownloadFile(HttpResponse response, string filepath)
{
System.IO.Stream iStream = null;
// Buffer to read 10K bytes in chunk:
byte[] buffer = new Byte[10000];
// Length of the file:
int length;
// Total bytes to read:
long dataToRead;
// Identify the file to download including its path.
// string filepath = "DownloadFileName";
// Identify the file name.
string filename = System.IO.Path.GetFileName(filepath);
try
{
// Open the file.
iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open,
System.IO.FileAccess.Read, System.IO.FileShare.Read);
// Total bytes to read:
dataToRead = iStream.Length;
response.ContentType = "application/octet-stream";
response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
// Read the bytes.
while (dataToRead > 0)
{
// Verify that the client is connected.
if (response.IsClientConnected)
{
// Read the data in buffer.
length = iStream.Read(buffer, 0, 10000);
// Write the data to the current output stream.
response.OutputStream.Write(buffer, 0, length);
// Flush the data to the HTML output.
response.Flush();
buffer = new Byte[10000];
dataToRead = dataToRead - length;
}
else
{
//prevent infinite loop if user disconnects
dataToRead = -1;
}
}
}
catch (Exception ex)
{
// Trap the error, if any.
response.Write("Error : " + ex.Message);
}
finally
{
if (iStream != null)
{
//Close the file.
iStream.Close();
}
}
/*
Other links related to this, may be useful for a reading.
http://www.odetocode.com/Articles/111.aspx
http://www.codecomments.com/archive290-2005-5-471328.html
http://www.ondotnet.com/pub/a/dotnet/2002/04/01/asp.html
http://www.yoda.arachsys.com/csharp/readbinary.html
http://msdn.microsoft.com/msdnmag/issues/05/11/BasicInstincts/
http://asp-net-whidbey.blogspot.com/
http://support.microsoft.com/kb/812406
http://www.eggheadcafe.com/articles/20011006.asp
*/
}
Here is a method which reads the contents of the file in chunks and sends it to the client. this way we avoid unnecessary reading of the full file into the memory
Courtesy: Microsoft website
*/
public void DownloadFile(HttpResponse response, string filepath)
{
System.IO.Stream iStream = null;
// Buffer to read 10K bytes in chunk:
byte[] buffer = new Byte[10000];
// Length of the file:
int length;
// Total bytes to read:
long dataToRead;
// Identify the file to download including its path.
// string filepath = "DownloadFileName";
// Identify the file name.
string filename = System.IO.Path.GetFileName(filepath);
try
{
// Open the file.
iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open,
System.IO.FileAccess.Read, System.IO.FileShare.Read);
// Total bytes to read:
dataToRead = iStream.Length;
response.ContentType = "application/octet-stream";
response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
// Read the bytes.
while (dataToRead > 0)
{
// Verify that the client is connected.
if (response.IsClientConnected)
{
// Read the data in buffer.
length = iStream.Read(buffer, 0, 10000);
// Write the data to the current output stream.
response.OutputStream.Write(buffer, 0, length);
// Flush the data to the HTML output.
response.Flush();
buffer = new Byte[10000];
dataToRead = dataToRead - length;
}
else
{
//prevent infinite loop if user disconnects
dataToRead = -1;
}
}
}
catch (Exception ex)
{
// Trap the error, if any.
response.Write("Error : " + ex.Message);
}
finally
{
if (iStream != null)
{
//Close the file.
iStream.Close();
}
}
/*
Other links related to this, may be useful for a reading.
http://www.odetocode.com/Articles/111.aspx
http://www.codecomments.com/archive290-2005-5-471328.html
http://www.ondotnet.com/pub/a/dotnet/2002/04/01/asp.html
http://www.yoda.arachsys.com/csharp/readbinary.html
http://msdn.microsoft.com/msdnmag/issues/05/11/BasicInstincts/
http://asp-net-whidbey.blogspot.com/
http://support.microsoft.com/kb/812406
http://www.eggheadcafe.com/articles/20011006.asp
*/
}
Wednesday, October 18, 2006
IIS Problem
When try to access an ASPX page on IIS, I got the following error yesterday. i spent few hours before finding a proper solution on this.
problem description (copied from net)
The XML page cannot be displayed
Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again later.
--------------------------------------------------------------------------------
A name was started with an invalid character. Error processing resource 'http://localhost/IssueTracker/Default.aspx'. Line...
<%@ Page Language="vb" AutoEventWireup="false" Inherits="ASPNET.StarterKit.IssueTracker._Default" CodeFile="Default.aspx">
Solution
register the dotnet framework again. be sure of the specific version.
you will be getting it in C:\Sysroot(it could be windows\system32) all the installed .net versions are listed out there. go the correct folder and execute the "aspnet_regiis -i" from command prompt. it worked for me.
C:\SYSROOT\Microsoft.NET\Framework\v2.0.50727
\aspnet_regiis -i
some other info on this blog
problem description (copied from net)
The XML page cannot be displayed
Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again later.
--------------------------------------------------------------------------------
A name was started with an invalid character. Error processing resource 'http://localhost/IssueTracker/Default.aspx'. Line...
<%@ Page Language="vb" AutoEventWireup="false" Inherits="ASPNET.StarterKit.IssueTracker._Default" CodeFile="Default.aspx">
Solution
register the dotnet framework again. be sure of the specific version.
you will be getting it in C:\Sysroot(it could be windows\system32) all the installed .net versions are listed out there. go the correct folder and execute the "aspnet_regiis -i" from command prompt. it worked for me.
C:\SYSROOT\Microsoft.NET\Framework\v2.0.50727
\aspnet_regiis -i
some other info on this blog
Friday, October 06, 2006
Java magic
Today a collegue of me was having problem in running a Hello.java program which prints plain hello on the console.
It was complaining time and again "NoSuchMethodError:main"...
we thought its problem with the JDK in that machine.
But actual culprit is my collegue only, what she did is that she wrote a Hello.java program with invalid main method (with no arguments) and placed it in JDK\bin directory. she compiled in that location itself so JDK\bin has the Hello.class file too.
Now she is trying to create Hello.java in a different directory and with proper main method. but she is getting the error.
When i gave java -verbose Hello
it is showing me that the class is loaded from JDK\bin, that was the mistake.
i removed the Hello.class file from JDK\bin and it is now referring the class file that is created in the current directory.
Summary
JVM gives preference to the JDK\bin directory for locating class files.
It was complaining time and again "NoSuchMethodError:main"...
we thought its problem with the JDK in that machine.
But actual culprit is my collegue only, what she did is that she wrote a Hello.java program with invalid main method (with no arguments) and placed it in JDK\bin directory. she compiled in that location itself so JDK\bin has the Hello.class file too.
Now she is trying to create Hello.java in a different directory and with proper main method. but she is getting the error.
When i gave java -verbose Hello
it is showing me that the class is loaded from JDK\bin, that was the mistake.
i removed the Hello.class file from JDK\bin and it is now referring the class file that is created in the current directory.
Summary
JVM gives preference to the JDK\bin directory for locating class files.
Wednesday, September 20, 2006
Log4j
Log4j is a nice logging solution for java developers.
http://www.vipan.com/htdocs/log4jhelp.html
http://rei1.m-plify.net/log4j/
http://www.onjava.com/pub/a/onjava/2002/08/07/log4j.html?page=2
http://www.vipan.com/htdocs/log4jhelp.html
http://rei1.m-plify.net/log4j/
http://www.onjava.com/pub/a/onjava/2002/08/07/log4j.html?page=2
Monday, September 11, 2006
downloading a web page using java code
U can use the following code to call the following methods and classes:
HttpURLConnection conn = getHttpURLConnectionUsingProxy(“http://www.google.com” "", "", "11.11.11.11", "80");
conn.connect();
InputStream xmlStream = null;
xmlStream = conn.getInputStream();
The code follows:
public HttpURLConnection getHttpURLConnectionUsingProxy(String urlstring, String username, String password, String proxyHost, String proxyPort){
String input = username + ":" + password;
String encoding = base64Encode(input);
// Enable the properties used for proxy support
System.getProperties().put("proxySet", "true" );
System.getProperties().put("proxyHost",proxyHost);
System.getProperties().put("proxyPort", proxyPort);
HttpURLConnection connection = null;
try{
URL url = new URL(urlstring);
connection = (HttpURLConnection)url.openConnection();
// Set up the connection so it knows you are sending
// proxy user information
connection.setRequestProperty( "Proxy-Authorization", encoding );
}catch(MalformedURLException murle){
System.out.println("MalformedURLException: " + murle.getMessage());
}catch(IOException ioe){
System.out.println("IOException: " + ioe.getMessage());
}
if (connection==null) System.out.println("Returning null connection");
return connection;
}
public String base64Encode(String s){
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
Base64OutputStream out = new Base64OutputStream(bOut);
try{
out.write(s.getBytes());
out.flush();
}catch (IOException exception){
}
return bOut.toString();
}
A separate class:
public class Base64OutputStream extends FilterOutputStream {
private int col = 0;
private int i = 0;
private int[] inbuf = new int[3];
public Base64OutputStream(OutputStream out){
super(out);
}
public void write(int c) throws IOException{
inbuf[i] = c;
i++;
if (i==3){
super.write(toBase64[(inbuf[0] & 0xFC) >> 2]);
super.write(toBase64[((inbuf[0] & 0x03) << 4) | ((inbuf[1] & 0xF0) >> 4)]);
super.write(toBase64[((inbuf[1] & 0x0F) << 2) | ((inbuf[2] & 0xC0) >> 6)]);
super.write(toBase64[inbuf[2] & 0x3F]);
col += 4;
i = 0;
if (col >= 76){
super.write('\n');
col = 0;
}
}
}
public void flush() throws IOException{
if (i==1){
super.write(toBase64[(inbuf[0] & 0xFC) >> 2]);
super.write(toBase64[(inbuf[0] & 0x03) << 4]);
super.write('=');
super.write('=');
}else if (i==2){
super.write(toBase64[(inbuf[0] & 0xFC) >> 2]);
super.write(toBase64[((inbuf[0] & 0x03) << 4) | ((inbuf[1] & 0xF0) >> 4)]);
super.write(toBase64[(inbuf[1] & 0x0F) << 2]);
super.write('=');
}
}
private char[] toBase64 = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
}
Thanks to chaya Infosys, chennai
HttpURLConnection conn = getHttpURLConnectionUsingProxy(“http://www.google.com” "
conn.connect();
InputStream xmlStream = null;
xmlStream = conn.getInputStream();
The code follows:
public HttpURLConnection getHttpURLConnectionUsingProxy(String urlstring, String username, String password, String proxyHost, String proxyPort){
String input = username + ":" + password;
String encoding = base64Encode(input);
// Enable the properties used for proxy support
System.getProperties().put("proxySet", "true" );
System.getProperties().put("proxyHost",proxyHost);
System.getProperties().put("proxyPort", proxyPort);
HttpURLConnection connection = null;
try{
URL url = new URL(urlstring);
connection = (HttpURLConnection)url.openConnection();
// Set up the connection so it knows you are sending
// proxy user information
connection.setRequestProperty( "Proxy-Authorization", encoding );
}catch(MalformedURLException murle){
System.out.println("MalformedURLException: " + murle.getMessage());
}catch(IOException ioe){
System.out.println("IOException: " + ioe.getMessage());
}
if (connection==null) System.out.println("Returning null connection");
return connection;
}
public String base64Encode(String s){
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
Base64OutputStream out = new Base64OutputStream(bOut);
try{
out.write(s.getBytes());
out.flush();
}catch (IOException exception){
}
return bOut.toString();
}
A separate class:
public class Base64OutputStream extends FilterOutputStream {
private int col = 0;
private int i = 0;
private int[] inbuf = new int[3];
public Base64OutputStream(OutputStream out){
super(out);
}
public void write(int c) throws IOException{
inbuf[i] = c;
i++;
if (i==3){
super.write(toBase64[(inbuf[0] & 0xFC) >> 2]);
super.write(toBase64[((inbuf[0] & 0x03) << 4) | ((inbuf[1] & 0xF0) >> 4)]);
super.write(toBase64[((inbuf[1] & 0x0F) << 2) | ((inbuf[2] & 0xC0) >> 6)]);
super.write(toBase64[inbuf[2] & 0x3F]);
col += 4;
i = 0;
if (col >= 76){
super.write('\n');
col = 0;
}
}
}
public void flush() throws IOException{
if (i==1){
super.write(toBase64[(inbuf[0] & 0xFC) >> 2]);
super.write(toBase64[(inbuf[0] & 0x03) << 4]);
super.write('=');
super.write('=');
}else if (i==2){
super.write(toBase64[(inbuf[0] & 0xFC) >> 2]);
super.write(toBase64[((inbuf[0] & 0x03) << 4) | ((inbuf[1] & 0xF0) >> 4)]);
super.write(toBase64[(inbuf[1] & 0x0F) << 2]);
super.write('=');
}
}
private char[] toBase64 = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
}
Thanks to chaya Infosys, chennai
Wednesday, June 14, 2006
Database Connection Pooling with Tomcat
Database Connection Pooling with Tomcat
by Kunal Jaggi
04/19/2006
Software object pooling is not a new concept. There are many scenarios where some type of object pooling technique is employed to improve application performance, concurrency, and scalability. After all, having your database code create a new Connection object on every client request is an expensive process. Moreover, with today's demanding applications, creating new connections for data access from scratch, maintaining them, and tearing down the open connection can lead to massive load on the server.
Connection pooling eliminates JDBC overhead. Further, object pooling also helps to reduce the garbage collection load. In this article, we'll look at an elegant way of creating a pool of open database-connection objects in Tomcat, so that they are handy whenever an application needs to access a DB resource.
With Database Connection Pooling (DBCP), we can scale our applications to handle increased load and deliver high performance benefits. Using recycled database connection objects cuts the time taken to re-instantiate and load frequently used objects, thus reducing unnecessary overheads. Configuring a DB pool can be a daunting task, because there has to be a way for different components within an application to know about the available pooled objects, and a mechanism to locate them. This is exactly where JNDI steps in, tying these dependencies together.
JNDI to the Rescue
The Java Naming and Directory Interface (JNDI) has been at the core of Java EE since its inception. JNDI offers a generic mechanism for Java EE components to find other components, resources, or services indirectly at runtime. The primary role of JNDI in a Java EE application is to provide an indirection layer, so that components can find required resources without being particularly aware of the indirection. This indirection is almost transparent. JNDI helps in holding applications together, but this coupling is very flexible, so that apps can be easily reassembled. JNDI spares you from providing direct references to the data source, JDBC driver class names, user names and passwords, or any vendor-specific quirks of setting up pooling. We just look up all of these dependencies at runtime through a JNDI call. The developer, on the other hand, is ignorant of the external resources.
Tomcat Configuration
Our approach to DBCP uses the Jakarta-Commons database connection pool. But first, we need to configure the JNDI DataSource in Tomcat by adding a declaration for the resource to server.xml file, which resides inside the /conf directory of your Tomcat installation (indicated by the environment variable CATALINA_HOME). The JNDI DataSource is used as a factory for connections. One of the major advantages of using a configuration like this is that the characteristics of the pool can be changed without affecting the application code. Our application's use of connection pooling is almost transparent. The following code snippet shows us how to configure the container to enable connection pooling.
reloadable="true" crossContext="true">
type="javax.sql.DataSource" removeAbandoned="true"
removeAbandonedTimeout="30" maxActive="100"
maxIdle="30" maxWait="10000" username="kunal"
password="java_facier"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost/dbcptest"/>
We can configure a maximum number of DB connections in the pool. Make sure you choose a maximum connection count large enough to handle all of your database connections--alternatively, you can set 0 for no limit. Further, we can set the maximum number of idle database connections to be retained in the pool. Set this value to -1 for no limit. The most optimal performance is attained when the pool in its steady state contains just enough connections to service all concurrent connection requests, without having to create new physical database connections at runtime. We can also specify the maximum time (in milliseconds) to wait for a database connection to become available, which in this example is 10 seconds. An exception is thrown if this timeout is exceeded. You can set this value to -1 to wait indefinitely. Please make sure your connector driver, such as mysql.jar, is placed inside the /common/lib directory of your Tomcat installation.
To achieve performance and high throughput, we also need to fine-tune the container to work under heavy traffic. Here's how we'll configure the Connector element for the maxProcessors and acceptCount parameters in the server.xml file:
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="150"
connectionTimeout="20000" disableUploadTimeout="true" />
Configuring JNDI Reference
In order for JNDI to resolve the reference, we have to insert a tag into the web.xml deployment descriptor file. We first begin by setting a tag for registering a ServletContextListener as shown below:
com.onjava.dbcp.DBCPoolingListener
DB Connection Pooling
jdbc/TestDB
javax.sql.DataSource
Container
EnrolledStudents
com.onjava.dbcp.CourseEnrollmentServlet
1
EnrolledStudents
/enrollment.do
This binding is vendor-specific, and every container has its own mechanism for setting data sources. Please note that this is just a declaration for dependency on an external resource, and doesn't create the actual resource. Comprehending the tags is pretty straightforward: this indicates to the container that the local reference name jdbc/TestDB should be set by the app deployer, and this should match with the resource name, as declared in server.xml file.
Putting DBCP into Action
As our application first starts asking the pool for Connection objects, they will be newly created, but when the application has finished with an object, it's returned to the pool rather than destroyed. This has huge performance benefits. Now, as the application needs more Connection objects, the pool will be able to issue recycled objects that have previously been returned by the application.
As an example, let's create a listener class to work with the pool. Our listener class implements the ServletContextListener interface; thus, it'll be initialized when the container starts and creates a ServletContext for this web app. Remember, there's only one ServletContext per web app. Any class implementing the ServletContextListener interface is initialized when the container starts. This early initialization cuts unnecessary overhead later, since it's ideal to have a cached set of open database connection objects available when the container starts rather than waiting for a client request. Inside the listener class, we'll do the necessary JNDI lookup and then set the DataSource as a ServletContext attribute so that it's available to the entire web app. The following code snippet shows us how to extract DataSource through a JNDI call:
public class DBCPoolingListener implements
ServletContextListener{
public void contextInitialized
(ServletContextEvent sce){
try {
// Obtain our environment naming context
Context envCtx = (Context) new InitialContext().
lookup("java:comp/env");
// Look up our data source
DataSource ds = (DataSource) envCtx.lookup
("jdbc/TestDB");
sce.getServletContext().setAttribute
("DBCPool", ds);
} catch(NamingException e){ e.printStackTrace();
}
}
public void contextDestroyed(ServletContextEvent
sce){
}
}
The component naming context is indicated by the prefix java:comp/env/.
For the sake of simplicity, we'll create a simple servlet, hard-coding the business logic and presentation. We'll use the JDBC 2.0 Standard Extension API, which specifies that a database service provider can implement a pooling technique that can allow multiple Connection objects to be shared among several requesting clients. Here's how we'll extract DataSource from the ServletContext attribute and then establish a Connection to pooled DB connection objects.
public void init() throws ServletException {
try {
//Create a datasource for pooled connections.
datasource = (DataSource) getServletContext().
getAttribute("DBCPool");
//Register the driver for non-pooled connections.
Class.forName("com.mysql.jdbc.Driver").
newInstance();
}
catch (Exception e) {
throw new ServletException(e.getMessage());
}
}
The servlet is written to use either pooled or non-pooled database connections, depending on the query string passed in its URL. The servlet fetches a pooled connection object using Tomcat DBCP, and non-pooled connections directly from MySQL connector.
Here's an example of obtaining a Connection object. If the pooledConnection flag is set, it simply calls getConnection() on the DataSource. If not, it manually creates a new Connection object:
private synchronized Connection getConnection
(boolean pooledConnection)
throws SQLException {
if (pooledConnection) {
pooledCount++;
// Allocate and use a connection from the pool
return datasource.getConnection();
}
else {
nonPooledCount++;
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost/dbcptest","kunal",
"java_facier");
return con; //return a newly created object
}
}
Having acquired a Connection, the servlet executes a simple join between the course and enrollment tables, and then formats and outputs the results as HTML. The example uses PreparedStatement to pre-compile SQL and run it repeatedly. This eliminates the tedious task of parsing and compiling the SQL query on every client request. Pre-compilation improves performance and offers enhanced security by preventing SQL injection attacks. For thread safety, we'll keep Connection, PreparedStatement, and ResultSet as local variables inside of the doGet() method.
Connections issued from the JNDI DataSource factory will be returned to the pool when closed. Clients use a connection pool by borrowing a connection object, using it, and then returning it to the pool by closing it. We have to make sure that after we are done with the Connection, we close it. If a Connection is not closed, it will never be returned to the pool and become available for reuse. Of course, that would tie up resources. The finally block guarantees that used ResultSet, PreparedStatement, and Connection objects are closed and prevents any connection pool leaks, as shown below:
finally {
try {if (rs != null) rs.close();} catch (SQLException e) {}
try {if (pstmt != null) pstmt.close();} catch (SQLException e) {}
try {if (connection != null) connection.close();} catch (SQLException e) {}
}
Performance Measurement
Before our application hits the ground running, we would like to stress test the app, evaluate its performance, and compare the results between the cached set of pooled connection objects and the non-pooling alternative. For this, we'll rely on JMeter, an open source tool for load testing with a drag-and-drop-style GUI. I have written a test plan for stress testing the web app. I have set up JMeter to stimulate 50 concurrent users, accessing a common servlet two times without any interval. The results are pretty apparent after looking at the JMeter graph results shown in Figures 1 and 2, below.
Figure 1. Pooled DB connections deviation (click for full-size image)
Figure 2. Non-pooled DB connections deviation (click for full-size image)
After several test runs, it turned out that connection pooling is at least four times faster than explicitly creating a DB connection object from the ground up. Admittedly, to get more accurate results, JMeter should run on a different machine. The ramp-up period, which describes the amount of time for creating the total number of threads, should be carefully chosen. It's not considered to be a good idea to set it to zero if you have a large number of threads, because that would create all of the threads at once and send out requests immediately. At the same time, a higher ramp-up period is also not appropriate, as it might underestimate the results.
Conclusion
Connection pooling is a technique used for sharing a cached set of open database connections among several requesting clients. It doesn't require you to modify your code significantly; rather, it provides enhanced performance benefits. Object pooling should be used with care. It does require additional overhead for such tasks as managing the state of the object pool, issuing objects to the application, and recycling used objects. Pooling is best suited for objects that have a short lifetime. If you are already working in a rich Java EE environment, then most likely you would be using an out-of-box connection pooling facility provided by your app server, and your applications' use of connection pooling is almost transparent.
Resources
http://www.onjava.com/pub/a/onjava/2006/04/19/database-connection-pooling-with-tomcat.html
• Example source code used in this article
Writing a custom session listener:
listener>
central.OurSessionListener
Here is my listener class:
package central;
import java.util.HashMap;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import wwxchange.utility.*;
import wwxchange.beans.*;
public class OurSessionListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent se) {
HttpSession session = se.getSession();
UserAcctBean user = (UserAcctBean) session.getAttribute("currentuser");
String loginID = user.getLoginID();
System.out.println("Added session: " + session.getId() + " for user " + user.getLoginID());
SystemControl.addActiveUser(session.getId(), user.getLoginID() );
}
public void sessionDestroyed(HttpSessionEvent se) {
HttpSession session = se.getSession();
SystemControl.removeActiveUser(session.getId());
System.out.println("Removed session: " + session.getId());
}
}
source: http://www.onjava.com/pub/a/onjava/2006/04/19/database-connection-pooling-with-tomcat.html?page=3
http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.ibm.db2.udb.apdv.java.doc/doc/t0010264.htm
by Kunal Jaggi
04/19/2006
Software object pooling is not a new concept. There are many scenarios where some type of object pooling technique is employed to improve application performance, concurrency, and scalability. After all, having your database code create a new Connection object on every client request is an expensive process. Moreover, with today's demanding applications, creating new connections for data access from scratch, maintaining them, and tearing down the open connection can lead to massive load on the server.
Connection pooling eliminates JDBC overhead. Further, object pooling also helps to reduce the garbage collection load. In this article, we'll look at an elegant way of creating a pool of open database-connection objects in Tomcat, so that they are handy whenever an application needs to access a DB resource.
With Database Connection Pooling (DBCP), we can scale our applications to handle increased load and deliver high performance benefits. Using recycled database connection objects cuts the time taken to re-instantiate and load frequently used objects, thus reducing unnecessary overheads. Configuring a DB pool can be a daunting task, because there has to be a way for different components within an application to know about the available pooled objects, and a mechanism to locate them. This is exactly where JNDI steps in, tying these dependencies together.
JNDI to the Rescue
The Java Naming and Directory Interface (JNDI) has been at the core of Java EE since its inception. JNDI offers a generic mechanism for Java EE components to find other components, resources, or services indirectly at runtime. The primary role of JNDI in a Java EE application is to provide an indirection layer, so that components can find required resources without being particularly aware of the indirection. This indirection is almost transparent. JNDI helps in holding applications together, but this coupling is very flexible, so that apps can be easily reassembled. JNDI spares you from providing direct references to the data source, JDBC driver class names, user names and passwords, or any vendor-specific quirks of setting up pooling. We just look up all of these dependencies at runtime through a JNDI call. The developer, on the other hand, is ignorant of the external resources.
Tomcat Configuration
Our approach to DBCP uses the Jakarta-Commons database connection pool. But first, we need to configure the JNDI DataSource in Tomcat by adding a declaration for the resource to server.xml file, which resides inside the /conf directory of your Tomcat installation (indicated by the environment variable CATALINA_HOME). The JNDI DataSource is used as a factory for connections. One of the major advantages of using a configuration like this is that the characteristics of the pool can be changed without affecting the application code. Our application's use of connection pooling is almost transparent. The following code snippet shows us how to configure the container to enable connection pooling.
removeAbandonedTimeout="30" maxActive="100"
maxIdle="30" maxWait="10000" username="kunal"
password="java_facier"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost/dbcptest"/>
We can configure a maximum number of DB connections in the pool. Make sure you choose a maximum connection count large enough to handle all of your database connections--alternatively, you can set 0 for no limit. Further, we can set the maximum number of idle database connections to be retained in the pool. Set this value to -1 for no limit. The most optimal performance is attained when the pool in its steady state contains just enough connections to service all concurrent connection requests, without having to create new physical database connections at runtime. We can also specify the maximum time (in milliseconds) to wait for a database connection to become available, which in this example is 10 seconds. An exception is thrown if this timeout is exceeded. You can set this value to -1 to wait indefinitely. Please make sure your connector driver, such as mysql.jar, is placed inside the /common/lib directory of your Tomcat installation.
To achieve performance and high throughput, we also need to fine-tune the container to work under heavy traffic. Here's how we'll configure the Connector element for the maxProcessors and acceptCount parameters in the server.xml file:
enableLookups="false" redirectPort="8443" acceptCount="150"
connectionTimeout="20000" disableUploadTimeout="true" />
Configuring JNDI Reference
In order for JNDI to resolve the reference, we have to insert a
This binding is vendor-specific, and every container has its own mechanism for setting data sources. Please note that this is just a declaration for dependency on an external resource, and doesn't create the actual resource. Comprehending the tags is pretty straightforward: this indicates to the container that the local reference name jdbc/TestDB should be set by the app deployer, and this should match with the resource name, as declared in server.xml file.
Putting DBCP into Action
As our application first starts asking the pool for Connection objects, they will be newly created, but when the application has finished with an object, it's returned to the pool rather than destroyed. This has huge performance benefits. Now, as the application needs more Connection objects, the pool will be able to issue recycled objects that have previously been returned by the application.
As an example, let's create a listener class to work with the pool. Our listener class implements the ServletContextListener interface; thus, it'll be initialized when the container starts and creates a ServletContext for this web app. Remember, there's only one ServletContext per web app. Any class implementing the ServletContextListener interface is initialized when the container starts. This early initialization cuts unnecessary overhead later, since it's ideal to have a cached set of open database connection objects available when the container starts rather than waiting for a client request. Inside the listener class, we'll do the necessary JNDI lookup and then set the DataSource as a ServletContext attribute so that it's available to the entire web app. The following code snippet shows us how to extract DataSource through a JNDI call:
public class DBCPoolingListener implements
ServletContextListener{
public void contextInitialized
(ServletContextEvent sce){
try {
// Obtain our environment naming context
Context envCtx = (Context) new InitialContext().
lookup("java:comp/env");
// Look up our data source
DataSource ds = (DataSource) envCtx.lookup
("jdbc/TestDB");
sce.getServletContext().setAttribute
("DBCPool", ds);
} catch(NamingException e){ e.printStackTrace();
}
}
public void contextDestroyed(ServletContextEvent
sce){
}
}
The component naming context is indicated by the prefix java:comp/env/.
For the sake of simplicity, we'll create a simple servlet, hard-coding the business logic and presentation. We'll use the JDBC 2.0 Standard Extension API, which specifies that a database service provider can implement a pooling technique that can allow multiple Connection objects to be shared among several requesting clients. Here's how we'll extract DataSource from the ServletContext attribute and then establish a Connection to pooled DB connection objects.
public void init() throws ServletException {
try {
//Create a datasource for pooled connections.
datasource = (DataSource) getServletContext().
getAttribute("DBCPool");
//Register the driver for non-pooled connections.
Class.forName("com.mysql.jdbc.Driver").
newInstance();
}
catch (Exception e) {
throw new ServletException(e.getMessage());
}
}
The servlet is written to use either pooled or non-pooled database connections, depending on the query string passed in its URL. The servlet fetches a pooled connection object using Tomcat DBCP, and non-pooled connections directly from MySQL connector.
Here's an example of obtaining a Connection object. If the pooledConnection flag is set, it simply calls getConnection() on the DataSource. If not, it manually creates a new Connection object:
private synchronized Connection getConnection
(boolean pooledConnection)
throws SQLException {
if (pooledConnection) {
pooledCount++;
// Allocate and use a connection from the pool
return datasource.getConnection();
}
else {
nonPooledCount++;
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost/dbcptest","kunal",
"java_facier");
return con; //return a newly created object
}
}
Having acquired a Connection, the servlet executes a simple join between the course and enrollment tables, and then formats and outputs the results as HTML. The example uses PreparedStatement to pre-compile SQL and run it repeatedly. This eliminates the tedious task of parsing and compiling the SQL query on every client request. Pre-compilation improves performance and offers enhanced security by preventing SQL injection attacks. For thread safety, we'll keep Connection, PreparedStatement, and ResultSet as local variables inside of the doGet() method.
Connections issued from the JNDI DataSource factory will be returned to the pool when closed. Clients use a connection pool by borrowing a connection object, using it, and then returning it to the pool by closing it. We have to make sure that after we are done with the Connection, we close it. If a Connection is not closed, it will never be returned to the pool and become available for reuse. Of course, that would tie up resources. The finally block guarantees that used ResultSet, PreparedStatement, and Connection objects are closed and prevents any connection pool leaks, as shown below:
finally {
try {if (rs != null) rs.close();} catch (SQLException e) {}
try {if (pstmt != null) pstmt.close();} catch (SQLException e) {}
try {if (connection != null) connection.close();} catch (SQLException e) {}
}
Performance Measurement
Before our application hits the ground running, we would like to stress test the app, evaluate its performance, and compare the results between the cached set of pooled connection objects and the non-pooling alternative. For this, we'll rely on JMeter, an open source tool for load testing with a drag-and-drop-style GUI. I have written a test plan for stress testing the web app. I have set up JMeter to stimulate 50 concurrent users, accessing a common servlet two times without any interval. The results are pretty apparent after looking at the JMeter graph results shown in Figures 1 and 2, below.
Figure 1. Pooled DB connections deviation (click for full-size image)
Figure 2. Non-pooled DB connections deviation (click for full-size image)
After several test runs, it turned out that connection pooling is at least four times faster than explicitly creating a DB connection object from the ground up. Admittedly, to get more accurate results, JMeter should run on a different machine. The ramp-up period, which describes the amount of time for creating the total number of threads, should be carefully chosen. It's not considered to be a good idea to set it to zero if you have a large number of threads, because that would create all of the threads at once and send out requests immediately. At the same time, a higher ramp-up period is also not appropriate, as it might underestimate the results.
Conclusion
Connection pooling is a technique used for sharing a cached set of open database connections among several requesting clients. It doesn't require you to modify your code significantly; rather, it provides enhanced performance benefits. Object pooling should be used with care. It does require additional overhead for such tasks as managing the state of the object pool, issuing objects to the application, and recycling used objects. Pooling is best suited for objects that have a short lifetime. If you are already working in a rich Java EE environment, then most likely you would be using an out-of-box connection pooling facility provided by your app server, and your applications' use of connection pooling is almost transparent.
Resources
http://www.onjava.com/pub/a/onjava/2006/04/19/database-connection-pooling-with-tomcat.html
• Example source code used in this article
Writing a custom session listener:
listener>
Here is my listener class:
package central;
import java.util.HashMap;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import wwxchange.utility.*;
import wwxchange.beans.*;
public class OurSessionListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent se) {
HttpSession session = se.getSession();
UserAcctBean user = (UserAcctBean) session.getAttribute("currentuser");
String loginID = user.getLoginID();
System.out.println("Added session: " + session.getId() + " for user " + user.getLoginID());
SystemControl.addActiveUser(session.getId(), user.getLoginID() );
}
public void sessionDestroyed(HttpSessionEvent se) {
HttpSession session = se.getSession();
SystemControl.removeActiveUser(session.getId());
System.out.println("Removed session: " + session.getId());
}
}
source: http://www.onjava.com/pub/a/onjava/2006/04/19/database-connection-pooling-with-tomcat.html?page=3
http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.ibm.db2.udb.apdv.java.doc/doc/t0010264.htm
Friday, March 31, 2006
Monday, March 27, 2006
Thursday, March 23, 2006
Data Mining
www.luigidragone.com/datamining/
http://www.helsinki.fi/~holler/datamining/algorithms.html
http://www.csc.liv.ac.uk/~frans/KDD/Software/Apriori-TFP/aprioriTFP.html
http://www.helsinki.fi/~holler/datamining/
http://www.helsinki.fi/~holler/datamining/algorithms.html
http://www.csc.liv.ac.uk/~frans/KDD/Software/Apriori-TFP/aprioriTFP.html
http://www.helsinki.fi/~holler/datamining/
Thursday, March 09, 2006
Tuesday, February 14, 2006
oracle top n query
http://www.devx.com/gethelpon/10MinuteSolution/16608/0/page/5
select * from
emp a
where 3 = (select count(distinct(sal)) from emp b
where b.sal >a.sal)
SELECT Empno, Ename, Job, Mgr, Hiredate, Sal
FROM
(SELECT Empno, Ename, Job, Mgr, Hiredate, Sal,
RANK() OVER
(ORDER BY SAL Desc NULLS LAST) AS Emp_Rank
FROM Emp
ORDER BY SAL Desc NULLS LAST)
WHERE Emp_Rank =2;
select * from
emp a
where 3 = (select count(distinct(sal)) from emp b
where b.sal >a.sal)
SELECT Empno, Ename, Job, Mgr, Hiredate, Sal
FROM
(SELECT Empno, Ename, Job, Mgr, Hiredate, Sal,
RANK() OVER
(ORDER BY SAL Desc NULLS LAST) AS Emp_Rank
FROM Emp
ORDER BY SAL Desc NULLS LAST)
WHERE Emp_Rank =2;
oracle top n query
select * from
emp a
where 3 = (select count(distinct(sal)) from emp b
where b.sal >a.sal)
SELECT Empno, Ename, Job, Mgr, Hiredate, Sal
FROM
(SELECT Empno, Ename, Job, Mgr, Hiredate, Sal,
RANK() OVER
(ORDER BY SAL Desc NULLS LAST) AS Emp_Rank
FROM Emp
ORDER BY SAL Desc NULLS LAST)
WHERE Emp_Rank =2;
emp a
where 3 = (select count(distinct(sal)) from emp b
where b.sal >a.sal)
SELECT Empno, Ename, Job, Mgr, Hiredate, Sal
FROM
(SELECT Empno, Ename, Job, Mgr, Hiredate, Sal,
RANK() OVER
(ORDER BY SAL Desc NULLS LAST) AS Emp_Rank
FROM Emp
ORDER BY SAL Desc NULLS LAST)
WHERE Emp_Rank =2;
Friday, February 10, 2006
VB and oracle
Links i Referred
http://www.orafaq.com/faqmsvb.htm
http://support.microsoft.com/default.aspx?scid=kb;en-us;300596&sd=tech
Create a System DSN in Windows XP
1. Click Start, point to Control Panel, double-click Administrative Tools, and then double-click Data Sources(ODBC).
2. Click the System DSN tab, and then click Add.
3. Click the database driver that corresponds with the database type to which you are connecting, and then click Finish.
4. Type the data source name. Make sure that you choose a name that you can remember. You will need to use this name later.
5. Click Select.
6. Click the correct database, and then click OK.
7. Click OK, and then click OK.
o Create a System DSN in Windows 2000
1. Click Start, point to Programs, point to Administrative Tools, and then double-click Data Sources (ODBC).
NOTE: In Windows 2000 Professional, click Start, point to Settings, click Control Panel, double-click Administrative Tools, and then double-click Data Sources (ODBC).
2. Click the System DSN tab.
3. Click Add.
4. Click the database driver that corresponds with the database type to which you are connecting, and then click Finish.
5. Type the data source name. Make sure to you a name that you will remember. You will need to use this name later.
6. Click Select.
7. Click the correct database, and then click OK.
8. Click OK in the next two dialog boxes.
ow does one connect to Oracle from VB?
Connectivity to Oracle is provided via ODBC or OO4O (Oracle Objects for OLE). For more information about ODBC, read the ODBC FAQ. For information about OO4O, read the OO4O FAQ. Look at this examples:
' DAO Example (Data Access Objects)
Dim wstemp As Workspace
Dim dbtemp As Database
Dim rstemp As Recordset
Set wstemp = DBEngine.Workspaces(0)
Set dbtemp = wstemp.OpenDatabase("", False, False, "ODBC;DSN=Oracle;USR=scott;PWD=tiger")
Set rstemp = dbtemp.OpenRecordset(myquery.Text, dbOpenDynaset, dbSQLPassThrough)
howmany = 0
Combo1.Clear
Do Until rstemp.EOF
msgbox rstemp(0)
rstemp.MoveNext
howmany = howmany + 1
Loop
' RDO Example (Remote Data Objects)
Dim contemp As New rdoConnection
Dim rstemp As rdoResultset
Dim envtemp As rdoEnvironment
Set envtemp = rdoEngine.rdoEnvironments(0)
envtemp.CursorDriver = rdUseServer
' or rdUseOdbc, rdUseNone, rdUseIfNeeded, rdUseClientBatch
With contemp
.Connect = "ODBC;DSN=Oracle;USR=scott;PWD=tiger"
.EstablishConnection rdDriverNoPrompt, false, rdoForwardOnly
' or rdoStatic, rdoKeyset, rdoDynamic
End With
Set rstemp = contemp.OpenResultset("select ...") ' Your SQL here
howmany = 0
With rstemp
Do Until .EOF Or howmany > 2000
msgbox .rdoColumns(0) ' Popup a message box showing the 1st column
.MoveNext
howmany = howmany + 1
Loop
ADO Example
Option Explicit
Public m_adoCnn As New ADODB.Connection
Public m_adoRst As New ADODB.Recordset
Public Sub Command1_Click()
m_adoCnn.ConnectionString = "Provider=MSDAORA;Password=tiger;User ID=scott;Data Source=database"
m_adoCnn.Open
End Sub
Private Sub Form_Unload(Cancel As Integer)
m_adoCnn.Close
End Sub
OO4O Example
Option Explicit
Dim m_oraSession As Object
Dim m_oraDatabase As Object
Private Sub Command1_Click()
Set m_oraSession = CreateObject("OracleInProcServer.XOraSession")
Set m_oraDatabase = m_oraSession.DBOpenDatabase("Database", "user/password", 0&)
MsgBox "Connected to " & m_oraDatabase.Connect & "@" & m_oraDatabase.DatabaseName
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set m_oraDatabase = Nothing
Set m_oraSession = Nothing
End Sub
# Back to top of file
Why is there only one record in my recordset?
When you do a recordcount and it return only one record in the recordset, while you know there are more records, you need to move to the last record before doing the count. Look at this example.
Dim rs As Recordset
rs.MoveLast
TxtNumRows.Text = rs.RecordCount
NOTE: Don't forget to do a rs.MoveFirst to get back to the first record again.
http://www.orafaq.com/faqmsvb.htm
http://support.microsoft.com/default.aspx?scid=kb;en-us;300596&sd=tech
Create a System DSN in Windows XP
1. Click Start, point to Control Panel, double-click Administrative Tools, and then double-click Data Sources(ODBC).
2. Click the System DSN tab, and then click Add.
3. Click the database driver that corresponds with the database type to which you are connecting, and then click Finish.
4. Type the data source name. Make sure that you choose a name that you can remember. You will need to use this name later.
5. Click Select.
6. Click the correct database, and then click OK.
7. Click OK, and then click OK.
o Create a System DSN in Windows 2000
1. Click Start, point to Programs, point to Administrative Tools, and then double-click Data Sources (ODBC).
NOTE: In Windows 2000 Professional, click Start, point to Settings, click Control Panel, double-click Administrative Tools, and then double-click Data Sources (ODBC).
2. Click the System DSN tab.
3. Click Add.
4. Click the database driver that corresponds with the database type to which you are connecting, and then click Finish.
5. Type the data source name. Make sure to you a name that you will remember. You will need to use this name later.
6. Click Select.
7. Click the correct database, and then click OK.
8. Click OK in the next two dialog boxes.
ow does one connect to Oracle from VB?
Connectivity to Oracle is provided via ODBC or OO4O (Oracle Objects for OLE). For more information about ODBC, read the ODBC FAQ. For information about OO4O, read the OO4O FAQ. Look at this examples:
' DAO Example (Data Access Objects)
Dim wstemp As Workspace
Dim dbtemp As Database
Dim rstemp As Recordset
Set wstemp = DBEngine.Workspaces(0)
Set dbtemp = wstemp.OpenDatabase("", False, False, "ODBC;DSN=Oracle;USR=scott;PWD=tiger")
Set rstemp = dbtemp.OpenRecordset(myquery.Text, dbOpenDynaset, dbSQLPassThrough)
howmany = 0
Combo1.Clear
Do Until rstemp.EOF
msgbox rstemp(0)
rstemp.MoveNext
howmany = howmany + 1
Loop
' RDO Example (Remote Data Objects)
Dim contemp As New rdoConnection
Dim rstemp As rdoResultset
Dim envtemp As rdoEnvironment
Set envtemp = rdoEngine.rdoEnvironments(0)
envtemp.CursorDriver = rdUseServer
' or rdUseOdbc, rdUseNone, rdUseIfNeeded, rdUseClientBatch
With contemp
.Connect = "ODBC;DSN=Oracle;USR=scott;PWD=tiger"
.EstablishConnection rdDriverNoPrompt, false, rdoForwardOnly
' or rdoStatic, rdoKeyset, rdoDynamic
End With
Set rstemp = contemp.OpenResultset("select ...") ' Your SQL here
howmany = 0
With rstemp
Do Until .EOF Or howmany > 2000
msgbox .rdoColumns(0) ' Popup a message box showing the 1st column
.MoveNext
howmany = howmany + 1
Loop
ADO Example
Option Explicit
Public m_adoCnn As New ADODB.Connection
Public m_adoRst As New ADODB.Recordset
Public Sub Command1_Click()
m_adoCnn.ConnectionString = "Provider=MSDAORA;Password=tiger;User ID=scott;Data Source=database"
m_adoCnn.Open
End Sub
Private Sub Form_Unload(Cancel As Integer)
m_adoCnn.Close
End Sub
OO4O Example
Option Explicit
Dim m_oraSession As Object
Dim m_oraDatabase As Object
Private Sub Command1_Click()
Set m_oraSession = CreateObject("OracleInProcServer.XOraSession")
Set m_oraDatabase = m_oraSession.DBOpenDatabase("Database", "user/password", 0&)
MsgBox "Connected to " & m_oraDatabase.Connect & "@" & m_oraDatabase.DatabaseName
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set m_oraDatabase = Nothing
Set m_oraSession = Nothing
End Sub
# Back to top of file
Why is there only one record in my recordset?
When you do a recordcount and it return only one record in the recordset, while you know there are more records, you need to move to the last record before doing the count. Look at this example.
Dim rs As Recordset
rs.MoveLast
TxtNumRows.Text = rs.RecordCount
NOTE: Don't forget to do a rs.MoveFirst to get back to the first record again.
Wednesday, February 08, 2006
P2P SSL authentication and JAVA with OpenSSL
This post contains some of my work about java and openssl.
Pre-requisites
install apache, mod_ssl(if it is not available with apache), openssl
configure openssl configuration file openssl.cnf
The Certificate Stuff:
there are 3 important options with openssl.
i.e, genrsa, req,ca
check the openssl help for all the detail input/output description.
creating key and self certified certificate
first create the key..
openssl genrsa -des3 -out ca.key 1024
then use the following command to create the CA certificate
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
now we generate key and certificate request key..
openssl genrsa -des3 -out server.key 1024
certificate request (CSR)
openssl req -new -key server.key -out server.csr
(generating key, request are done at client side and sent across to the CA for
certification)
Command to certify using our own CA.
openssl ca -in -out -keyfile -cert
example: openssl ca -in server.csr -out server.crt -keyfile ca.key -cert ca.crt
this way we can sign any reguest use openssl.cnf file to put certifying
criteria like city name should be or country name should
Now generating keystores so that our application can use SSL certificates for
secured communication.
use pkcs12 facility to export certificates to a pkcs12 store with a command
similar to the following..
for CA..
openssl pkcs12 -export -in cacert.pem -inkey cakey.pem -out ca.p12
for client
penssl pkcs12 -export -in client.crt -inkey client.key -out client.p12
NOTE:
keytool -list -keystore test.p12 -storetype PKCS12
keytool error: java.io.IOException: Set tag error
You could try to clean up your keystore. Execute commands:
openssl pkcs12 -in test.p12 -clcerts -out file.pem
openssl pkcs12 -export -in file.pem -out clean.p12
Using keystores
we need to put the ca keystore in trust store and the client certificate in keystore
in java it is just setting the system properties as shown in the following program and the magic works..
import java.io.IOException;
import java.io.PrintStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.io.*;
import java.net.*;
import java.util.*;
public class TestClient {
public TestClient(){
try{
java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
//System.setProperty("javax.net.debug", "all");
System.setProperty"java.protocol.handler.pkgs","com.sun.net.ssl.internal.www.protocol");
//System.setProperty("javax.net.ssl.trustStore", "truststore");
System.setProperty("javax.net.ssl.trustStore", "ca.p12");
System.setProperty("javax.net.ssl.trustStoreType", "pkcs12");
System.setProperty("javax.net.ssl.trustStorePassword","password");
System.out.println("after truststore setp");
System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
System.setProperty("javax.net.ssl.keyStore", "client.p12");
System.setProperty("javax.net.ssl.keyStorePassword", "password");
System.out.println("after keystore setting");
System.out.println("Sending XML with http ");
URL url = new URL("https://SERVER_USRL");
System.out.println("after url created");
//URLConnection uc = (URLConnection)url.openConnection();
//System.out.println("after connection establisht");
//uc.setDoOutput(true);
//uc.setDoInput(true);
//uc.setAllowUserInteraction(false);
//BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
//System.out.println("The instance of url.openConnection |" +url.openConnection()"|");
com.sun.net.ssl.HttpsURLConnection connection = (com.sun.net.ssl.HttpsURLConnection)url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
PrintWriter pw = new PrintWriter(new FileWriter("output.xml"));
String inputLine;
while ((inputLine = in.readLine()) != null)
pw.println(inputLine);
in.close();
pw.close();
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String arg[]){
System.out.println("before");
TestClient obj= new TestClient();
System.out.println("after");
}
}
General notes about OPENSSL
1)openssl uses openssl.cnf while creating certificate request as well as when we are certifying request with our own CA.
so this is a crucial one, we can change the default options like country name,
city, province etc., and while certifying also this configuration file is used to validate the client CSR file
openssl uses 2 text files while certifying requests.
serial
index.txt
serial will contain the certifiate serial number
intially it contains 01 and after that it will be incremented automatically for each request.
index.txt contains the created certificate information ( i think so) initially
it will contain nothing..
see that this file will have no content in the beginning
may be size should be 0 kb
this 2 things will create lot of errors if there is something wrong.
use online help for setting up openssl and to resolve errors generated during
creating .csr or .crt files..
http://tirian.magd.ox.ac.uk/~nick/openssl-certs/index.shtml
APACHE configuration:
apache needs mod_ssl module for dealing with SSL. Load this module and ssl.conf will be used to create virtualhosts with SSL configurations.
read apache documentation for various attribues in ssl.conf
sample virtualhost configuration in ssl.conf
ServerName testing.cybernetsoft.com
SSLEngine on
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
SSLCertificateFile /etc/httpd/conf/ssl.crt/server.crt
SSLCertificateKeyFile /etc/httpd/conf/ssl.key/server.key
SSLCertificateChainFile /etc/httpd/conf/ssl.crt/ca.crt
SSLCACertificateFile /etc/httpd/conf/ssl.crt/ca.crt
SSLCACertificatePath /etc/httpd/conf/ssl.crt
SSLVerifyDepth 1
HostnameLookups double
#SSLVerifyClient require
#SSLRequire (%(SSL_CLIENT_I_DN_CN) eq %(HTTP_HOST))
#SSLRequire (%(SSL_CLIENT_I_DN_O) eq "Cybernet Software Systems Inc")
# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"}
# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5
# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 )
#SLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/
# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd."
# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"}
# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5
# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 )
# or %{REMOTE_ADDR} =~ m/^11\.1\.14\.[0-9]+$/
CustomLog logs/ssl_request_log
"%t %h cn %{SSL_CLIENT_S_DN_CN}x remoteaddr %{REMOTE_ADDR}x remotehost %{REMOTE_HOST}x remoteident %{REMOTE_IDENT}x \"%r\" %b"
WebLogicHost 11.1.14.13
WebLogicPort 7001
StatPath true
HungServerRecoverSecs 300
ConnectTimeoutSecs 10
#SSLRequire (%{SSL_CLIENT_S_DN_CN} eq %{REMOTE_HOST})
#SSLRequire (%{SSL_CLIENT_VERIFY} eq "SUCCESS")
WebLogicHost 11.1.14.13
WebLogicPort 7001
SetHandler weblogic-handler
SETTING UP tomcat
Setting up Apache Tomcat and a Simple Apache SOAP Client for SSL Communication.
http://ws.apache.org/soap/docs/install/FAQ_Tomcat_SOAP_SSL.html
create key and sertificate from keytool for server.
keytool -genkey -alias tomcat-sv -dname "CN=harinath.cybernetsoft.com, OU=Java services team, O=Cybernet software systems, L=Chennai,
S=TN, C=IN" -keyalg RSA -keypass changeit -storepass changeit -keystore server.keystore
keytool -export -alias tomcat-cv -storepass changeit -file server.cer -keystore server.keystore
do the same thing for client the following steps worked fine for tomcat
CREATING KEYSTORE FOR TOMCAT:
1) keytool -genkey -alias tomcat-cl -dname "CN=harinath.cybernetsoft.com,OU=J2EE TEAM, O=CSS, L=CHENNAI, S=TN, C=IN" -keyalg RSA -keypass changeit -storepass changeit -keystore client.keystore
2)keytool -export -alias tomcat-cl -storepass changeit -file client.cer -keystore client.keystore
keytool -export -alias tomcat -storepass password -file c.crt -keystore client.keystore
3) and now change ur server.xml for ssl
enableLookups="true" disableUploadTimeout="true" acceptCount="100" debug="0" scheme="https" secure="true" keystoreFile="/usr/local/openssl/client.keystore"
clientAuth="false" keystorePass="changeit" sslProtocol="TLS"/>
Tomcat by default uses keystore named ".keystore" inside the home directory of
the user.
I think we can provide keystore and truststore and their passwords in connector itself.
Read the tomcat documentation of the version you are using.
LINKS:
http://www.flatmtn.com/computer/Linux-SSLCertificatesApache.html
installing CA Into IE
http://wasd.vsm.com.au/ht_root/other/faq/msie_ca_cert/
http://httpd.apache.org/docs-2.0/
http://www.impetus.us/~rjmooney/projects/misc/clientcertauth.html
http://www.samspublishing.com/articles/article.asp?p=30115&seqNum=11
http://tirian.magd.ox.ac.uk/~nick/openssl-certs/index.shtml
http://www.modssl.org/docs/2.8/ssl_reference.html#table3
http://httpd.apache.org/docs-2.0/mod/mod_ssl.html#sslrequiressl
http://www.samspublishing.com/articles/article.asp?p=30115&seqNum=5
http://www.impetus.us/~rjmooney/projects/misc/clientcertauth.html
sample config file openssl.cnf
http://paf.se/openssl/openssl.cnf.html
A very useful stuff.. on how to create certificates etc.. just a text file but
really useful.
http://rei1.m-plify.net/howtoon-certificates.txt
http://www.openssl.org/docs/apps/ca.html
http://www.drh-consultancy.demon.co.uk/pkcs12faq.html
http://search.netscape.com/ns/boomframe.jsp?query=installing+client+certificate+in+browser&page=1&offset=0&result_url=redir%3Fsrc%3Dwebsearch%26requestId%3Deab426fbf64c7db%26clickedItemRank%3D1%26userQuery%3Dinstalling%2Bclient%2Bcertificate%2Bin%2Bbrowser%26clickedItemURN%3Dhttp%253A%252F%252Fzeus.phys.uconn.edu%252Fprod%252Fdocs%252FcertSetup.html%26invocationType%3D-%26fromPage%3Ddshnnp%26amp%3BampTest%3D1&remove_url=http%3A%2F%2Fzeus.phys.uconn.edu%2Fprod%2Fdocs%2FcertSetup.html
http://www.cs.sunysb.edu/documentation/jsse/api_users_guide.html
http://java.sun.com/j2se/1.4.2/docs/api/javax/net/ssl/SSLSocketFactory.html
http://forum.java.sun.com/thread.jsp?forum=60&thread=204299
http://forum.java.sun.com/thread.jsp?forum=60&thread=525858
http://forum.java.sun.com/thread.jsp?forum=2&thread=258908
http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/samples/sockets/client/SSLSocketClientWithClientAuth.java
http://java.sun.com/products/jsse/doc/apidoc/com/sun/net/ssl/TrustManagerFactory.html
http://www.javaworld.com/javaworld/javatips/jw-javatip96.html
http://www.javaolympus.com/J2SE/NETWORKING/JavaSockets/JavaSockets.jsp
http://www-106.ibm.com/developerworks/java/library/ws-secmap/
http://java.sun.com/products/jsse/
The following helps in customization of JSSE like keymanager, trustmanger etc. and includes a sample server/clients application with SSL.
http://www-106.ibm.com/developerworks/java/library/j-customssl/
file:///usr/weblogic81/samples/server/examples/src/examples/security/sslclient/SSLClient.html
http://www-106.ibm.com/developerworks/java/library/j-customssl/
http://archives.java.sun.com/cgi-bin/wa?A2=ind0201&L=java-security&D=0&P=736
permissions in java
http://java.sun.com/j2se/1.4.2/docs/guide/security/permissions.html
http://mindprod.com/jgloss/certificate.html
Pre-requisites
install apache, mod_ssl(if it is not available with apache), openssl
configure openssl configuration file openssl.cnf
The Certificate Stuff:
there are 3 important options with openssl.
i.e, genrsa, req,ca
check the openssl help for all the detail input/output description.
creating key and self certified certificate
first create the key..
openssl genrsa -des3 -out ca.key 1024
then use the following command to create the CA certificate
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
now we generate key and certificate request key..
openssl genrsa -des3 -out server.key 1024
certificate request (CSR)
openssl req -new -key server.key -out server.csr
(generating key, request are done at client side and sent across to the CA for
certification)
Command to certify using our own CA.
openssl ca -in
example: openssl ca -in server.csr -out server.crt -keyfile ca.key -cert ca.crt
this way we can sign any reguest use openssl.cnf file to put certifying
criteria like city name should be
Now generating keystores so that our application can use SSL certificates for
secured communication.
use pkcs12 facility to export certificates to a pkcs12 store with a command
similar to the following..
for CA..
openssl pkcs12 -export -in cacert.pem -inkey cakey.pem -out ca.p12
for client
penssl pkcs12 -export -in client.crt -inkey client.key -out client.p12
NOTE:
keytool -list -keystore test.p12 -storetype PKCS12
keytool error: java.io.IOException: Set tag error
You could try to clean up your keystore. Execute commands:
openssl pkcs12 -in test.p12 -clcerts -out file.pem
openssl pkcs12 -export -in file.pem -out clean.p12
Using keystores
we need to put the ca keystore in trust store and the client certificate in keystore
in java it is just setting the system properties as shown in the following program and the magic works..
import java.io.IOException;
import java.io.PrintStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.io.*;
import java.net.*;
import java.util.*;
public class TestClient {
public TestClient(){
try{
java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
//System.setProperty("javax.net.debug", "all");
System.setProperty"java.protocol.handler.pkgs","com.sun.net.ssl.internal.www.protocol");
//System.setProperty("javax.net.ssl.trustStore", "truststore");
System.setProperty("javax.net.ssl.trustStore", "ca.p12");
System.setProperty("javax.net.ssl.trustStoreType", "pkcs12");
System.setProperty("javax.net.ssl.trustStorePassword","password");
System.out.println("after truststore setp");
System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
System.setProperty("javax.net.ssl.keyStore", "client.p12");
System.setProperty("javax.net.ssl.keyStorePassword", "password");
System.out.println("after keystore setting");
System.out.println("Sending XML with http ");
URL url = new URL("https://SERVER_USRL");
System.out.println("after url created");
//URLConnection uc = (URLConnection)url.openConnection();
//System.out.println("after connection establisht");
//uc.setDoOutput(true);
//uc.setDoInput(true);
//uc.setAllowUserInteraction(false);
//BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
//System.out.println("The instance of url.openConnection |" +url.openConnection()"|");
com.sun.net.ssl.HttpsURLConnection connection = (com.sun.net.ssl.HttpsURLConnection)url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
PrintWriter pw = new PrintWriter(new FileWriter("output.xml"));
String inputLine;
while ((inputLine = in.readLine()) != null)
pw.println(inputLine);
in.close();
pw.close();
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String arg[]){
System.out.println("before");
TestClient obj= new TestClient();
System.out.println("after");
}
}
General notes about OPENSSL
1)openssl uses openssl.cnf while creating certificate request as well as when we are certifying request with our own CA.
so this is a crucial one, we can change the default options like country name,
city, province etc., and while certifying also this configuration file is used to validate the client CSR file
openssl uses 2 text files while certifying requests.
serial
index.txt
serial will contain the certifiate serial number
intially it contains 01 and after that it will be incremented automatically for each request.
index.txt contains the created certificate information ( i think so) initially
it will contain nothing..
see that this file will have no content in the beginning
may be size should be 0 kb
this 2 things will create lot of errors if there is something wrong.
use online help for setting up openssl and to resolve errors generated during
creating .csr or .crt files..
http://tirian.magd.ox.ac.uk/~nick/openssl-certs/index.shtml
APACHE configuration:
apache needs mod_ssl module for dealing with SSL. Load this module and ssl.conf will be used to create virtualhosts with SSL configurations.
read apache documentation for various attribues in ssl.conf
sample virtualhost configuration in ssl.conf
ServerName testing.cybernetsoft.com
SSLEngine on
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
SSLCertificateFile /etc/httpd/conf/ssl.crt/server.crt
SSLCertificateKeyFile /etc/httpd/conf/ssl.key/server.key
SSLCertificateChainFile /etc/httpd/conf/ssl.crt/ca.crt
SSLCACertificateFile /etc/httpd/conf/ssl.crt/ca.crt
SSLCACertificatePath /etc/httpd/conf/ssl.crt
SSLVerifyDepth 1
HostnameLookups double
#SSLVerifyClient require
#SSLRequire (%(SSL_CLIENT_I_DN_CN) eq %(HTTP_HOST))
#SSLRequire (%(SSL_CLIENT_I_DN_O) eq "Cybernet Software Systems Inc")
# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"}
# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5
# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 )
#SLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/
# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd."
# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"}
# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5
# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 )
# or %{REMOTE_ADDR} =~ m/^11\.1\.14\.[0-9]+$/
CustomLog logs/ssl_request_log
"%t %h cn %{SSL_CLIENT_S_DN_CN}x remoteaddr %{REMOTE_ADDR}x remotehost %{REMOTE_HOST}x remoteident %{REMOTE_IDENT}x \"%r\" %b"
WebLogicHost 11.1.14.13
WebLogicPort 7001
StatPath true
HungServerRecoverSecs 300
ConnectTimeoutSecs 10
#SSLRequire (%{SSL_CLIENT_S_DN_CN} eq %{REMOTE_HOST})
#SSLRequire (%{SSL_CLIENT_VERIFY} eq "SUCCESS")
WebLogicHost 11.1.14.13
WebLogicPort 7001
SetHandler weblogic-handler
SETTING UP tomcat
Setting up Apache Tomcat and a Simple Apache SOAP Client for SSL Communication.
http://ws.apache.org/soap/docs/install/FAQ_Tomcat_SOAP_SSL.html
create key and sertificate from keytool for server.
keytool -genkey -alias tomcat-sv -dname "CN=harinath.cybernetsoft.com, OU=Java services team, O=Cybernet software systems, L=Chennai,
S=TN, C=IN" -keyalg RSA -keypass changeit -storepass changeit -keystore server.keystore
keytool -export -alias tomcat-cv -storepass changeit -file server.cer -keystore server.keystore
do the same thing for client the following steps worked fine for tomcat
CREATING KEYSTORE FOR TOMCAT:
1) keytool -genkey -alias tomcat-cl -dname "CN=harinath.cybernetsoft.com,OU=J2EE TEAM, O=CSS, L=CHENNAI, S=TN, C=IN" -keyalg RSA -keypass changeit -storepass changeit -keystore client.keystore
2)keytool -export -alias tomcat-cl -storepass changeit -file client.cer -keystore client.keystore
keytool -export -alias tomcat -storepass password -file c.crt -keystore client.keystore
3) and now change ur server.xml for ssl
clientAuth="false" keystorePass="changeit" sslProtocol="TLS"/>
Tomcat by default uses keystore named ".keystore" inside the home directory of
the user.
I think we can provide keystore and truststore and their passwords in connector itself.
Read the tomcat documentation of the version you are using.
LINKS:
http://www.flatmtn.com/computer/Linux-SSLCertificatesApache.html
installing CA Into IE
http://wasd.vsm.com.au/ht_root/other/faq/msie_ca_cert/
http://httpd.apache.org/docs-2.0/
http://www.impetus.us/~rjmooney/projects/misc/clientcertauth.html
http://www.samspublishing.com/articles/article.asp?p=30115&seqNum=11
http://tirian.magd.ox.ac.uk/~nick/openssl-certs/index.shtml
http://www.modssl.org/docs/2.8/ssl_reference.html#table3
http://httpd.apache.org/docs-2.0/mod/mod_ssl.html#sslrequiressl
http://www.samspublishing.com/articles/article.asp?p=30115&seqNum=5
http://www.impetus.us/~rjmooney/projects/misc/clientcertauth.html
sample config file openssl.cnf
http://paf.se/openssl/openssl.cnf.html
A very useful stuff.. on how to create certificates etc.. just a text file but
really useful.
http://rei1.m-plify.net/howtoon-certificates.txt
http://www.openssl.org/docs/apps/ca.html
http://www.drh-consultancy.demon.co.uk/pkcs12faq.html
http://search.netscape.com/ns/boomframe.jsp?query=installing+client+certificate+in+browser&page=1&offset=0&result_url=redir%3Fsrc%3Dwebsearch%26requestId%3Deab426fbf64c7db%26clickedItemRank%3D1%26userQuery%3Dinstalling%2Bclient%2Bcertificate%2Bin%2Bbrowser%26clickedItemURN%3Dhttp%253A%252F%252Fzeus.phys.uconn.edu%252Fprod%252Fdocs%252FcertSetup.html%26invocationType%3D-%26fromPage%3Ddshnnp%26amp%3BampTest%3D1&remove_url=http%3A%2F%2Fzeus.phys.uconn.edu%2Fprod%2Fdocs%2FcertSetup.html
http://www.cs.sunysb.edu/documentation/jsse/api_users_guide.html
http://java.sun.com/j2se/1.4.2/docs/api/javax/net/ssl/SSLSocketFactory.html
http://forum.java.sun.com/thread.jsp?forum=60&thread=204299
http://forum.java.sun.com/thread.jsp?forum=60&thread=525858
http://forum.java.sun.com/thread.jsp?forum=2&thread=258908
http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/samples/sockets/client/SSLSocketClientWithClientAuth.java
http://java.sun.com/products/jsse/doc/apidoc/com/sun/net/ssl/TrustManagerFactory.html
http://www.javaworld.com/javaworld/javatips/jw-javatip96.html
http://www.javaolympus.com/J2SE/NETWORKING/JavaSockets/JavaSockets.jsp
http://www-106.ibm.com/developerworks/java/library/ws-secmap/
http://java.sun.com/products/jsse/
The following helps in customization of JSSE like keymanager, trustmanger etc. and includes a sample server/clients application with SSL.
http://www-106.ibm.com/developerworks/java/library/j-customssl/
file:///usr/weblogic81/samples/server/examples/src/examples/security/sslclient/SSLClient.html
http://www-106.ibm.com/developerworks/java/library/j-customssl/
http://archives.java.sun.com/cgi-bin/wa?A2=ind0201&L=java-security&D=0&P=736
permissions in java
http://java.sun.com/j2se/1.4.2/docs/guide/security/permissions.html
http://mindprod.com/jgloss/certificate.html
Sunday, January 22, 2006
Saturday, January 21, 2006
sql - returning top n records
Returning only the first N records in a SQL query differs quite a bit between database platforms. Here's some samples:
Microsoft SQL Server
SELECT TOP 10 column FROM table
PostgreSQL and MySQL
SELECT column FROM table
LIMIT 10
Oracle
SELECT column FROM table
WHERE ROWNUM <= 10
(use order by too for the specific column - harinath)
Due to these differences if you want to keep your code database independent you should use the maxrows attribute in the cfquery tag. The tradeoffs to database independance is performance, I would expect maxrows to be slower than specifying the rows in the SQL.
SELECT column FROM table
PostgreSQL has a cool feature that will let you return an arbitrary range of rows (eg return rows 10-20). This is very handy for displaying pages of records:
SELECT column FROM table
LIMIT 10 OFFSET 20
The above query will return rows 20-30
Microsoft SQL Server
SELECT TOP 10 column FROM table
PostgreSQL and MySQL
SELECT column FROM table
LIMIT 10
Oracle
SELECT column FROM table
WHERE ROWNUM <= 10
(use order by too for the specific column - harinath)
Due to these differences if you want to keep your code database independent you should use the maxrows attribute in the cfquery tag. The tradeoffs to database independance is performance, I would expect maxrows to be slower than specifying the rows in the SQL.
SELECT column FROM table
PostgreSQL has a cool feature that will let you return an arbitrary range of rows (eg return rows 10-20). This is very handy for displaying pages of records:
SELECT column FROM table
LIMIT 10 OFFSET 20
The above query will return rows 20-30
oracle - removing duplicate records
Question:
I have a table T1 with columns C1, C2 and C3. Currently, there are duplicate
records in T1 with the C1, C2 combination.
T1:
C1 C2 C3
-- -- --
1 50 a
1 50 b
2 89 x
2 89 y
2 89 z
I would like to delete the duplicate record on this combination. What is the best way of writing the PL/SQL block or query to
do this?
Answer:
delete from T1
2 where rowid <> ( select max(rowid)
3 from t1 b
4 where b.c1 = t1.c1
5 and b.c2 = t1.c2 )
6 /
3 rows deleted.
select * from t1;
C1 C2 C
---------- ---------- -
1 50 b
2 89 z
I have a table T1 with columns C1, C2 and C3. Currently, there are duplicate
records in T1 with the C1, C2 combination.
T1:
C1 C2 C3
-- -- --
1 50 a
1 50 b
2 89 x
2 89 y
2 89 z
I would like to delete the duplicate record on this combination. What is the best way of writing the PL/SQL block or query to
do this?
Answer:
delete from T1
2 where rowid <> ( select max(rowid)
3 from t1 b
4 where b.c1 = t1.c1
5 and b.c2 = t1.c2 )
6 /
3 rows deleted.
select * from t1;
C1 C2 C
---------- ---------- -
1 50 b
2 89 z
Subscribe to:
Posts (Atom)