Thursday, October 31, 2013

Running HTTPS services in Tomcat - java.io.FileNotFoundException: /home/user/.keystore (No such file or directory)

I found today a tomcat server which was complaining about:
Oct 31, 2013 8:26:22 PM org.apache.catalina.startup.SetAllPropertiesRule begin
WARNING: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'SSLCertificateFile' to '/opt/tomcat/certs/sample.com.crt' did not find a matching property.
Oct 31, 2013 8:26:22 PM org.apache.catalina.startup.SetAllPropertiesRule begin
WARNING: [SetAllPropertiesRule]{Server/Service/Connector} Setting property 'SSLCertificateKeyFile' to '/opt/tomcat/certs/bsample.com.key' did not find a matching property.
...
Oct 31, 2013 8:26:23 PM org.apache.tomcat.util.net.jsse.JSSESocketFactory getStore
SEVERE: Failed to load keystore type JKS with path /home/user/.keystore due to /home/user/.keystore 
(No such file or directory)
java.io.FileNotFoundException: /home/user/.keystore (No such file or directory)
I was convinced my APR was installed correctly but Tomcat was giving me the clue lines above (despite I missed them because basically it was INFO level ;)
Oct 31, 2013 8:40:47 PM org.apache.catalina.core.AprLifecycleListener init
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
This was the result of a missing line in setenv:
...
JAVA_OPTS="$JAVA_OPTS \
-Djava.library.path=/usr/local/apr/lib \
...
So make sure the APR path is set in setenv.sh and that you have no INFO stating that APR was not found.

Wednesday, October 30, 2013

On Security: From mod-jk to mod-proxy

Mod_jk is fast, binary protocol which has allowed us to scale Tomcat server java applications for years. However to encrypt the traffic mod-jk configuration will get messy.

Mod_proxy on the other hand is a little bit slower because it works directly on HTTP connectors but being a proxy to regular HTTP(s) it supports encrypted traffic in an easier to configure way.

And since the overhead is really nothing nowadays with the high speed LAN there is no reason that would stop you from migrating from an insecure mod_jk configuration to an encrypted mod_proxy configuration.

Here is what it takes to get your tomcat servers to get the traffic (very simple but fully functional example). Of course as usual there are tons of configuration options for mod_proxy you might need for your needs. All I am presenting here is how to get sticky sessions work. Note that certificates need to be hosted in tomcat (besides apache) as well. In addition note the jvmRoute attribute is still needed the same way it is for modjk.

I am assuming you are using the Apache Portable Runtime (APR) library. Keep in mind that you must not have any warnings about APR. This for example would be a no-no (solve that first installing the library and making sure tomcat library path can reach it):
Oct 31, 2013 8:40:47 PM org.apache.catalina.core.AprLifecycleListener init
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
Read more about this issue here.

In tomcat server.xml
       <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="200" scheme="https" secure="true"
               SSLCertificateFile="/opt/tomcat/certs/sample.com.crt"
               SSLCertificateKeyFile="/opt/tomcat/certs/sample.com.key"
               clientAuth="false" sslProtocol="TLS" />
        
       <Engine name="Catalina" defaultHost="localhost" jvmRoute="sample-app1">
       ...
          <Host name="sample.com"  appBase="sample-app"
          unpackWARs="true" autoDeploy="true"
          deployonstartup="true"/>
        </Engine>        
    
Enable the necessary modules in apache:
$ sudo a2enmod proxy_http
$ sudo a2enmod proxy_balancer
In apache virtual host few things change like everything related to "proxy" and the elimination of any jk directive. Note for example how for static resources we make exceptions through the use of an exclamation mark so those are served directly from Apache instead of Tomcat (instead of the Alias/SetEnvIf Request_URI + no-jk sentences needed for mod_jk).
<VirtualHost sample.com:443>
 ...
 #Make sure Proxy errors are not served back to the user (I use a common page for all 500 errros here)
 ErrorDocument 500 /html/error/503.html
 ...
 SSLProxyEngine on
 ProxyPreserveHost on
 ProxyRequests off

 # Before using the below see http://thinkinginsoftware.blogspot.com/2014/05/mod-proxy-suddenly-failing-with-500-502.html. Use the below only if you are working with *expired* self signed certificates. It should be fine if the cert is not expired though.
 # SSLProxyCheckPeerExpire off

 <Proxy balancer://sample-app>
    ProxySet lbmethod=bybusyness
    BalancerMember https://tomcat1.sample.com:8443 route=sample-app1
    BalancerMember https://tomcat2.sample.com:8443 route=sample-app2
 </Proxy>
ProxyPass /images !
ProxyPass /js !
ProxyPass /css !
ProxyPass /html !
ProxyPass / balancer://sample-app/ stickysession=JSESSIONID|jsessionid scolonpathdelim=On
...
</VirtualHost>

Do not forget to restart apache. To test this configuration you can sniff the traffic now in Apache:
$ sudo tcpdump -i eth0 -X port 8443 > /tmp/del
Then hit the service from curl targettimg a particular cluster node (using -k in case you use a self-signed certificate):
$ curl -i -b "JSESSIONID=.sample-app1" -k "https://sample.com?password=cleartext"
Now inspect the results in apache and you should see no hits for password:
$ grep password /tmp/del

Thursday, October 24, 2013

Connection is read-only. Queries leading to data modification are not allowed SQL Error: 0, SQLState: S1009

JPA specification does not support changing the transaction isolation level and that is the reason HibernateExtendedJpaDialect and IsolationSupportSessionTransactionData classes have been developed in the wild (Disclaimer: I am merely copying and pasting the ones I found below but all credits go their original authors).

We went ahead and tried HibernateExtendedJpaDialect just to notice that randomly entity persistence would fail with:
WARN [org.hibernate.util.JDBCExceptionReporter] - SQL Error: 0, SQLState: S1009
ERROR [org.hibernate.util.JDBCExceptionReporter] - Connection is read-only. Queries leading to data modification are not allowed
When you compare the code of the two classes you can identify extra cleanup which is essential to avoid leaving existing connections in a dirty state. This is very important especially for pooled connections of course:
package com.sample.utils.jpa;

import java.sql.Connection;
import java.sql.SQLException;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;

import org.hibernate.Session;
import org.hibernate.jdbc.Work;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.orm.jpa.vendor.HibernateJpaDialect;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;

public class HibernateExtendedJpaDialect extends HibernateJpaDialect {

    private Logger logger = LoggerFactory.getLogger(HibernateExtendedJpaDialect.class);

    /**
     * This method is overridden to set custom isolation levels on the connection
     * @param entityManager
     * @param definition
     * @return
     * @throws PersistenceException
     * @throws SQLException
     * @throws TransactionException
     */
    @Override
    public Object beginTransaction(final EntityManager entityManager,
            final TransactionDefinition definition) throws PersistenceException,
            SQLException, TransactionException {
        Session session = (Session) entityManager.getDelegate();
        if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) {
            getSession(entityManager).getTransaction().setTimeout(definition.getTimeout());
        }

        entityManager.getTransaction().begin();
        logger.debug("Transaction started");

        session.doWork(new Work() {

            @Override
            public void execute(Connection connection) throws SQLException {
                logger.debug("The connection instance is {}", connection);
                logger.debug("The isolation level of the connection is {} and the isolation level set on the transaction is {}",
                        connection.getTransactionIsolation(), definition.getIsolationLevel());
                DataSourceUtils.prepareConnectionForTransaction(connection, definition);
            }
        });

        return prepareTransaction(entityManager, definition.isReadOnly(), definition.getName());
    }

}
package com.sample.utils.jpa;

import java.sql.Connection;
import java.sql.SQLException;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;

import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.orm.jpa.vendor.HibernateJpaDialect;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;

public class IsolationSupportHibernateJpaDialect extends HibernateJpaDialect {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Logger logger = LoggerFactory.getLogger(IsolationSupportHibernateJpaDialect.class);

    /**
     * This method is overridden to set custom isolation levels on the connection
     * 
     * @param entityManager
     * @param definition
     * @return
     * @throws PersistenceException
     * @throws SQLException
     * @throws TransactionException
     */
    @SuppressWarnings("deprecation")
    @Override
    public Object beginTransaction(final EntityManager entityManager, final TransactionDefinition definition)
        throws PersistenceException, SQLException, TransactionException {
        boolean infoEnabled = false;
        boolean debugEnabled = false;
        Session session = (Session) entityManager.getDelegate();
        if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) {
            getSession(entityManager).getTransaction().setTimeout(definition.getTimeout());
        }

        Connection connection = session.connection();
        infoEnabled = logger.isInfoEnabled();
        debugEnabled = logger.isDebugEnabled();
        if (infoEnabled) {
            logger.info("Connection Info: isolationlevel={} , instance={} ", connection.getTransactionIsolation(), connection);
            logger.info("Transaction Info: IsolationLevel={} , PropagationBehavior={} , Timeout={} , Name={}",
                new Object[] { definition.getIsolationLevel(), definition.getPropagationBehavior(), definition.getTimeout(),
                        definition.getName() });
        }
        if (debugEnabled) {
            logger.debug("The isolation level of the connection is {} and the isolation level set on the transaction is {}",
                connection.getTransactionIsolation(), definition.getIsolationLevel());
        }
        Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(connection, definition);
        if (infoEnabled) {
            logger.info("The previousIsolationLevel {}", previousIsolationLevel);
        }

        entityManager.getTransaction().begin();
        if (infoEnabled) {
            logger.debug("Transaction started");
        }

        Object transactionDataFromHibernateJpaTemplate = prepareTransaction(entityManager, definition.isReadOnly(),
            definition.getName());

        return new IsolationSupportSessionTransactionData(transactionDataFromHibernateJpaTemplate, previousIsolationLevel,
            connection);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.orm.jpa.vendor.HibernateJpaDialect#cleanupTransaction(java.lang.Object)
     */
    @Override
    public void cleanupTransaction(Object transactionData) {
        super.cleanupTransaction(((IsolationSupportSessionTransactionData) transactionData)
            .getSessionTransactionDataFromHibernateTemplate());
        ((IsolationSupportSessionTransactionData) transactionData).resetIsolationLevel();
    }

    private static class IsolationSupportSessionTransactionData {

        private final Object sessionTransactionDataFromHibernateJpaTemplate;
        private final Integer previousIsolationLevel;
        private final Connection connection;

        public IsolationSupportSessionTransactionData(Object sessionTransactionDataFromHibernateJpaTemplate,
            Integer previousIsolationLevel, Connection connection) {
            this.sessionTransactionDataFromHibernateJpaTemplate = sessionTransactionDataFromHibernateJpaTemplate;
            this.previousIsolationLevel = previousIsolationLevel;
            this.connection = connection;
        }

        public void resetIsolationLevel() {
            if (this.previousIsolationLevel != null) {
                DataSourceUtils.resetConnectionAfterTransaction(connection, previousIsolationLevel);
            }
        }

        public Object getSessionTransactionDataFromHibernateTemplate() {
            return this.sessionTransactionDataFromHibernateJpaTemplate;
        }

    }

}

Tuesday, October 22, 2013

RDP into Windows from native Linux or from Linux XRDP session

If you are doing VDI using Ubuntu XRDP you get a nice security gain: No clipboard allowed out of the box. However that might be also an issue for developer productivity.

You can always connect to your Windows based VDI via RDP using rdesktop though, and when doing so you will have access to the clipboard. After all in a Corporate environment most likely you are using Exchange; since Microsoft Outlook is the perfect client for it perhaps it makes sense just to RDP into Windows after all to send those emails sharing some snippets of code with your colleagues.
$ rdesktop -g 90% -d myDomain -u myUser -p - rdp.sample.com
This starts an RDP session in a window taking 90% of the current Linux box.

Security starts with finding bugs

Finding bugs proactively in your application is not a matter of good practices for the sake of following them. It actually has a big impact in risk management. That is the reason I believe no build should be possible if the application is not bug free.

As usual there is a trade-off though. Ranking the bug is important, you know, severity, impact, service class you name it.

FindBugs is an open source project which we have used for ages in the Java world. Together with Maven it allows us to break the build if the code is not bug free. Here is all you need in pom.xml:
            <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>findbugs-maven-plugin</artifactId>
          <configuration>
            <maxRank>15</maxRank>
          </configuration>
          <executions>
            <execution>
              <phase>verify</phase> 
              <goals>
                <goal>check</goal> 
              </goals>
            </execution>
          </executions>
            </plugin>
        </plugins>
        <pluginManagement>
Note that I use maxRank=15 which is the one by default used in the findbugs Eclipse plugin and which I confirmed myself reveals real issues we should not ignore in our code base (The selection of rank will depend on your goals and controls for risk management). As per the documentation "This element matches warnings with a particular bug rank. The value attribute should be an integer value between 1 and 20, where 1 to 4 are scariest, 5 to 9 scary, 10 to 14 troubling, and 15 to 20 of concern bugs". The threshold is another important parameter to setup for this BTW.

Now your typical maven build will fail with information about potential bugs:
...
[INFO] [findbugs:findbugs {execution: findbugs}]
[INFO] Fork Value is true
[INFO] Done FindBugs Analysis....
[INFO] [findbugs:check {execution: default}]
[INFO] BugInstance size is 1
[INFO] Error size is 0
[INFO] Total bugs: 1
[INFO] Dead store to message in com.sample.sayHi(String, Errors, Errors) ["com.sample.HelloWorld"] At HelloWorld.java:[lines 44-267]
...
The above is just saying that the variable "message" is a "dead store". Of course you can skip findbugs to speed up development like in:
mvn clean install -Dfindbugs.skip=true
You might want to exclude some warnings like in the case of generated stubs that provide code you know that works but that follows bad coding practices. In those cases you have XML or annotations available. To use annotations you need to include findbugs as a compile scope dependency.
<dependency>
 <groupId>com.google.code.findbugs</groupId>
 <artifactId>annotations</artifactId>
 <version>2.0.2</version>
 <scope>compile</scope>
</dependency>
Now you can use exclusions like in:
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NM_SAME_SIMPLE_NAME_AS_SUPERCLASS", justification = "Stub autogenerated classes")
@WebServiceClient(name = "Service", targetNamespace = "http://geneva.advent.com", wsdlLocation = "file:/geneva-jax-ws.wsdl")
public class Service extends javax.xml.ws.Service {

    private final static URL SERVICE_WSDL_LOCATION;
...

Monday, October 21, 2013

Change your Windows Domain password from Linux or OSX

GUI method

Login via RDP and press CTRL+ALT+DEL (FN+CTRL+ALT+DELETE on a MAC OSX) and get the menu to change the password.

CLI method

Samba is all you need:
$ smbpasswd -U myUser -r domain.controller.sample.com
In case you do not have smbpasswd available in OSX should I remind brew can help?
$ brew install samba
Here is one typical error you might get if the password does not meet system necessities:
machine dckr5.krco.com rejected the password change: Error was : Password restriction.

From distributed JOTM XAPool to local Tomcat Pool

The old JOTM driver is not longer supported and while other alternatives exist our project did not longer need the complexities of distributed transactions. I thought moving back to pure Spring + JPA + Hibernate was going to be easy however it took a while to get that downgrade right. Here are the steps we followed Eliminate all dependencies from tomcat:
cd /opt/tomcat/lib
mv -f carol-iiop-delegate.jar carol-interceptors.jar howl.jar jotm-core.jar ow2-connector-1.5-spec.jar ow2-jta-1.1-spec.jar xapool-1.6.beta.jar ~/
Remove dependencies from project:

<!-- Remove the jotm completely when confirmed the new config works
        <dependency>
            <groupId>org.ow2.jotm</groupId>
            <artifactId>jotm-core</artifactId>
            <version>2.2.1</version>
            <scope>provided</scope>
            <exclusions>
                <exclusion>
                    <artifactId>jacorb</artifactId>
                    <groupId>org.jacorb</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>jacorb</artifactId>
                    <groupId>org.jacorb</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>jacorb-idl</artifactId>
                    <groupId>org.jacorb</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>commons-logging</artifactId>
                    <groupId>commons-logging</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>howl</artifactId>
                    <groupId>org.objectweb.howl</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>ow2-jta-1.1-spec</artifactId>
                    <groupId>org.ow2.spec.ee</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        -->
Remove the JotmFactoryBean which for some reason we had to include in our code (Most likely we were using a Spring version where it was not available)
/*
 * Copyright 2002-2008 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.transaction.jta;

import javax.naming.NamingException;
import javax.transaction.SystemException;

import org.objectweb.jotm.Current;
import org.objectweb.jotm.Jotm;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;

/**
 * {@link FactoryBean} that retrieves the JTA UserTransaction/TransactionManager
 * for ObjectWeb's JOTM. Will retrieve
 * an already active JOTM instance if found (e.g. if running in JOnAS),
 * else create a new local JOTM instance.
 *
 * 

With JOTM, the same object implements both the * {@link javax.transaction.UserTransaction} and the * {@link javax.transaction.TransactionManager} interface, * as returned by this FactoryBean. * *

A local JOTM instance is well-suited for working in conjunction with * ObjectWeb's XAPool, e.g. with bean * definitions like the following: * *

 * <bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/>
 *
 * <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
 *   <property name="userTransaction" ref="jotm"/>
 * </bean>
 *
 * <bean id="innerDataSource" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
 *   <property name="transactionManager" ref="jotm"/>
 *   <property name="driverName" value="..."/>
 *   <property name="url" value="..."/>
 *   <property name="user" value="..."/>
 *   <property name="password" value="..."/>
 * </bean>
 *
 * <bean id="dataSource" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
 *   <property name="dataSource" ref="innerDataSource"/>
 *   <property name="user" value="..."/>
 *   <property name="password" value="..."/>
 *   <property name="maxSize" value="..."/>
 * </bean>
* * Note that Spring's {@link JtaTransactionManager} will automatically detect * that the passed-in UserTransaction reference also implements the * TransactionManager interface. Hence, it is not necessary to specify a * separate reference for JtaTransactionManager's "transactionManager" property. * *

Implementation note: This FactoryBean uses JOTM's static access method * to obtain the JOTM {@link org.objectweb.jotm.Current} object, which * implements both the UserTransaction and the TransactionManager interface, * as mentioned above. * * @author Juergen Hoeller * @since 21.01.2004 * @see JtaTransactionManager#setUserTransaction * @see JtaTransactionManager#setTransactionManager * @see org.objectweb.jotm.Current */ public class JotmFactoryBean implements FactoryBean, DisposableBean { private Current jotmCurrent; private Jotm jotm; public JotmFactoryBean() throws NamingException { // Check for already active JOTM instance. this.jotmCurrent = Current.getCurrent(); // If none found, create new local JOTM instance. if (this.jotmCurrent == null) { // Only for use within the current Spring context: // local, not bound to registry. this.jotm = new Jotm(true, false); this.jotmCurrent = Current.getCurrent(); } } /** * Set the default transaction timeout for the JOTM instance. *

Should only be called for a local JOTM instance, * not when accessing an existing (shared) JOTM instance. */ public void setDefaultTimeout(int defaultTimeout) { this.jotmCurrent.setDefaultTimeout(defaultTimeout); // The following is a JOTM oddity: should be used for demarcation transaction only, // but is required here in order to actually get rid of JOTM's default (60 seconds). try { this.jotmCurrent.setTransactionTimeout(defaultTimeout); } catch (SystemException ex) { // should never happen } } /** * Return the JOTM instance created by this factory bean, if any. * Will be null if an already active JOTM instance is used. *

Application code should never need to access this. */ public Jotm getJotm() { return this.jotm; } public Object getObject() { return this.jotmCurrent; } public Class getObjectType() { return this.jotmCurrent.getClass(); } public boolean isSingleton() { return true; } /** * Stop the local JOTM instance, if created by this FactoryBean. */ public void destroy() { if (this.jotm != null) { this.jotm.stop(); } } }

Include in your project the code for IsolationSupportSessionTransactionData custom class (Just Google it) which is supposed to take care of custom levels of transaction isolations as they are not supported by the JPA specification. Include JTA dependency in the project:
        <dependency>
         <groupId>javax.transaction</groupId>
         <artifactId>jta</artifactId>
         <version>1.1</version>
        </dependency>
File persistence.xml changes:
    ...
    <!-- Use RESOURCE_LOCAL instead of JTA -->
    <persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
    ...
            <!-- Remove completely the below once JOTM is removed and project is working
            <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JOTMTransactionManagerLookup" />
            
            <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/> 
            
            <property name="hibernate.transaction.flush_before_completion" value="false" />
            <property name="hibernate.transaction.auto_close_session" value="false" />
            <property name="hibernate.current_session_context_class" value="jta" />
            <property name="hibernate.connection.release_mode" value="auto" />
            -->
    ...
    
File applicationContext.xml changes (Spring Application Context file):
    ...
    <!-- Remove all XA related configuration as soon as we confirm there are no issues with the new pool -->
    <!-- first XA data source -->
    <!-- 
    <bean id="innerDataSource" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
        <property name="transactionManager" ref="jotm" />
        <property name="driverName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>
    -->
    <!-- first XA data source pool -->
    <!-- 
    <bean id="dataSource" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
        <property name="transactionManager" ref="jotm" />
        <property name="dataSource" ref="innerDataSource" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="minSize" value="${jdbc.minSize}" />
        <property name="maxSize" value="${jdbc.maxSize}" />
        <property name="checkLevelObject" value="2"/>
        <property name="sleepTime" value="${jdbc.sleepTime}" />
        <property name="lifeTime" value="${jdbc.lifeTime}" />
        <property name="jdbcTestStmt" value="SELECT NOW()"/>
    </bean>
     -->
    ...
        <!--  Data source not pooled -->
 <bean id="dataSourceTemplate" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
     <property name="driverClassName" value="${jdbc.driverClassName}" />
     <property name="url" value="${jdbc.url}" />
     <property name="username" value="${jdbc.username}" />
     <property name="password" value="${jdbc.password}" />
 </bean>

 <!--  Connection pool data source. -->
     <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
      <!-- Refer to a separately created bean as a data source template to work around a quirk of Tomcat's class loader. -->
     <property name="dataSource" ref="dataSourceTemplate" />
     <property name="initialSize" value="${jdbc.minSize}" />
            <property name="maxActive" value="${jdbc.maxSize}" />
            <property name="timeBetweenEvictionRunsMillis" value="${jdbc.sleepTime}" />
            <property name="maxAge" value="${jdbc.lifeTime}" />
            <property name="validationQuery" value="SELECT 1"/>
 </bean>
     ...
    
    
    
    
    
    
    
    
        
    
    ...
    <!-- Use a JPA Dialect able to handle different transaction isolation levels -->
    <bean id="Emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        ...
        <property name="jpaDialect">
            <!-- <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" /> -->
            <bean class="com.sample.jpa.HibernateExtendedJpaDialect" />
        </property>
    ...
        <!--  Stop using the JOTM transaction manager for @Transactional -->
    <!-- <tx:annotation-driven transaction-manager="jtaTransactionManager" proxy-target-class="false" />
     -->
     
    <tx:annotation-driven transaction-manager="transactionManager" />
    

Friday, October 18, 2013

Linux or Solaris bash: rm: Arg list too long

Let us remove all files following a wildcard:
$ rm /tmp/log*
bash: /usr/bin/rm: Arg list too long
Commands find and xargs to the rescue:
$ find /tmp -name "logMonitor*" | xargs rm

Wednesday, October 09, 2013

Ubuntu Apache security patches

The most important command to run when looking at current version of apache is not actually the below:
$ apache2 -v
Server version: Apache/2.2.22 (Ubuntu)
Server built:   Jul 12 2013 13:37:15
The above will tell you not much. You need to inspect further:
$ sudo apt-cache policy apache2
apache2:
  Installed: 2.2.22-1ubuntu1
  Candidate: 2.2.22-1ubuntu1
  Version table:
 *** 2.2.22-1ubuntu1 0
        500 http://us.archive.ubuntu.com/ubuntu/ precise/main amd64 Packages
        100 /var/lib/dpkg/status
This is actually telling us that the server is vulnerable. As a minimum we need 2.2.22-1ubuntu2. What should we do? Simple:
$ sudo apt-get update
$ sudo apt-get upgrade
Which BTW will most likely address other security issues because we will be moving from an old Ubuntu version, for example:
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.04
DISTRIB_CODENAME=precise
DISTRIB_DESCRIPTION="Ubuntu 12.04 LTS"
To a patched version of it:
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.04
DISTRIB_CODENAME=precise
DISTRIB_DESCRIPTION="Ubuntu 12.04.3 LTS"

Monday, October 07, 2013

Client Java applications performance

When it comes to a Java client application you better use the "-client" flag and the correct garbage collector. Failure to do so will result in slower responses and more memory consumption:
-client -XX:+UseSerialGC
Those running processes like Talend Java based ETLs encapsulated in a shell script should use the above flags for example.

Wednesday, October 02, 2013

lastcomm and turning accounting on in Solaris

The lastcomm command will not work in Solaris:
$ lastcomm
/var/adm/pacct: No such file or directory
Unless you turn accounting on:
$ /usr/lib/acct/turnacct on

Solaris find newest file

Not as simple as it would be in Linux ;-)
$ find /my/directory/path/ -name "someOptionalPatternToFilter" -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7," ",$9 }' | sort | tail -1 | awk '{print $3}'

Followers