Freitag, 6. April 2012

NoSuchMethodError when having an abstract class with eclipse link

For example you have these 3 classes

@Entity
@Table(name = "book")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "clazz", discriminatorType = DiscriminatorType.STRING)
public abstract class Book implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    @Column(name = "id")
    private Long id;

    @Column(name = "title")
    private String title;

    @Column(name = "ISBN")
    private String isbn;
 
}

@Entity(name = "PaperBook")
@DiscriminatorValue(value = "PaperBook")
public class PaperBook extends Book {

    @Column(name = "pages")
    private Integer pages;
}

@Entity(name = "AudioBook")
@DiscriminatorValue(value = "AudioBook")
public class AudioBook extends Book {

    @Column(name = "medium")
    private String medium;

    @Column(name = "length_in_minutes")
    private Integer lengthInMinutes;
}
I do not write out all getter, setter, equals, hashCode, toString Methods because it is just an example.

Then you are going to see this exception:
java.lang.NoSuchMethodError: de.mischur.library.entities.Book.(Lorg/eclipse/persistence/internal/descriptors/PersistenceObject;)V
 at de.mischur.library.entities.PaperBook.(PaperBook.java)
 at de.mischur.library.entities.PaperBook._persistence_new(PaperBook.java)
 at org.eclipse.persistence.internal.descriptors.PersistenceObjectInstantiationPolicy.buildNewInstance(PersistenceObjectInstantiationPolicy.java:30)
 at org.eclipse.persistence.descriptors.ClassDescriptor.selfValidationAfterInitialization(ClassDescriptor.java:3870)
 at org.eclipse.persistence.descriptors.ClassDescriptor.validateAfterInitialization(ClassDescriptor.java:5688)
 at org.eclipse.persistence.descriptors.ClassDescriptor.postInitialize(ClassDescriptor.java:3547)
 at org.eclipse.persistence.descriptors.ClassDescriptor.postInitialize(ClassDescriptor.java:3447)
 at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:526)
 at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:476)
 at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:435)
 at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:676)
 at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.login(DatabaseSessionImpl.java:634)
 at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:208)
 at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:488)
 at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getDatabaseSession(EntityManagerFactoryDelegate.java:188)
 at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:277)
 at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:294)
 at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:272)
 at org.springframework.orm.jpa.JpaTransactionManager.createEntityManagerForTransaction(JpaTransactionManager.java:445)
 at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:366)
 at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
 at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.startTransaction(TransactionalTestExecutionListener.java:513)
 at org.springframework.test.context.transaction.TransactionalTestExecutionListener.startNewTransaction(TransactionalTestExecutionListener.java:271)
 at org.springframework.test.context.transaction.TransactionalTestExecutionListener.beforeTestMethod(TransactionalTestExecutionListener.java:164)
 at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:358)
 at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
 at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
 at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
 at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
 at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
 at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
 at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
So far I know until now this problem occurs when eclipselink is weaving your class outside of an JEE container.

To avoid that problem you should disable internal weaving your persistence.xml file
 
or set it via property map
propertiesMap.put(PersistenceUnitProperties.WEAVING_INTERNAL, "false");
or when using spring you can use the earlier described ExtendedEclipseLinkJpaVendorAdapter
and set the property in the spring config file
    
        
    

Dienstag, 3. April 2012

Best practice for maven site generation in a multi module environment

One example how to decrease the time for creating the site of a maven multi module project
whizbang
|-- pom.xml
|-- core
|   `-- pom.xml
|-- gui
|   `-- pom.xml
|-- jmx
|   `-- pom.xml
`-- src
in the pom.xml from whizbang you normally have something like this:
            
                core
                gui
                jmx
            
this config would always generate the sites for all sub modules when you call mvn site in the folder of whizbang. depending on the size of the project and configured plugins this can be very time consuming. so we decided to work only on profiles. We removed the module section completely and defined 2 profiles.
    
        
            default
            
                true
            
            
                core
                gui
                jmx
            
        
        
            writeDoc
            
                false
            
            
                
                    
                        org.apache.maven.plugins
                        maven-site-plugin
                        3.0
                        
                            ${site.output.directory}
                            
                                
                                    org.apache.maven.plugins
                                    maven-project-info-reports-plugin
                                    2.4
                                    
                                        false
                                        false
                                    
                                    
                                        index
                                    
                                
                            
                        
                    
                            
            
        
    
mvn clean install has the default behaviour. And when you want to write doc and test the site locally you can easily use this command mvn -P writeDoc site this generates only the site for whizbang project and not for sub projects.

Montag, 2. April 2012

Extend existing EclipseLinkJpaVendorAdapter

The existing EclipseLinkJpaVendorAdapter allows you to set some basic functions. Most of the parameters are not configurable over the existing one. Here’s my extended version:
package de.mischur.utils;

import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;

public class ExtendedEclipseLinkJpaVendorAdapter extends EclipseLinkJpaVendorAdapter {

    public static final Logger log = LoggerFactory.getLogger(ExtendedEclipseLinkJpaVendorAdapter.class);

    private String targetServer = null;
    private String logger = null;
    private String profiler = null;

    private String cacheCoordinationNamingService = null;

    private String cacheCoordinationProtocol = null;

    private String jndiUser = null;

    private String jndiPwd = null;

    private String propagateAsynchronously = null;

    private String removeConnectionOnError = null;

    private String rmiUrl = null;

    private String rmiAnnouncementDelay = null;

    private String rmiMulticastGroup = null;

    private String rmiMulticastGroupPort = null;

    private String packetTime2Live = null;

    private String jmsTopic = null;

    private String jmsFactory = null;

    private String jmsHost = null;

    private String jmsReusePublisher = null;


    @Override
    public Map getJpaPropertyMap() {
        Map jpaProperties = super.getJpaPropertyMap();

        if (StringUtils.isNotEmpty(targetServer)) {
            jpaProperties.put(PersistenceUnitProperties.TARGET_SERVER, targetServer);
        }
        if (StringUtils.isNotEmpty(logger)) {
            jpaProperties.put(PersistenceUnitProperties.LOGGING_LOGGER, logger);
        }
        if (StringUtils.isNotEmpty(profiler)) {
            jpaProperties.put(PersistenceUnitProperties.PROFILER, profiler);
        }

        if (StringUtils.isNotEmpty(cacheCoordinationProtocol)) {
            jpaProperties.put(PersistenceUnitProperties.COORDINATION_PROTOCOL, cacheCoordinationProtocol);

            if (StringUtils.isNotEmpty(cacheCoordinationNamingService)) {
                jpaProperties.put(PersistenceUnitProperties.COORDINATION_NAMING_SERVICE, cacheCoordinationNamingService);
            }
            if (StringUtils.isNotEmpty(jndiUser)) {
                jpaProperties.put(PersistenceUnitProperties.COORDINATION_JNDI_USER, jndiUser);
            }

            if (StringUtils.isNotEmpty(jndiPwd)) {
                jpaProperties.put(PersistenceUnitProperties.COORDINATION_JNDI_PASSWORD, jndiPwd);
            }

            if (StringUtils.isNotEmpty(propagateAsynchronously)) {
                jpaProperties.put(PersistenceUnitProperties.COORDINATION_ASYNCH, propagateAsynchronously);
            }

            if (StringUtils.equalsIgnoreCase("rmi", cacheCoordinationProtocol)) {
                if (StringUtils.isNotEmpty(rmiUrl)) {
                    jpaProperties.put(PersistenceUnitProperties.COORDINATION_RMI_URL, rmiUrl);
                }
                if (StringUtils.isNotEmpty(packetTime2Live)) {
                    jpaProperties.put(PersistenceUnitProperties.COORDINATION_RMI_PACKET_TIME_TO_LIVE, packetTime2Live);
                }

                if (StringUtils.isNotEmpty(rmiMulticastGroup)) {
                    jpaProperties.put(PersistenceUnitProperties.COORDINATION_RMI_MULTICAST_GROUP, rmiMulticastGroup);
                }

                if (StringUtils.isNotEmpty(rmiMulticastGroupPort)) {
                    jpaProperties.put(PersistenceUnitProperties.COORDINATION_RMI_MULTICAST_GROUP_PORT, rmiMulticastGroupPort);
                }

                if (StringUtils.isNotEmpty(rmiAnnouncementDelay)) {
                    jpaProperties.put(PersistenceUnitProperties.COORDINATION_RMI_ANNOUNCEMENT_DELAY, rmiAnnouncementDelay);
                }
                if (StringUtils.isNotEmpty(removeConnectionOnError)) {
                    jpaProperties.put(PersistenceUnitProperties.COORDINATION_REMOVE_CONNECTION, removeConnectionOnError);
                }

            }
            if (StringUtils.equalsIgnoreCase("jms", cacheCoordinationProtocol)) {
                if (StringUtils.isNotEmpty(jmsTopic)) {
                    jpaProperties.put(PersistenceUnitProperties.COORDINATION_JMS_TOPIC, jmsTopic);
                }
                if (StringUtils.isNotEmpty(jmsFactory)) {
                    jpaProperties.put(PersistenceUnitProperties.COORDINATION_JMS_FACTORY, jmsFactory);
                }

                if (StringUtils.isNotEmpty(jmsHost)) {
                    jpaProperties.put(PersistenceUnitProperties.COORDINATION_JMS_HOST, jmsHost);
                }
                if (StringUtils.isNotEmpty(jmsReusePublisher)) {
                    jpaProperties.put(PersistenceUnitProperties.COORDINATION_JMS_REUSE_PUBLISHER, jmsReusePublisher);
                }
            }
        }

 if (StringUtils.isNotEmpty(weavingInternal)) {
     jpaProperties.put(PersistenceUnitProperties.WEAVING_INTERNAL, Boolean.toString(BooleanUtils.toBoolean(weavingInternal)));
 }

        if (log.isDebugEnabled()) {
            log.debug("After setting own props");
            for (String key : jpaProperties.keySet()) {
                log.debug(key + "=" + jpaProperties.get(key));
            }
        }
        return jpaProperties;
    }

    public String getTargetServer() {
        return targetServer;
    }

    /**
     * Overrides the property <property>eclipselink.target-server</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#TARGET_SERVER
     */
    public void setTargetServer(String targetServer) {
        this.targetServer = targetServer;
    }

    public String getLogger() {
        return logger;
    }

    /**
     * Overrides the property <property>eclipselink.logging.logger</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#LOGGING_LOGGER
     */
    public void setLogger(String logger) {
        this.logger = logger;
    }

    public String getProfiler() {
        return profiler;
    }

    /**
     * Overrides the property <property>eclipselink.profiler</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#PROFILER
     */
    public void setProfiler(String profiler) {
        this.profiler = profiler;
    }

    public String getCacheCoordinationNamingService() {
        return cacheCoordinationNamingService;
    }

    public void setCacheCoordinationNamingService(String cacheCoordinationNamingService) {
        this.cacheCoordinationNamingService = cacheCoordinationNamingService;
    }

    public String getRemoveConnectionOnError() {
        return removeConnectionOnError;
    }

    /**
     * Overrides the property <property>eclipselink.cache.coordination.remove-connection-on-error</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#COORDINATION_REMOVE_CONNECTION
     */
    public void setRemoveConnectionOnError(String removeConnectionOnError) {
        this.removeConnectionOnError = removeConnectionOnError;
    }

    public String getCacheCoordinationProtocol() {
        return cacheCoordinationProtocol;
    }

    /**
     * Overrides the property <property>eclipselink.cache.coordination.protocol</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#COORDINATION_PROTOCOL
     */
    public void setCacheCoordinationProtocol(String cacheCoordinationProtocol) {
        this.cacheCoordinationProtocol = cacheCoordinationProtocol;
    }

    public String getRmiUrl() {
        return rmiUrl;
    }

    /**
     * Overrides the property <property>eclipselink.cache.coordination.rmi.url</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#COORDINATION_RMI_URL
     */
    public void setRmiUrl(String rmiUrl) {
        this.rmiUrl = rmiUrl;
    }

    public String getJndiUser() {
        return jndiUser;
    }

    /**
     * Overrides the property <property>eclipselink.cache.coordination.jndi.user</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#COORDINATION_JNDI_USER
     */
    public void setJndiUser(String jndiUser) {
        this.jndiUser = jndiUser;
    }

    public String getJndiPwd() {
        return jndiPwd;
    }

    /**
     * Overrides the property <property>eclipselink.cache.coordination.jndi.password</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#COORDINATION_JNDI_PASSWORD
     */
    public void setJndiPwd(String jndiPwd) {
        this.jndiPwd = jndiPwd;
    }

    public String getPropagateAsynchronously() {
        return propagateAsynchronously;
    }

    /**
     * Overrides the property <property>eclipselink.cache.coordination.propagate-asynchronously</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#COORDINATION_ASYNCH
     */
    public void setPropagateAsynchronously(String propagateAsynchronously) {
        this.propagateAsynchronously = propagateAsynchronously;
    }

    public String getRmiAnnouncementDelay() {
        return rmiAnnouncementDelay;
    }

    /**
     * Overrides the property <property>eclipselink.cache.coordination.rmi.announcement-delay</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#COORDINATION_RMI_ANNOUNCEMENT_DELAY
     */
    public void setRmiAnnouncementDelay(String rmiAnnouncementDelay) {
        this.rmiAnnouncementDelay = rmiAnnouncementDelay;
    }

    public String getRmiMulticastGroup() {
        return rmiMulticastGroup;
    }

    /**
     * Overrides the property <property>eclipselink.cache.coordination.rmi.multicast-group</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#COORDINATION_RMI_MULTICAST_GROUP
     */
    public void setRmiMulticastGroup(String rmiMulticastGroup) {
        this.rmiMulticastGroup = rmiMulticastGroup;
    }

    public String getRmiMulticastGroupPort() {
        return rmiMulticastGroupPort;
    }

    /**
     * Overrides the property <property>eclipselink.cache.coordination.rmi.multicast-group.port</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#COORDINATION_RMI_MULTICAST_GROUP_PORT
     */
    public void setRmiMulticastGroupPort(String rmiMulticastGroupPort) {
        this.rmiMulticastGroupPort = rmiMulticastGroupPort;
    }

    public String getPacketTime2Live() {
        return packetTime2Live;
    }

    /**
     * Overrides the property <property>eclipselink.cache.coordination.rmi.packet-time-to-live</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#COORDINATION_RMI_PACKET_TIME_TO_LIVE
     */
    public void setPacketTime2Live(String packetTime2Live) {
        this.packetTime2Live = packetTime2Live;
    }

    public String getJmsTopic() {
        return jmsTopic;
    }

    /**
     * Overrides the property <property>eclipselink.cache.coordination.jms.topic</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#COORDINATION_JMS_TOPIC
     */
    public void setJmsTopic(String jmsTopic) {
        this.jmsTopic = jmsTopic;
    }

    public String getJmsFactory() {
        return jmsFactory;
    }

    /**
     * Overrides the property <property>eclipselink.cache.coordination.jms.factory</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#COORDINATION_JMS_FACTORY
     */
    public void setJmsFactory(String jmsFactory) {
        this.jmsFactory = jmsFactory;
    }

    public String getJmsHost() {
        return jmsHost;
    }

    /**
     * Overrides the property <property>eclipselink.cache.coordination.jms.host</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#COORDINATION_JMS_HOST
     */
    public void setJmsHost(String jmsHost) {
        this.jmsHost = jmsHost;
    }

    public String getJmsReusePublisher() {
        return jmsReusePublisher;
    }

    /**
     * Overrides the property <eclipselink.cache.coordination.jms.reuse-topic-publisher</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#COORDINATION_JMS_REUSE_PUBLISHER
     */
    public void setJmsReusePublisher(String jmsReusePublisher) {
        this.jmsReusePublisher = jmsReusePublisher;
    }

    public String getWeavingInternal() {
 return weavingInternal;
    }

    /**
     * Overrides the property <eclipselink.weaving.internal</property> from persistence.xml
     * @see org.eclipse.persistence.config.PersistenceUnitProperties#WEAVING_INTERNAL
     */
    public void setWeavingInternal(String weavingInternal) {
 this.weavingInternal = weavingInternal;
    }

}
And the related xml declaration:
  
    Config for EclipseLink
    
    
    
    
  

Freitag, 30. März 2012

EclipseLinkSessionLogger with SLF4J

Here is the source code for your own Slf4JEclipseLinkSessionLogger. I found this in one mailing list.
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.logging.SessionLogEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Slf4JEclipseLinkSessionLogger extends AbstractSessionLog implements SessionLog {

    public static final Logger LOG = LoggerFactory.getLogger(Slf4JEclipseLinkSessionLogger.class);

    @Override
    public void log(SessionLogEntry sle) {

        switch (sle.getLevel()) {

        case SEVERE:
            LOG.error(buildLogMessage(sle));
            break;

        case WARNING:
            LOG.warn(buildLogMessage(sle));
            break;

        case INFO:
            LOG.info(buildLogMessage(sle));
            break;

        default:
            LOG.debug(buildLogMessage(sle));
        }
        if (sle.hasException()) {
            LOG.error("Exception in EclipseLink", sle.getException());
        }
    }

    private String buildLogMessage(SessionLogEntry sle) {
        StringBuilder b = new StringBuilder();
        b.append("message=").append(sle.getMessage());
        if (sle.getSession() != null && sle.getSession().getName() != null) {
            b.append("\n sessionName=").append(sle.getSession().getName());
        }
        if (sle.getThread() != null && sle.getThread().getName() != null) {
            b.append("\n threadName=").append(sle.getThread().getName());
        }
        if (sle.hasException()) {
            b.append("\n Exception=").append(sle.getException().getMessage());
        }

        return b.toString();
    }

}

Montag, 26. März 2012

Apache Maven Fluido Skin

In the apache announce list they developers from maven announced that the maven skin Fluido has a new version. So I tried this skin out again. It looks some one more fancy then other skins but still version 1.2 has a bug in the breadcrumb section of generated html files.

To enable the new skin open your site.xml file.

After the body section you add these tag’s

    org.apache.maven.skins
    maven-fluido-skin
    1.2
  

For more information what you can do check out the skin page Maven Fluido Skin
Now to come again to my problem: When you do not define a breadcrumb in the site.xml the layout is destroyed.
how it should look like:
how it is without breadcrumbs:

To have it nice we decided in our team to use the main items from the menu as bread crumbs.

The javascript which shows the current place [path] of your folder is still missing by default.

Donnerstag, 22. März 2012

Problem with Pagination and Ordering in JPA

Some days back we implemented ordering for different columns. There we faced the problem that result what is displayed is not the same as data is in the database. So we all thought we do not set the pagination parameters correctly or it is a problem in eclipse link.

I googled a little bit around. The problem is not pagination or eclipse link. The problem is how pagination works at all. Even when you fire the SQL directly to the database the problem occurs.

You have to use a unique id as well for ordering when pagination is used that the database will always sent the data back in the correct order.

see also Bug on using pagination on Oracle?

Dienstag, 20. März 2012

Speed up compile time for GWT

Compilation takes long time for GWT projects. The reason for it is the permutation for different browsers.
Permutation means the GWT compiler generates JS and HTML files for different browser by default.
This can be really annoying when you are developing and you only want to see the result in the IE or Firefox

To enable permutation for only one browser do the the following:
Open file XXXXX.gwt.xml of your application.
add this line:
  
possible values are:
  • ie6 = Internet Explorer 6
  • ie8 = Internet Explorer 8
  • ie9 = Internet Explorer 9
  • gecko1_8 = Firefox
  • safari = safari and chrome
  • opera = opera
To enable permutation for 2 browsers write something like this:
  
  
This would generate files for IE8 and Firefox.

Some time measurements from our GWT project
only one browser:
- GWT compilation time: 39.436s
- total time for mvn clean install in GWT project: 1:35.403s

all browsers:
- GWT compilation time: 58.435s
- total time for mvn clean install in GWT project: 1:59.730s

20 seconds are worth the optimization.
You only have to keep in mind to NOT commit these changes to your source code repository when the real application should run on different browsers.

Freitag, 16. März 2012

pretty format a xml string

do you get most of the time xml not in a human readable format?

this snippet can help:
private String formatXml(String xml) {
        try {
            Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();
            serializer.setOutputProperty(OutputKeys.INDENT, "yes");
            serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
            Source xmlSource = new SAXSource(new InputSource(new ByteArrayInputStream(xml.getBytes())));
            StreamResult res = new StreamResult(new ByteArrayOutputStream());
            serializer.transform(xmlSource, res);
            return new String(((ByteArrayOutputStream) res.getOutputStream()).toByteArray());
        } catch (Exception e) {
            return xml;
        }
    }

Donnerstag, 15. März 2012

Try to write more - promise

Hi all

I know I stopped writing last year in April.

I try to write now more constantly! Promise! :-)

Mittwoch, 14. März 2012

How to configure tomcat to use slf4j and logback

This section explains how to configure Tomcat to use slf4j rather than java.util.logging for all Tomcat's internal logging.

First of all it is nothing special because it will use the log4j over slf4 and logback.


  1. Download tomcat-juli.jar and tomcat-juli-adapters.jar that are available as an "extras" component for Tomcat. See Additional Components documentation for details.

  2. Put the following jars into $CATALINA_HOME/lib.

    • log4j-over-slf4j-1.6.4.jar

    • logback-classic-1.0.0.jar

    • logback-core-1.0.0.jar

    • slf4j-api-1.6.4.jar

    • tomcat-juli-adapters.jar



  3. Replace $CATALINA_HOME/bin/tomcat-juli.jar with tomcat-juli.jar from "extras"

  4. Delete $CATALINA_BASE/conf/logging.properties to prevent java.util.logging generating zero length log files.

  5. Add logback.xml into $CATALINA_HOME/lib.
    Example:
    <configuration>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
    ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
    <!--
    <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    -->
    <pattern>%d{HH:mm:ss.SSS} %-5level %logger{50} - %msg%n</pattern>
    </encoder>
    </appender>

    <root level="INFO">
    <appender-ref ref="STDOUT" />
    </root>
    </configuration>