Tuesday, December 30, 2014

Building a executable JAR file with external libraries through JDeveloper

Building a executable JAR file with external libraries through JDeveloper

This post explain the different approaches to build the executable JAR file with external libraries through JDeveloper.

Referring the external libraries from JAR:

Right Click project and select properties
Click on Deployment and create new JAR deployment profile.
Select "Include Manifest File" option.
Select the main class.



Create a manifest file(any location) and add the required jar files to the Class-Path header

Class-Path.mf

Class-Path: json.jar log4j.jar

 End the Class-Path.mf file by a carriage return.


Add the Class-Path.mf file to Additional Manifest Files to Merge into Manifest.mf


Saturday, December 20, 2014

Encrypting/Decrypting data in Adobe Experience Manager(AEM)

Encrypting/Decrypting data in Adobe Experience Manager

com.adobe.granite.crypto.CryptoSupport service can be used to encrypt/decrypt the data in Adobe Experience Manager(AEM).

Maven Dependency:

<dependency>
  <groupId>com.adobe.granite</groupId>
        <artifactId>com.adobe.granite.crypto</artifactId>
         <version>0.0.18</version>
         <scope>provided</scope>
 </dependency>

Service to encrypt/decrypt the message:

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import com.adobe.granite.crypto.CryptoException;
import com.adobe.granite.crypto.CryptoSupport;

@Component(immediate = true, metatype = true)
@Service(value = EncrypionService.class)
public class EncrypionService {
@Reference
private CryptoSupport cryptoSupport;

public String encrypt(String plainText) throws Exception
{
try {
return cryptoSupport.protect(plainText);
} catch (CryptoException e) {
throw e;
}
}

public String decrypt(String encryptedText) throws Exception
{
try {
return cryptoSupport.unprotect(encryptedText);
} catch (CryptoException e) {
throw e;
}
}
}

org.apache.sling.engine.impl.SlingRequestProcessorImpl service: Uncaught Throwable java.lang.LinkageError: loader constraint violation - Adobe Experience Manager(AEM)

org.apache.sling.engine.impl.SlingRequestProcessorImpl service: Uncaught Throwable java.lang.LinkageError: loader constraint violation - Adobe Experience Manager(AEM)

Sometimes we may receive the following exception while invoking the Adobe Experience Manager(AEM) services.

20.12.2014 11:15:31.816 *ERROR* [0:0:0:0:0:0:0:1 [1419054331815] GET /services/EmailServlet HTTP/1.1] org.apache.sling.engine.impl.SlingRequestProcessorImpl service: Uncaught Throwable java.lang.LinkageError: loader consaint violation: when resolving interface method "com..commerce.connector.CommerceService.getSession(Ljavax/servlet/http/HttpServleequest;Ljavax/servlet/http/HttpServleesponse;)Lcom//commerce/connector/session/CommerceSession;" the class loader (instance of org/apache/felix/framework/BundleWiringImpl$BundleClassLoaderJava5) of the current class, com///servlet/EmailServlet, and the class loader (instance of org/apache/felix/framework/BundleWiringImpl$BundleClassLoaderJava5) for resolved class, com//commerce/connector/CommerceService, have different Class objects for the type connector.CommerceService.getSession(Ljavax/servlet/http/HttpServleequest;Ljavax/servlet/http/HttpServleesponse;)Lcom//commerce/connector/session/CommerceSession; used in the signature
at com...servlet.EmailServlet.doPost(EmailServlet.java:67)
at com...servlet.EmailServlet.doGet(EmailServlet.java:56)
at org.apache.sling.api.servlets.SlingSafeMethodsServlet.mayService(SlingSafeMethodsServlet.java:268)
at org.apache.sling.api.servlets.SlingAllMethodsServlet.mayService(SlingAllMethodsServlet.java:139)

This error will be thrown while invoking the service of one bundle from another bundle.

To fix this issue, make sure the required packages from the target bundle is imported to the source bundle.


Thursday, December 18, 2014

org.apache.sling.security.impl.ReferrerFilter Rejected empty referrer header for POST request -Adobe Experience Manager(AEM)

org.apache.sling.security.impl.ReferrerFilter Rejected empty referrer header for POST request - Adobe Experience Manager(AEM)

We will receive the following exception while testing the Adobe Experience Manager(AEM) POST Servlets from Rest client.


15.12.2014 22:55:01.434 *INFO* [0:0:0:0:0:0:0:1 [1418664301434] POST /services/EmailServlet HTTP/1.1] org.apache.sling.security.impl.ReferrerFilter Rejected empty 
referrer header for POST request to /services/EmailServlet

This error is is due to the Apache Sling Referrer Filter will not allow empty Referer address by default.

For testing purpose, we can allow empty referrer by changing the Apache Sling Referrer Filter.

Apache Sling Referrer Filter configuration

Go to the Felix Console - http://localhost:4502/system/console/configMgr
Search for "Apache Sling Referrer Filter"
Select "Allow Empty"

This should be only enabled for testing purpose in dev environment.

Wednesday, December 17, 2014

Sending mail through Java API with Gmail server – Adobe Experience Manager(AEM)

Sending mail through Java API with Gmail server – Adobe Experience Manager(AEM)

This post will explain the steps required to send mail in Adobe Experience Manager(AEM) through Java API with Gmail server.

Configure mail service:

Go to the Felix Console - http://localhost:4502/system/console/configMgr
Search for Day CQ Mail Service
Enter the Gmail server details as shown below and Save the data.

SMTP Server Host   - smtp.gmail.com
SMTP Server Port    - 465
SMTP User              - your gmail username
SMTP Password      - your password
From Address          - your email
SMTP Use SSL      - true


You may need to enable the access for less secure apps in google account - https://www.google.com/settings/security/lesssecureapps

Email Template:

Create the email template as text file and store it in repository - /etc/email/template/emailTemplate.txt (change the path accordingly)


Sunday, December 14, 2014

how to create the page through Java API in Adobe Experience Manager(AEM)

how to create the page through Java API in Adobe Experience Manager(AEM)

This post will explain how to create a page through Java API in Adobe Experience Manager(AEM)

Create the API service

This service create a sample page in Adobe Experience Manager(AEM).

import javax.jcr.Node;
import javax.jcr.Session;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.osgi.service.component.ComponentContext;

import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;

@Component(immediate = true, label = "Create Page Service", description = "Create Sample Page", metatype = true)
@Service(value = CreateSamplePage.class )
public class CreateSamplePage   {

@Reference
private ResourceResolverFactory resolverFactory;
private ResourceResolver resourceResolver;
 
private void createPage() throws Exception {
String path="/content/poc";
String pageName="samplePage";
String pageTitle="Sample Page";
String template="/apps/geometrixx/templates/homepage";
String renderer="geometrixx/components/homepage";

this.resourceResolver = this.resolverFactory.getAdministrativeResourceResolver(null);
    Page prodPage = null;
    Session session = this.resourceResolver.adaptTo(Session.class);
    try {
    if (session != null) {

    // Create Page    
    PageManager pageManager = this.resourceResolver.adaptTo(PageManager.class);
    prodPage = pageManager.create(path, pageName, template, pageTitle);
    Node pageNode = prodPage.adaptTo(Node.class);

Node jcrNode = null;
if (prodPage.hasContent()) {
jcrNode = prodPage.getContentResource().adaptTo(Node.class);
} else {                
jcrNode = pageNode.addNode("jcr:content", "cq:PageContent");
}
          jcrNode.setProperty("sling:resourceType", renderer);
     
     
         Node parNode = jcrNode.addNode("par");
         parNode.setProperty("sling:resourceType", "foundation/components/parsys");

 Node textNode = parNode.addNode("text");
 textNode.setProperty("sling:resourceType", "foundation/components/text");
 textNode.setProperty("textIsRich", "true");
 textNode.setProperty("text", "Test page");

session.save();
        session.refresh(true);
 }
       
} catch (Exception e) {
throw e;

   }    
}




Saturday, December 13, 2014

java.net.ConnectException,Bootstrap to server failed while deploying the compoite - Orace SOA Suite

 java.net.ConnectException,Bootstrap to server failed while deploying the compoite - Orace SOA Suite

Sometimes we may receive the following exception while deploying the composite to Oracle SOA Suite server using even though the sever is running fine and reachable.

oracle.rc.asadapter.connection.ConnectionException
at oracle.rc.asadapter.weblogic.connection.spi.Weblogic10JndiProvider.getPresentation(Weblogic10JndiProvider.java:86)

Caused by: javax.naming.CommunicationException [Root exception is java.net.ConnectException: t3://127.0.0.1:8000: Bootstrap to localhost/127.0.0.1:8000 failed. It is likely that the remote side declared peer gone on this JVM]
at weblogic.jndi.internal.ExceptionTranslator.toNamingException(ExceptionTranslator.java:40)

Caused by: java.net.ConnectException: t3://127.0.0.1:8000: Bootstrap to localhost/127.0.0.1:8000 failed. It is likely that the remote side declared peer gone on this JVM

Caused by: java.rmi.ConnectException: Bootstrap to localhost/127.0.0.1:8000 failed. It is likely that the remote side declared peer gone on this JVM
at weblogic.rjvm.ConnectionManager.bootstrap(ConnectionManager.java:334)


This issue can be resolved by configuring valid machine IP or complete name of the machines, including the domain extension as listen address in weblogic server.

Thursday, December 11, 2014

Can not write to the specified destfile - Error while deploying through jenkins

Can not write to the specified destfile - Error while deploying through jenkins

Some times we may receive the following error "Can not write to the specified destfile"  while performing the deployment through Jenkins.


The error is due to the user running the Jenkins(the user installed the Jenkins) is not having the permission to write the content to the specified file.

To fix the issue make the owner of the file/folder to the user running the Jenkins

chown -R jenkins:jenkins hybris

Provide the required permission to the file/folder

chmod 777

Tuesday, December 9, 2014

Implementing Internationalization with i18n in Adobe CQ5

Implementing Internationalization with i18n in Adobe CQ5

This post will explain how to implement Internationalization with i18n in Adobe CQ5

Configuring i18 keys:

Create a sling:folder i18n inside apps or apps/<<application>> or inside the components folder based on the scope. e.g. /apps/i18n or apps/myapp/i18n or apps/myapp/global/components/mycomponent/i18n


Create a folder for each language inside 118n folder
Assign mixin to the language folders created in the previous step (e.g. en, ar etc) from crx console mix:language
For the language nodes (e.g. en, ar etc) add String property jcr: language, value = ISO language code (en, es etc)

Create nodes of type sling:MessageEntry for each field label
Add 2 properties sling:key = <keyname> and sling:message = <message>


Save all the changes

Using the i18n keys in JSP:

<%@page session="false"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@page import="java.util.Locale,java.util.ResourceBundle,com.day.cq.i18n.I18n"%>
<%@include file="/libs/foundation/global.jsp"%>
<cq:setContentBundle/>
<%
final Locale pageLocale = currentPage.getLanguage(false);
final ResourceBundle resourceBundle = slingRequest.getResourceBundle(pageLocale);
I18n i18n = new I18n(resourceBundle);
%>
<%= i18n.get("cartItem") %>

Thursday, December 4, 2014

how to Invoke the SOAP services from Adobe CQ5

how to Invoke the SOAP services from Adobe CQ5

This post will explain how to invoke the SOAP services from Adobe CQ5

Configure wsimport  plugin to POM.xml:

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>jaxws-maven-plugin</artifactId>
   <version>1.12</version>
   <executions>
      <execution>
         <goals>
            <goal>wsimport</goal>
         </goals>
      </execution>
   </executions>
   <configuration>
      <verbose>true</verbose>
      <args>
         <arg>-B-XautoNameResolution</arg>
      </args>
      <wsdlUrls>
         <wsdlUrl>http://localhost:8080/services/AddressService_1.0.wsdl</wsdlUrl>
      </wsdlUrls>
      <sourceDestDir>src/main/java/</sourceDestDir>
      <packageName>com.ws.address.validation</packageName>
   </configuration>
</plugin>

Change the wsdlurl,sourceDestDir and packageName accordingly.


Saturday, November 29, 2014

User name and password do not match error while accessing CRXDE - Adobe CQ5

User name and password do not match error while accessing CRXDE - Adobe CQ5

Sometimes we may receive User name and password do not match error while accessing the CRXDE and also Authentication Failed error while accessing the Adobe CQ5 configMgr.




We will be receiving this error if the anonymous user account is deleted accidentally.

How to fix

This can be fixed by restarting the repository, anonymous user account will be re-created upon repository restart.

Wednesday, November 12, 2014

Enabling SSL in Dispatcher with self signed certificate - Adobe CQ5

Enabling SSL in Dispatcher with self signed certificate - Adobe CQ5

This post will explain how to Enabling SSL in Dispatcher with self signed certificate in Adobe CQ5

Generating Self signed certificate in Dispatcher:

Create a folder ssl under /etc/httpd/ directory.
Generate server.key and server.crt file by running the following command:

openssl req -new -x509 -sha1 -newkey rsa:1024 \
-nodes -keyout /etc/httpd/ssl/server.key -out /etc/httpd/ssl/server.crt \
-subj '/O=<Organization>/OU=<Department>/CN= <Common Name>'

Change the <Organization>, <Department> and <Common Name> accordingly.

Configure Dispatcher:

Install mod_ssl.so by running the following command
yum install mod_ssl

Modify the VirtualHost in /etc/httpd/conf.d/ssl.conf file with the host name.

<VirtualHost test.server.com:443>

Also, specify the server certificate and key path in the below properties.

SSLCertificateFile /etc/httpd/ssl/server.crt
SSLCertificateKeyFile /etc/httpd/ssl/server.key

Restart the Apache HTTP Server,now we can able to access the urls through https.

Tuesday, November 11, 2014

How to configure SAML SSO for Adobe CQ5

Configuring SAML SSO for Adobe CQ5

Configure Apache Referrer Filter:

Navigate to the web console: http://HOST:4502/system/console/configMgr

Expand Apache Sling Referrer Filter

Add the SAML SSO server host name to the Allowed Hosts section (depending on the authoring environment you are configuring), Check the Allow Empty checkbox and Click Save.


Configure Adobe Granite SAML 2.0 Authentication Handler:

Configured the required details for authentication

    Path
    /
    Service Ranking
    5002
    IPD URL
    IDP HTTP Redirect
    Unchecked - Use an HTTP Redirect to the IDP URL instead of sending an AuthnRequest-message to request credential
    Service Provider Entity ID
    Default Redirect
    /
    User ID Attribute
    UserID - The name of the attribute containing the user ID used to authenticate and create the user in the CRX repository
    Use Encryption
    Unchecked - Whether or not this authentication handler expects encrypted SAML assertions
    Autocreate CRX Users
    Unchecked - Whether or not to autocreate nonexisting users in the repository
    Add to Groups
    Unchecked - Whether or not a user should be autmatically added to CRX groups after successful authentication
    Group Membership
    <empty--no value> - The name of the attribute containing a list of CRX groups this user should be added to
    NameIDPolicy Format
    urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified - The value of the NameIDPolicy format parameter to send in the AuthnRequest message.

Monday, November 10, 2014

Referencing the services between OSGI bundles – AEM

Referencing the services between OSGI bundles – AE

This post explains how to refer the services between OSGI bundles in Adobe Experience Manager.

Export-Package:

Bundles may export zero or more packages from the JAR to be consumable by other bundles. The export list is a comma-separated list of fully-qualified packages, often with a version attribute. If not specified, the version defaults so 0.0.0.

In the target bundle the packages contains the required services and the classes exposed to the other bundles should be exported.


Import-Package 

The Import-Package header is used to declare dependencies at a package level from the bundle. At runtime, the bundle will be wired up with whatever (compatible) bundle offers the package.

In the source bundle the packages contains the required services and classes referred from other bundle should be imported.

Thursday, September 25, 2014

Not able to create the session in OSB console - Could not create directory /osb/config/sessions/weblogic

Not able to create the session in OSB console - Could not create directory <DOMAIN_HOME>/osb/config/sessions/weblogic

Sometimes we may receive the error "could not create directory <DOMAIN_HOME>/osb/config/sessions/weblogic" in the OSB console while trying to create the session.



There will be a multiple reason for this issue, in our case the root cause of the exception is the space is full for the mount  point


How to Fix

To resolve the issue add extra space to the mount point or clear some of the unwanted files and make the required space.

Monday, September 22, 2014

XML-22036: (Error) Cannot convert result tree fragment to NodeSet - Oracle SOA Suite 11g

XML-22036: (Error) Cannot convert result tree fragment to NodeSet - Oracle SOA Suite 11g

We are getting the below exception in runtime while passing the parameter and accessing the same from XSLT in Oracle SOA Suite.




The following exception occurred while attempting to execute operation copy at line 139
-<exception class="com.collaxa.cube.xml.xpath.XPathException">
-<parsererror style="display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black">
<h3>This page contains the following errors:</h3>
<div style="font-family:monospace;font-size:12px">
error on line 7 at column 1: Extra content at the end of the document
</div>
<h3>Below is a rendering of the page up to the first error.</h3>
</parsererror>
XPath expression failed to execute.
An error occurs while processing the XPath expression; the expression is ora:doXSLTransformForDoc('xsl/DistinctPayload.xsl', $inputVariableLocal.payload, 'FlowSubscriberVar2', $FlowSubscriberVar2).
The XPath expression failed to execute; the reason was: javax.xml.transform.TransformerException: oramds:/deployed-composites/default/PPDSOM_EventManager_rev1.0/xsl/DistinctPayload.xsl<Line 8, Column 82>: XML-22036: (Error) Cannot convert result tree fragment to NodeSet..
Check the detailed root cause described in the exception message text and verify that the XPath query is correct.
-<stack>
<f>com.collaxa.cube.xml.xpath.BPELXPathUtil.evaluate#262</f>
<f>com.collaxa.cube.engine.ext.bpel.common.BPELWMPHelper.evalFromValue#339</f>
<f>com.collaxa.cube.engine.ext.bpel.v1.wmp.BPEL1AssignWMP.__executeStatements#137</f>
<f>com.collaxa.cube.engine.ext.bpel.common.wmp.BaseBPELActivityWMP.perform#158</f>
<f>com.collaxa.cube.engine.CubeEngine.performActivity#2543</f>
<f>com.collaxa.cube.engine.CubeEngine._handleWorkItem#1165</f>
<f>com.collaxa.cube.engine.CubeEngine.handleWorkItem#1071</f>
<f>com.collaxa.cube.engine.dispatch.message.instance.PerformMessageHandler.handleLocal#73</f>
<f>com.collaxa.cube.engine.dispatch.DispatchHelper.handleLocalMessage#220</f>
<f>com.collaxa.cube.engine.dispatch.DispatchHelper.sendMemory#328</f>
<f>com.collaxa.cube.engine.CubeEngine.endRequest#4430</f>
<f>com.collaxa.cube.engine.CubeEngine.endRequest#4361</f>
<f>com.collaxa.cube.engine.CubeEngine._createAndInvoke#698</f>
<f>com.collaxa.cube.engine.CubeEngine.createAndInvoke#555</f>
<f>com.collaxa.cube.engine.delivery.DeliveryService.handleInvoke#673</f>
<f>com.collaxa.cube.engine.ejb.impl.CubeDeliveryBean.handleInvoke#293</f>
<f>...</f>
</stack>
</exception>

Wednesday, September 17, 2014

SCAC-50012 - Oracle SOA Suite 11g

SCAC-50012 - Oracle SOA Suite 11g

This error will occur most of time compiling the Oracle BPEL component in Oracle SOA Suite with java embedded activity, If there is any issue with the java code this exception will be thrown.

We were facing the SCAC-50012 exception with the following code.

String orderID  =  ((oracle.xml.parser.v2.XMLElement) getVariableData("inputVariable","payload",'/client:process/client:input')).getFirstChild().getNodeValue();
String Title=("OrderID: " +orderID);                                        
setCompositeInstanceTitle(Title);

The actual  issue with the XPATH expression specified within the single quote(copy paste issue), the compilation became successful after converting the single quotes to double quotes.

String orderID  =  ((oracle.xml.parser.v2.XMLElement) getVariableData("inputVariable","payload","/client:process/client:input")).getFirstChild().getNodeValue();
String Title=("OrderID: " +orderID);                                        
setCompositeInstanceTitle(Title);

Monday, September 1, 2014

Dynamic Endpoint Implementation through DB Table –Oracle SOA Suite

Dynamic Endpoint Implementation through DB Table –Oracle SOA Suite

The below document explain the approach to store change the endpoints of the service dynamically in Oracle SOA Suite.



Download Load_Balancer_Probe_SOA-INFRA.pdf

Friday, August 29, 2014

How to create Repository Nodes thorough Java API in Adobe Experience Manager(AEM)

How to  create Repository Nodes thorough Java in Adobe Experience Manager(AEM)

We can create the repository nodes inAdobe Experience Manager(AEM) through Java API , the below code snippet will help us to create the nodes in Adobe Experience Manager(AEM).

private static final String BASE_PATH = "/etc/commerce/products"; // the folder under which the nodes should be created

//Get the Resource resolver from request - Creating the node through Servlet
ResourceResolver resolver = request.getResourceResolver();

//Get the Resource resolver through resolver factory - Creating the node through Service
@Reference
private ResourceResolverFactory resolverFactory;//Get the resolverFactory reference in the service

ResourceResolver resolver = resolverFactory.getAdministrativeResourceResolver(null);//Get the resolver

//Get the session
Session session = resolver.adaptTo(Session.class);

//Create the Node
Node node = JcrUtil.createPath(BASE_PATH+<<Node Name>>, JcrConstants.NT_UNSTRUCTURED, session);

//Set the required properties
node.setProperty("name", "sample");
node.setProperty("description", "sample");

//Save the session
session.save();

While creating the NT_UNSTRUCTURED node make sure the parent folder is sling:folder, the node will not be created if the parent node is of type nt::folder.

Friday, July 25, 2014

Handling Parallel events through OnEvent event handlers – Oracle SOA Suite

Handling Parallel events through OnEvent event handlers – Oracle SOA Suite

This post will explain, how to handle Parallel events through OnEvent event handlers in Oracle SOA Suite 11g



Download Handling_Parallel_events_ OnEvent_event_handlers_V1.pdf

Thursday, July 24, 2014

Cipher not initialized exception while invoking the Salesforce service through OSB

Cipher not initialized exception while invoking the Salesforce service through OSB

We are getting the "Cipher not initialized" exception wile invoking the Salesforce services through OSB.


We are able to invoke the login.salesforce.com URL successfully and able to receive the session id, also this exception was thrown only for a particular sandbox but the all other sandbox invocation is successful.

The "Cipher not initialized" exception will be thrown when there is no common Ciphers available between the client and server while negotiating the SSL communication.

We have raised a case with Salesforce regarding this and receive the response as "We recently upgraded our Cipher suites for SSL. To resolve the issue upgrade latest version of Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files- 6 for JDK1.6 on middleware."

After upgrading the Unlimited Strength Jurisdiction Policy Files in all the servers nodes we are able to invoke the service successfully.

Steps to resolve the issue

  • Download the Unlimited Strength Jurisdiction Policy Files from http://www.oracle.com/technetwork/java/javase/downloads/index.html(Under Additional Resources" section), for java 1.6 use http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
  • Unzip the downloaded zip 
  • Copy local_policy.jar and US_export_policy.jar to the $JAVA_HOME/jre/lib/security in all the OSB nodes.
  • Restarts the servers.
Now you will be able to invoke the service successfully.

Thursday, July 10, 2014

Integrating Adobe Experience Manager(AEM) with REST services

Integrating Adobe Experience Manager(AEM) with REST services

The below document explains the approach to integrate Adobe CQ5 with REST services.



Download Integrating_CQ5_with_RESTServices.pdf

Saturday, July 5, 2014

java.io.IOException: Server returned HTTP response code: 400 - While invoking the Salesforce login url from java to get the access token

java.io.IOException: Server returned HTTP response code: 400 - While invoking the Salesforce login url from java to get the access token

I was getting the below exception while invoking the Salesforce login url to get the OAuth access_token from java.

java.io.IOException: Server returned HTTP response code: 400 for URL: https://login.salesforce.com/services/oauth2/token
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1436)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
at RestCaller.execute(RestCaller.java:46)
at RestCaller.main(RestCaller.java:10)

This exception will happen normally when the values of client_id, client_security, username and password are not specified correctly while invoking the login url - https://login.salesforce.com/services/oauth2/token to get the OAuth access token.

"grant_type=password&client_id=13MVG9Y6d_xxxxxxx&client_secret=8039xxxxx&username=albinsharpxxxxx&password=Albinxxxx"

In my case, I have specified all the values properly but still it was not working, it worked after resetting the password and getting the new security token - password(password+security token)

Invoking Salesforce REST based web service from Java

Invoking Salesforce REST based web service from Java

This post will explain the approach to call the Salesfore REST based webservice through java.
I have exposed a Apex class as REST service from salesforce to fetch the account details.

@RestResource(urlMapping='/AccountDetails/*')
global with sharing class AccountDetails {

    @HttpGet
    global static Account doGet() {
        RestRequest req = RestContext.request;
        RestResponse res = RestContext.response;
        String accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
        System.debug('Account Id:'+accountId);
        Account result = [SELECT Id, Name, Phone, Website FROM Account WHERE Id = :accountId];
        return result;
    }
}

The communication is of two steps
  •  getting the access_token 
  •  invoking the service endpoint by attaching the access_token to the request.
To obtain an access token, we will send an HTTP POST request to the authentication endpoint exposed by Salesforce - https://login.salesforce.com/services/oauth2/token  with the details client_id, client_secret, username and password.This values can be get from the configured Connected Apps from salesforce.



Friday, July 4, 2014

Ignoring the Host Name verification while invoking the HTTPS service through HttpsURLConnection

Ignoring the Host Name verification while invoking the HTTPS service through HttpsURLConnection

Sometimes you may receive the Host Name mismatch exception while invoking the HTTPS service from the Java client even though the valid certificate is installed to the key store.

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching <Host Name> found

The root cause of the exception is the CN name of the certificate is not matching with the host name used to connect the service.

In real scenario while the certificate is signed with third party certificate authority , the CN name will be specified as the host name of the server where the service is hosted or wildcard name will be specified e.g *.example.com to represent all sub domains in a domain. So there will not be any issue while connecting to the service.

This mismatch exception will happen most of the time communicating with self signed certificate, the certificate is signed with CN name that is not matching with the host name.

How to Fix the issue

To resolve the issue, the certificate should be signed with proper CN name or we can create a custom host name verifier to customize the host name verification functionality.

We have to return true from the custom host name verifier for the host name for which the CN name is mismatching.This will connect to the service irrespective of the host name used .

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.HttpURLConnection;

public class HTTPCaller {
static {
   javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
   new javax.net.ssl.HostnameVerifier(){
       public boolean verify(String hostname,
               javax.net.ssl.SSLSession sslSession) {
           if (hostname.equals("localhost")) {
               return true;
           }
           return false;
       }
   });
}

    public static String execute() {
        String targetURL="https://localhost/test"
        URL url;
        HttpURLConnection connection = null;
        try {
            url = new URL(targetURL);
            url = new URL(url.toString());              

            connection = (HttpURLConnection)url.openConnection();
            connection.setRequestProperty("accept", "application/xml"); //for GET service to return xml payload

            InputStream is = connection.getInputStream();
            BufferedReader rd = new BufferedReader(new InputStreamReader(is));
            System.out.println("\n Received response" + System.currentTimeMillis());

            String line;
            StringBuffer response = new StringBuffer();
            while ((line = rd.readLine()) != null) {
                response.append(line);
                response.append('\r');
            }
            rd.close();
            return response.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return (e.getClass().getName()+":"+e.getMessage().toString());
        }
        finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

Wednesday, July 2, 2014

Encrypting XML Payload through XSLT in Spring WS

Encrypting XML Payload through XSLT in Spring WS

The below document explain the approach to This document will explain the approach to encrypt the critical elements of XML payload while invoking the services in Spring WS or storing the data to a database table through XSLT.



Encrypting_XML_Payload.pdf

Tuesday, July 1, 2014

Unit Testing the Velocity Templates in spring

Unit Testing the Velocity Templates in spring

It is painful to test the Velocity Template  by deploying to the server while doing frequent changes.
The unit testing  will help as to overcome this and do proper testing without deploying the project to the server.
This post will explain the approach to unit test the Velocity Templates through eclipse.

Spring velocity configurations

Create a Velocity-test.xml configuration file to configure the velocity bean - instead of creating separate configuration file we can also use the project configuration file that has the velocity bean configuration (e.g. application-context.xml)


Change the vm template path accordingly.

Create a test java class (VelocityTest.java)

import java.io.*;
import java.util.ArrayList;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.thomson.ecom.core.velocity.VelocityContextBuilder;
public class VelocityTest
{
public static void main(String[] args) throws Exception
{
ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:velocity-test.xml");
ArrayList<Employee> employeeList=new ArrayList<Employee>();

Employee emp1=new Employee();
emp1.setContactNo("111111");
emp1.setDept("CSC");
emp1.setEmail("[email protected]");
emp1.setEmpName("Albin");
emp1.setEmpNo("1");
emp1.setLocation("Bangalore");
employeeList.add(emp1);

Employee emp2=new Employee();
emp2.setContactNo("22222");
emp2.setDept("IT");
emp2.setEmail("[email protected]");
emp2.setEmpName("Albin1");
emp2.setEmpNo("2");
emp2.setLocation("Bangalore");
employeeList.add(emp2);

Employee emp3=new Employee();
emp3.setContactNo("33333");
emp3.setDept("IT");
emp3.setEmail("[email protected]");
emp3.setEmpName("Albin2");
emp3.setEmpNo("3");
emp3.setLocation("Bangalore");
employeeList.add(emp3);

VelocityEngine engine = ctx.getBean("velocityEngine", VelocityEngine.class);
Context velocityCtx = VelocityContextBuilder.getInstance().buildContext();
velocityCtx.put("empList", employeeList);

Writer w = new FileWriter(new File("D:\\Albin\\velocity.html"));
engine.mergeTemplate("EmployeeEmailTemplate.vm", velocityCtx, w);
w.close();

System.exit(0);
}
}

Change the velocity.html file path and the vm template name accordingly.
Pass the required inputs to the velocityCtx map.
Execute the VelocityTest.java; this will generate the velocity.html file in the specified location.

Resolving cvc-elt.1: Cannot find the declaration of element 'beans' in Spring

Resolving cvc-elt.1: Cannot find the declaration of element 'beans' in Spring

I was receiving the following exception while running the Spring application in standalone mode with maven and eclipse.

Exception in thread "main" org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 11 in XML document from class path resource [encrypt/encrypting-test.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'beans'.
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:396)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)

Caused by: org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'beans'.
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source)

Unfortunately, I could not able to find any issue in my bean configuration file.

<? xml version="1.0" encoding="UTF-8 ?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <bean id="encryptXMLPayload" class="com.encrypt.EncryptXMLPayload">
          <property name="encryptor" ref="encryptor" /> 
          <property name="messageStylesheet" value="classpath:encrypt/encryptXMLPayload.xslt" />
     </bean>
     <bean id="encryptor" class="com.encrypt.Encryptor" init-method="init">
           <property name="keyData" value="pYOkcj4_kf-4hn-A-IkclLWDBJI-T5bd"/>
     </bean> 
 </beans>

After analysis, the issue is with version mismatch between the pom.xml(spring version configured) and the schema version  configured in the bean configuration file

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.0.0.RELEASE</version>
<scope>compile</scope>
</dependency>

<? xml version="1.0" encoding="UTF-8 ?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">


How to Fix


The issue got resolved after changing the schema version to 3.0 in the bean configuration file as shown below

<? xml version="1.0" encoding="UTF-8 ?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 

The spring version configured in the pom.xml and the schema version used in the bean configuration files should be matching.

Loading configuration properties from Database Table in Spring Application

Loading configuration properties from Database Table in Spring Application

This is better approach to store the configuration properties to a database table so that this can be managed easily.
This post will explains the approach to store and retrieve the configuration properties from database table in spring project.

Bean definition in Spring context file:

Configure the below bean definition to the spring context file

<!--  Loads properties to set environment-specific values within the DB table for that environment -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="properties">
<bean class="org.apache.commons.configuration.ConfigurationConverter"
factory-method="getProperties">
<constructor-arg>
<bean class="org.apache.commons.configuration.DatabaseConfiguration">
  <constructor-arg>
  <ref bean="propertyDataSource"/>
</constructor-arg>
     <constructor-arg value="Properties"/>  <!--  DB Table -->
     <constructor-arg value="prop_key"/> <!-- DB Key Column -->
   <constructor-arg value="prop_value"/> <!--  DB Value Column -->
   </bean>
</constructor-arg>
</bean>
</property>
</bean>

Properties database table

The Properties database table should be pre-created with the required configuration values

Prop_keyProp_value
ftp.hostlocalhost
ftp.useralbin

Data source configuration

The datasource ref bean  propertyDataSource should be configured in the spring context file.

<jee:jndi-lookup id="propertyDataSource" jndi-name="java:comp/env/jdbc/propertyDS"/>

Here i am using the Tomcat server, the actual datasource - jdbc/propertyDS should be configured in context.xml file of the Tomcat server.

<Resource name="jdbc/propertyDS "
auth="Container"
type="javax.sql.DataSource"
username="property_user"
password="property "
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://localhost:1433;DatabaseName=Soa"
maxActive="4"
maxIdle="2"/>

Refer the properties

Now the properties can be referred as shown below

<bean id="ftp" class="com.doc.FTPService">
<property name="host" value="${ftp.host}"/>
<property name="user" value="${ftp.user}"/>
</bean>

Sunday, June 29, 2014

Spring Web service with NTLM Authentication

Spring Web service with NTLM Authentication

NTLM is a proprietary authentication scheme developed by Microsoft and optimized for Windows operating system.

This post will explain how to invoke the NTLM authentication enabled web services from spring integration.

Spring Web Service uses the Apache HTTPClient to communicate to the NTLM authentication enabled services.

We named our spring bean as WebServiceNTLMAuhCommunicationClientImpl, it will extend the class org.springframework.ws.client.core.support.WebServiceGatewaySupport

We have overridden the method initGateway to set the org.apache.commons.httpclient.NTCredentials object to CommonsHttpMessageSender.

The userName, password and the domain name should be provided to createthe NTCredential object.

The afterPropertiesSet method on CommonsHttpMessageSender class should be invoked after setting the credential - afterPropertiesSet method will set the credentials to HttPClient.

WebServiceNTLMAuhCommunicationClientImpl.java

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.NTCredentials;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.ws.transport.http.CommonsHttpMessageSender;

public class WebServiceNTLMAuhCommunicationClientImpl extends WebServiceGatewaySupport {
 private String basicAuthUsername;
 private String basicAuthPassword;
 private String domain;
 private String hostname;


 public String getHostname() {
  return hostname;
 }

  public void setHostname(String hostname) {
  this.hostname = hostname;
 }

  public Object send(String url, Object request)
 {
  return this.getWebServiceTemplate().marshalSendAndReceive(
    url, request, null);
 }

 public void setBasicAuthPassword(String basicAuthPassword)
    {
     this.basicAuthPassword = basicAuthPassword;
    }

  public void setBasicAuthUsername(String basicAuthUsername)
    {
     this.basicAuthUsername = basicAuthUsername;
    }

 public String getDomain() {
  return domain;
 }

  public void setDomain(String domain) {
  this.domain = domain;
 }

  @Override
    protected void initGateway() throws Exception
    {
  if(this.basicAuthUsername != null || this.basicAuthPassword != null)
  {
    ((CommonsHttpMessageSender)this.getMessageSenders()[0]).setCredentials(getCredentials());
    ((CommonsHttpMessageSender)this.getMessageSenders()[0]).afterPropertiesSet();
  }
  super.initGateway();
    }

 private Credentials getCredentials() {
   return new NTCredentials(this.basicAuthUsername, this.basicAuthPassword, getHostname(), getDomain());
 }

}

Wednesday, June 25, 2014

javax.management.MBeanException: The configuration file, deployed-composites.xml, does not contain the composite-revision element

javax.management.MBeanException: The configuration file, deployed-composites.xml, does not contain the composite-revision element

We were receiving the following exception while deploying the composite to the SOA server in Solaris.

The exception was thrown while activating the component.

compositeMgrTask:
     [java] Connecting to: service:jmx:t3://localhost:8004/jndi/weblogic.management.mbeanservers.runtime
     [java] connection initiated
     [java] javax.management.MBeanException: The configuration file, deployed-composites.xml, does not contain the CRMASYNC/zz!5.3.19 composite-revision element.
     [java]     at oracle.as.jmx.framework.standardmbeans.spi.OracleStandardEmitterMBean.doInvoke(OracleStandardEmitterMBean.java:986)

The actual exception is the component was not deployed successfully due to some exception and it is trying to activate the same .

The exception while deploying the component is

[deployComposite] setting user/password..., user=weblogic
[deployComposite] Processing sar=/shared/11g/soa_deploy/code/config/scripts/../../LoadBalancerProbe/zz/deploy/sca_zz_rev5.3.19.jar
[deployComposite] Adding sar file -/shared/11g/soa_deploy/code/config/scripts/../../LoadBalancerProbe/zz/deploy/sca_zz_rev5.3.19.jar
[deployComposite] INFO: Creating HTTP connection to host:localhost, port:8004
[deployComposite] INFO: Received HTTP response from the server, response code=500
[deployComposite] ---->response code=500, error:There was an error deploying/undeploying composite on SOA1: Error in reading data from deployer client.: /var/tmp/sar_base_dir_07be0448-8481-4ade-a2e9-253e5a8ba33c/sca_zz_rev5.3.19.jar (No such file or directory).

Based on the error, the deployer could not able to retrieve the jar file from the tmp location.
After analysis, the /var/tmp space is full and the script could not able to write the jar file.
We can use df -kh command to find the space utilization


How to Fix

To resolve the issue login as root user and clear the /var/tmp folder.

Thursday, June 12, 2014

Generating JAXB artifacts from XSD/WSDL through Maven

Generating JAXB artifacts from XSD/WSDL through Maven

The maven-jaxb2-plugin can be used to generate the java classes from both XSD/WSDL.

Plugin configuration in Pom.xml

The below plug in configuration can be used in the pom.xml file to generate the sources.
<plugin>
  <groupId>org.jvnet.jaxb2.maven2</groupId>
  <artifactId>maven-jaxb2-plugin</artifactId>
  <version>0.7.3</version>
  <executions>
    <execution>
      <id>app1-stub-generation</id>
      <goals>
        <goal>generate</goal>
      </goals>
      <configuration>
        <schemaDirectory>src/main/resources</schemaDirectory>
        <schemaIncludes>
          <include>*.xsd</include>
        </schemaIncludes>
        <generatePackage>com.thomson.ecom.service.bean.demo</generatePackage>
        <clearOutputDir>false</clearOutputDir>
        <generateDirectory>src/main/java</generateDirectory>
        <strict>true</strict>
      </configuration>
    </execution>
 
 
  </executions>
</plugin>

Change the include accordingly to generate for wsdl -   <include>*.wsdl</include>

Generate the sources

To generate the sources, Right click on pom.xml-->Run As-->Maven generate-sources


This will generate all the java classes to src/main/java

Wednesday, June 11, 2014

Configuring JAXB2-Maven-Plugin not to clear the outputdirectory

Configuring JAXB2-Maven-Plugin not to clear the outputdirectory

JAXB2-Maven-Plugin will help us to generate the java classes from the xsd.
By default the plugin clears the existing contents in the ouputdirectory and generate the new java classes into the outputdirectory.

Some cases we may need to generate the java classes from multiple source xsd's so we have to configure the plugin not to clear the outputdirectory.

Yo have to add <clearOutputDir>false</clearOutputDir> in the plugin configuration.

<plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxb2-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>xjc</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <!-- The schema directory or xsd files. -->
                <schemaDirectory>${basedir}/src/main/resources</schemaDirectory>
                <!-- The package in which the source files will be generated. -->
                <packageName>com.service.bean.demo</packageName>
                 <clearOutputDir>false</clearOutputDir>
                <!-- The working directory to create the generated java source files. -->
                <outputDirectory>${basedir}/src/main/java</outputDirectory>
            </configuration>
        </plugin>

Tuesday, June 10, 2014

Changing the default Maven repository location in eclipse

Changing the default Maven repository location in eclipse

Sometimes we may required to modify the default maven repository location to custom location for the eclipse project.
Eclipse project will have the variable M2_REPO defined as read only.


The following steps will help as to change the default Mavan repository location.

Modify the settings.xml file in the <<USER_HOME>>/.m2 and add the localRepository value accordingly.



If the .m2 folder ia not available in the USER_HOME create the same(md .m2) and also create a settings.xml file and update the file with the following contents(change the value of localrepository and the repository url accordingly)