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