Wednesday, June 15, 2011

How to solve javax.net.ssl.SSLHandshakeException?

A few days ago, I deployed one of my applications to Weblogic 10.3 AS but it failed to send emails, I was using gmail as my SMTP server and this was the error :

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.

After many searches I found the solution and now I'm gonna share it with you.
The problem is that the public key of the SMTP server is not imported into JRE's default keystore, in order to import it, you should follow these steps:
  1. Install OpenSSL (http://www.openssl.org/)
  2. Double-click the openssl file from the directory that gets installed
  3. Run: s_client -connect smtp.gmail.com:465 (465 is port of SMTP, if you are using another port, use that one)
  4. From the output, you want only the alphanumeric string between the lines which say 'BEGIN CERTIFICATE' and 'END CERTIFICATE' (inclusive). Copy the results into a file called gmail.cert using your favorite text editor.

  5. Now its time to import the public key into default keystore. From Java installation's bin directory run:
    keytool -import -alias smtp.gmail.com -keystore $JAVA_HOME/jre/lib/security/cacerts -file C:\path\to\gmail.cert
* The default keystore password is 'changeit'.

This should solve your problem, if you still have problem with Weblogic server, the reason is that Weblogic has it's own default keystore which is located at: 

$ORACLE_HOME/weblogic/wlserver_10.3/server/lib/DemoTrust.jks

All you need to do is to import gmail.cert into the above keystore in the same way you did for JRE's keystore.

* The default keystore password is 'DemoTrustKeyStorePassPhrase'.


Saturday, October 24, 2009

Page Ranking Implemented in Java

Within the past few years, Google has become the far most utilized search engine worldwide. This success is because of the high quality results in comparison to other search engines. This high quality result is because of the Page Ranking feature that google is using.


Each document is assigned with a ranking while it is being indexed. when you search for a keyword, pages with higher page rank are displayed on top.


The page rank algorithm is found by Google founders Lawrence Page and Sergey Brin.


In this article we first go through the algorithm and then implement it in Java.


The article is available from http://www.javadev.org/files/Ranking.pdf

The source code is available from http://www.javadev.org/files/ranking.zip

Tuesday, November 25, 2008

How to Develop JAAS Security on JBoss AS ?

A few days ago I was proposed to develop an airline ticketing system using JavaEE platform. For this system I decided to use EJB3 and JSF running on JBoss application server.
As long as security is a vital concern in such applications, I decided to use JAAS (Java Authentication and Authorization Service) to implement authentication and authorization.
After searching for the required configurations to implement a JAAS based security on JBoss, I couldn’t find anything useful, even in the JBoss documents! (JavaEE developers are not very unfamiliar with this).
It took a while for me to find all the required settings and run my project under JAAS technology on the JBoss application server, so I decided to share my knowledge and document it, hope to be useful for somebody.

The printable version of this article is available at:
http://www.javadev.org/files/JAAS-JBoss.pdf

Tuesday, July 31, 2007

Hibernate Performance Tuning

Performance is one the most important issues in applications. Application Performance depends on a variety of parameters which must be mentioned carefully to prevent bottle nakes in the application.
Performance-tuning your application should first include the most obvious settings,such as the best fetching strategies and use of proxies.

This is an article about how to tune our hibernate settings to gain the best performance and prevent vulnerable problems.

You can view a printable version(PDF) of the article at:
http://www.javadev.org/files/Hibernate%20Performance%20Tuning.pdf

Saturday, July 28, 2007

How to REST?! - RESTing Without JAX-WS

During our example we used JAX-WS API to communicate with the web service. Although this is the best way, but there are other ways as well.One of these ways is using HttpURLConnection:

1. The client uses the URL.openConnection() method to create an instance of HttpURLConnection representing a connection to the Web service’s URL.

2. HttpURLConnection.connect() sends the HTTP GET request that has been configured using the Web service’s URL.

3. The Web service processes the request and writes the appropriate XML document to the HTTP response stream.

4. The HttpURLConnection’s InputStream is used to read the HTTP response’s XML document.

Exmaple of a non-JAX-WS Client

URL url = new URL(""); // the web service URL
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.connect();InputStream in = con.getInputStream();

byte[] b = new byte[1024]; // 1K buffer

int result = in.read(b);
while (result != -1) {
System.out.write(b,0,result);
result =in.read(b);
}
in.close();
con.disconnect();

Note that the in this case the web service does not return the XML message directly in the StreamSource format but it writes the StreamSource result to the response OutputStream.

How to REST?! - XML Transformation

In the previous sections, we sent and received XML messages to/from web service.In this communication the client and web service received the XML message in the formats that they were expecting. These formats were defined in the XML schema files. But sometimes we need to adapt ourselves with different formats of information. For example some services may use email instead of username to identify their customers. So we must provide a way for different XML formats to be acceptable by our RESTful web service.Here we need to transform the incoming xml message to an acceptable format. We can use XSLT for this reason.XSLT makes sense as the transformation tool of choice within SOA integration frameworks, because it is a universally accepted standard and the transformation engines that interpret XSLT to perform data transformations keep getting better and faster.

As an example assume that the authentication message came from the client is in the following format:
<?xml version="1.0"?>
<auth xmlns="http://www.javadev.org/mail" xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance" xsi:schemaLocation="http://www.javadev.org/mail
http://javadev.org/rest/auth/mail.xsd">
<email>foo</email>
<password>foo</password>
</auth>

As you can see <username> is replaced with <email> , for the authentication service there is no difference between username and email, because both of them are unique. But the main point of the consideration is that currently, when we are parsing the incoming xml document, we expect the <username> element but we are facing an <email> element.To transform the incoming XML document to the expected format we write an XSLT and use it in the JAXP API.The XSLT document is as bellow:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:mail=
http://www.javadev.org/mail>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="mail:auth">
<auth xmlns="http://www.javadev.org/auth" xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xsi:schemaLocation="http://www.javadev.org/auth
http://javadev.org/rest/auth/auth.xsd">
<xsl:apply-templates/>
</auth>
</xsl:template>
<xsl:template match="mail:email">
<xsl:apply-templates select="./mail:email"/>
</xsl:template>
<xsl:template match="mail:password">
<xsl:apply-templates select="./mail:password"/>
</xsl:template>
<xsl:template match="mail:email">
<username>
<xsl:value-of select="."/>
</username>
</xsl:template>
<xsl:template match="mail:password">
<password>
<xsl:value-of select="."/>
</password>
</xsl:template>
</xsl:stylesheet>


This XSLT transformer reads the source XML file and converts it to the destination XML format.After creating the XSLT file, we need to apply it to the incoming xml file before parsing it.

InputStream xslt = this.getClass().getResourceAsStream("mail_to_user.xslt");
try {
TransformerFactory.newInstance().newTransformer(new StreamSource(xslt))
.transform(src, res);
} catch (Exception e) {
e.printStackTrace();
}

The only difference is that we pass the XSLT document as an StreamSource object to the Transformer to use it before converting the incoming StreamSource object to the equivalent OutputStream.So we can convert any format of incoming messages to our desired format before extracting information.

How to REST?! - Authentication Client

We are using a simple java application as our client.The client is using the JAX-WS API to communicate with the web service.It first generates an XML message which contains information need to be authenticated.

info += "<?xml version=\"1.0\"?>";
info += "<auth xmlns=\"http://www.javadev.org/auth\" xmlns:xsi=\"
http://www.w3.org/2001/XMLSchema-instance\
"+
xsi:schemaLocation=\"
http://www.javadev.org/auth
\"+
http://www.javadev.org/rest/auth/auth.xsd >";
info += "<username>foo</username>";
info += "<password>foo</password>";
info += "</auth>";

As you can see, we are generating an XML message with the Username and Password which must be authenticated in the web service.

In the client, Service is used to create an instance of javax.xml.ws.Dispatch, which enables XML message-level interaction with the target Web service. Dispatch is the low-level JAX-WS 2.0 API that requires clients to construct messages by working directly with the XML, rather than with a higher- level binding such as JAXB 2.0 schema derived program elements. For many REST proponents, however, this is exactly the programming paradigm they want—direct access to the XML request and response messages.
The client uses the Service.addPort() method to create a port within the Service instance that can be used to access the RESTful web service.
Next, the Service.createDispatch() method is invoked to create an instance of Dispatch—a Dispatch instance that enables you to work with XML request/response messages as instances of javax.xml.transform.Source.
The Dispatch.invoke() method then packages the XML request—per the JAX-WS 2.0 HTTP Binding—and sends it to the RESTful service. The invoke() method waits for the response before returning.The service processes the HTTP GET and sends an HTTP response that includes the XML.The invoke() method returns the response XML message as an instance of Source.

// Create an InputStream with the authentication info
ByteArrayInputStream bais = new ByteArrayInputStream(info.getBytes());

QName svcQName = new QName("http://rest", "svc");
QName portQName = new QName("http://rest", "port");
Service svc = Service.create(svcQName);
svc.addPort(portQName, HTTPBinding.HTTP_BINDING, url);
Dispatch dis =
svc.createDispatch(portQName, Source.class, Service.Mode.PAYLOAD);
StreamSource result = (StreamSource) dis.invoke(new StreamSource(bais));

Notice that you have to create QName instances for the Service instance and the “port” that corresponds to the RESTful Web service. In a SOAP scenario, these qualified names would correspond to the WSDL definitions for the wsdl:service and wsdl:port. Since there is no WSDL when invoking a RESTful service, these QName instances are gratuitous. They are required by the API, but not used to invoke the RESTful service.
The URL used in the addPort method is the URL of your web service for example we used http://localhost:8080/auth/authService which:
localhost is the name/IP of your running application server.
8080 is the port port of your application server.
auth is the context path of your web service which in our example is defined.
authService is the value of serviceName attribute of the @WebServiceProvider annotation in the web service.As you can see the authentication result is returned as an Source object. So we should parse it and extract the message as we did in the web service.