Tuesday, July 1, 2014

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)