Search
Calendar
November 2017
S M T W T F S
« Sep    
 1234
567891011
12131415161718
19202122232425
2627282930  
Your widget title
Archives

Posts Tagged ‘Spring’

PostHeaderIcon Spring: Failed to read schema document

Case

I try to deploy a Mule ESB configuration, using this XML:

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:pattern="http://www.mulesoft.org/schema/mule/pattern"
 xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core
 http://www.mulesoft.org/schema/mule/core/3.1/mule.xsd
 http://www.mulesoft.org/schema/mule/pattern
 http://www.mulesoft.org/schema/mule/pattern/3.1/mule-pattern.xsd
 ">
 <pattern:simple-service name="authenticationService"
 address="http://localhost:1234/authenticationService"
 component-class="lalou.jonathan.esb.components.AuthenticationComponent"
 type="direct" />
</mule>

I get the following error:

Ignored XML validation warning
org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'http://www.mulesoft.org/schema/mule/pattern/3.1/mule-pattern.xsd'

Extended Stacktrace

2011-11-22 16:10:25,375 WARN  xml.XmlBeanDefinitionReader         - Ignored XML validation warning
org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'http://www.mulesoft.org/schema/mule/pattern/3.1/mule-pattern.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.
 at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
 at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.warning(ErrorHandlerWrapper.java:96)
 at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:380)

Notice that Mule ESB files are similar to classic Spring files. Of course, I first checked the pointed XSD was actually reachable.
Anyway, this error should be raised when your application, for any reason -firewall, proxies, network interruption-, cannot access the remote site where the XSD is hosted.

Fix

  • Copy the XSD to a local folder
  • Create a file spring.schemas
  • Make it available in the classpath in META-INF.
  • Add the following line
  • http\://www.mulesoft.org/schema/mule/pattern/3.1/mule-pattern.xsd=WEB-INF/classes/mule-pattern.xsd

    The pattern is: missing resource (beware of escaping colon) = path in classpath of the local XSD

  • Rebuild, pack and run!

PostHeaderIcon java.net.ConnectException: (…) Bootstrap to (…) failed. It is likely that the remote side declared peer gone on this JVM

Case and Topology

RMI services are deployed on UAT, exposed via a F5, at the following address: t3://my-f5-frontal.my.domain.extension:7090
The actual servers are my-first-node.my.domain.extension and my-second-node.my.domain.extension.

The client application is deployed in a remote location, on a QA server.
The ports are open between QA and UAT, and we can ping and use telnet with no issue on QA.

Anyway, when I launch the client application from QA, I get the following error:

2011-10-31 06:41:03,277 INFO  support.DefaultListableBeanFactory  - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@79e304: defining beans [jonathanServiceClient]; root of factory hierarchy
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'smartServiceClient' defined in class path resource [com/lalou/jonathan/rmi-client-spring.xml]: Invocation of init method failed; nested exception is org.springframework.remoting.RemoteLookupFailureException: JNDI lookup for RMI service [rmiServices] failed; nested exception is javax.naming.CommunicationException [Root exception is java.net.ConnectException: t3://my-f5-frontal.my.domain.extension:7090: Bootstrap to my-f5-frontal.my.domain.extension/111.222.012.123:7090 failed. It is likely that the remote side declared peer gone on this JVM]

Explanation and Fix

Owing to my understanding, here is the point: when the client tries to connect to F5, it presents itself with its name, and the F5 returns the name of the actual server. If both client and server are not on the same domain (“domain” as network domain, no link with Weblogic domain), then the DNS resolution may fail.

To fix this issue, you have to follow one or both of the following points: everything depends on your local topology.

WebLogic: “Listen Address”

Modify the “Listen Address” in WebLogic administration console, from home:  Servers > MyFirstNode/MySecondNode > Configuration > General > Listen Address > update it

By “update” the “Listen Address”, I mean providing the complete name of the machines, including the domain extension.
eg: my-first-node.my.domain.extension and my-second-node.my.domain.extension, rather than my-first-node and my-second-node (or, even worse, localhost).
You can also provide an IP, cf. WebLogic documentation on Oracle’s website.

Of course, you can decide to set it directly in WebLogic’s config.xml.

Caution! This option may also be set via the command line running WebLogic, using the flag -Dweblogic.ListenAddress=... Therefore, take care to be consistent between the content of console/config.xml and the command line option.

Hosts

On client side, check the content of hosts file. Usually, you can found it at /etc/hosts (or C:\WINDOWS\system32\drivers\etc\hosts on Windows XP).
Assuming your machine is myClientMachine with an IP 123.123.123.123 and a domain extension remote.domain, then your hosts file should look like:

127.0.0.1       localhost
123.123.123.123  myClientMachine

Update it to:

127.0.0.1       localhost
123.123.123.123  myClientMachine myClientMachine.remote.domain

PostHeaderIcon How to Read a BLOB for a Human Being?

Case

I have had to access a BLOB and read its content. By principle, I dislike using binary objects, which do not suit easy tracing and auditing. Anyway, in my case, floats are stored in a BLOB, and I need read them in order to validate my current development.

You have many ways to read the content of the BLOB. I used two: SQL and Java

SQL

Start your TOAD for Oracle ; you can launch queries similar to this:

SELECT UTL_RAW.cast_to_binary_float
             (DBMS_LOB.submyrecord (myrecord.myrecordess,
                                    4,
                                    1 + (myrecordessnameid * 4)
                                   )
             ) AS myrecordessvalue
  FROM mytable myrecord
 WHERE myrecordessid = 123456; 

You can also run a stored procedure, similar to this:

DECLARE
   blobAsVariable  BLOB;
   my_vr           RAW (4);
   blobValue       FLOAT;
   bytelen         NUMBER  := 4;
   v_index         NUMBER  := 5;
   jonathan        RAW (4);
   loopLength      INT;
BEGIN
   SELECT myField
     INTO blobAsVariable
     FROM myTable
    WHERE tableid = (5646546846);

   DBMS_LOB.READ (blobAsVariable, bytelen, 1, jonathan);
   loopLength := UTL_RAW.cast_to_binary_integer (jonathan);

   FOR rec IN 1 .. loopLength
   LOOP
      DBMS_LOB.READ (blobAsVariable, bytelen, v_index, my_vr);
      blobValue := UTL_RAW.cast_to_binary_float (my_vr);
      v_index := v_index + 4;
      DBMS_OUTPUT.put_line (TO_CHAR (blobValue));
   END LOOP;
END;

Java

I am still not sure to be DBA expert. Indeed I am convinced I am more fluent in Java than in PL/SQL 😉

Create a Spring configuration file, let’s say BlobRuntimeTest-applicationContext.xml:

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <!-- $Id: BlobRuntimeTest-applicationContext.xml  $ -->
    <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin:@myDBserver:1234:MY_SCHEMA"/>
        <property name="username" value="jonathan"/>
        <property name="password" value="lalou"/>
        <property name="initialSize" value="2"/>
        <property name="minIdle" value="2"/>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

</beans>

Now create a runtime test:

/**
 * User: Jonathan Lalou
 * Date: Aug 7, 2011
 * Time: 5:22:33 PM
 * $Id: BlobRuntimeTest.java $
 */
public class BlobRuntimeTest extends TestCase {
    private static final Logger LOGGER = Logger.getLogger(BlobRuntimeTest.class);

    private static final String TABLE = "jonathanTable";
    private static final String PK_FIELD = "jonathanTablePK";
    private static final String BLOB_FIELD = "myBlobField";
    private static final int[] PK_VALUES = {123, 456, 789};

    private ApplicationContext applicationContext;
    private JdbcTemplate jdbcTemplate;

    @Before
    public void setUp() throws Exception {
        applicationContext = new ClassPathXmlApplicationContext(
                "lalou/jonathan/the/cownboy/BlobRuntimeTest-applicationContext.xml");
        assertNotNull(applicationContext);
        jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
        assertNotNull(jdbcTemplate);
    }

    @After
    public void tearDown() throws Exception {
    }

    @Test
    public void testGetArray() throws Exception {
        for (int pk_value : PK_VALUES) {
            final Blob blob;
            final byte[] bytes;
            final float[] floats;

            blob = (Blob) jdbcTemplate.queryForObject("select " + BLOB_FIELD + " from " + TABLE + " where " + PK_FIELD + " = " + pk_value, Blob.class);
            assertNotNull(blob);
            bytes = blob.getBytes(1, (int) blob.length());
            // process your blob: unzip, read, concat, add, etc..
            // floats = ....

            LOGGER.info("Blob size: "  + floats.length);
            LOGGER.info(ToStringBuilder.reflectionToString(floats));
        }
    }
}

PostHeaderIcon RMI / Spring / Cannot narrow remote object ClusterableRemoteRef

Case

Under WebLogic, I deploy RMI services:

    <bean id="fakeRmiServer" class="org.springframework.remoting.rmi.JndiRmiServiceExporter">
        <property name="service" ref="fakeInterfaceImpl" />
        <property name="serviceInterface" value="lalou.jonathan.FakeInterface" />
        <property name="jndiName" value="fakeRmiServer" />
    </bean>
    <bean id="fakeInterfaceImpl" class="lalou.jonathan.FakeInterfaceImpl" />

The WAR is hosted by a WebLogic 10.3.3 server (this point does not matter).

I retrieve the RMI services on client side, with this Spring config:

    <bean id="fakeServiceClient" class="org.springframework.remoting.rmi.JndiRmiProxyFactoryBean">
        <property name="jndiName" value="fakeRmiServer"/>
        <property name="jndiEnvironment">
            <props>
                <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
                <prop key="java.naming.provider.url">t3://localhost:7003</prop>
            </props>
        </property>
        <property name="serviceInterface" value="lalou.jonathan.FakeInterface"/>
    </bean>

On launching the client side, I get this error:

java.lang.ClassCastException: Cannot narrow remote object ClusterableRemoteRef(-2462835584319760815S:123.123.123.123:[7003,7003,-1,-1,-1,-1,-1]:JonathanApplication:JonathanAdminServer [-2462835584319760815S:123.123.123.123:[7003,7003,-1,-1,-1,-1,-1]:JonathanApplication:JonathanAdminServer/375])/375 to lalou.jonathan.FakeInterface

Complete Stacktrace

java.lang.ClassCastException: Cannot narrow remote object ClusterableRemoteRef(-2462835584319760815S:123.123.123.123:[7003,7003,-1,-1,-1,-1,-1]:JonathanApplication:JonathanAdminServer [-2462835584319760815S:123.123.123.123:[7003,7003,-1,-1,-1,-1,-1]:JonathanApplication:JonathanAdminServer/375])/375 to lalou.jonathan.FakeInterface

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fakeServiceClient' defined in class path resource [lalou/jonathan/java/webservices/jonathan-services.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [lalou.jonathan.java.webservices.FakeServiceWSServer]: Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fakeServiceClient' defined in class path resource [lalou/jonathan/java/webservices/jonathan-rmi-client-spring.xml]: Invocation of init method failed; nested exception is org.springframework.remoting.RemoteLookupFailureException: Could not narrow RMI stub to service interface [lalou.jonathan.FakeInterface]; nested exception is java.lang.ClassCastException: Cannot narrow remote object ClusterableRemoteRef(-2462835584319760815S:123.123.123.123:[7003,7003,-1,-1,-1,-1,-1]:JonathanApplication:JonathanAdminServer [-2462835584319760815S:123.123.123.123:[7003,7003,-1,-1,-1,-1,-1]:JonathanApplication:JonathanAdminServer/375])/375 to lalou.jonathan.FakeInterface
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:883)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:839)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:440)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:221)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:729)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:381)
        at org.apache.cxf.transport.servlet.CXFServlet.loadAdditionalConfig(CXFServlet.java:171)
        at org.apache.cxf.transport.servlet.CXFServlet.updateContext(CXFServlet.java:139)
        at org.apache.cxf.transport.servlet.CXFServlet.loadSpringBus(CXFServlet.java:101)
        at org.apache.cxf.transport.servlet.CXFServlet.loadBus(CXFServlet.java:70)
        at org.apache.cxf.transport.servlet.AbstractCXFServlet.init(AbstractCXFServlet.java:78)
        at (...)
        at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:440)
        at org.mortbay.jetty.servlet.ServletHolder.doStart(ServletHolder.java:263)
        at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
        at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:736)
        at org.mortbay.jetty.servlet.Context.startContext(Context.java:140)
        at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1282)
        at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:518)
        at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:499)
        at org.mortbay.jetty.plugin.Jetty6PluginWebAppContext.doStart(Jetty6PluginWebAppContext.java:115)
        at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
        at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
        at org.mortbay.jetty.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:156)
        at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
        at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
        at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
        at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
        at org.mortbay.jetty.Server.doStart(Server.java:224)
        at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
        at org.mortbay.jetty.plugin.Jetty6PluginServer.start(Jetty6PluginServer.java:132)
        at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:454)
        at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:396)
        at org.mortbay.jetty.plugin.Jetty6RunWarExploded.execute(Jetty6RunWarExploded.java:170)
        at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:569)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:539)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
        at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
        at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
        at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
        at org.codehaus.classworlds.Launcher.main(Launcher.java:375)

Fix

Indeed, this issue appeared with Spring 2.5.4, and was fixed with 2.5.6 release. I let you guess which version I was using…
(cf. Spring 2.5.6 Changelog: * JndiRmiClientInterceptor skips narrowing for RmiInvocationHandler stubs (fixing a regression in 2.5.4)
Therefore, to fix this issue you have to upgrade your Spring version to 2.5.6.

PostHeaderIcon Use a JDBC datasource from WebLogic’s JNDI

Case

Your application is connected to a database. The configuration of the DB connexion is set in a Spring file. You would like the connexion to be set in WebLogic, so that no URL/login/password lays in your source code.

Steps

WebLogic

Create a new data source:

  • go the WebLogic console >
    • JDBC >
      • DataSource >
        • New >
          • set the name, JNDI name (eg: database.jndi.name), DB type  (Oracle, Sybase, …) >
            • Next >
              • Select the driver >
                • Next >
                  • Select the targeted server(s)

This will

  1. create a new file <yourDomain>/config/jdbc/<datasourceName>-XXXX-jdbc.xml.
  2. add a <jdbc-system-resource> block in <yourDomain>/config/config.xml

Spring

Replace the block:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.username}" />
<property name="password" value="${database.password}" />
 </bean>

with:

<jee:jndi-lookup id="dataSource" jndi-name="${database.jndi.name}" />