Как настроить динамическое плетение с помощью EclipseLink & Spring? - PullRequest
10 голосов
/ 21 июня 2011

Как настроить динамическое плетение с помощью EclipseLink & Spring? Прямо сейчас я пытаюсь заставить это работать с тестом Junit, но позже мне нужно будет заставить его работать с Tomcat (мой отдел стандартизировался на нем около 10 лет).

У меня две основные проблемы:

1. Spring хочет ткача времени:

Исключение:

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:181)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
<snip>
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.weaving.AspectJWeavingEnabler#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
<snip>
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
<snip>
Caused by: java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
    at org.springframework.context.weaving.DefaultContextLoadTimeWeaver.setBeanClassLoader(DefaultContextLoadTimeWeaver.java:91)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1437)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1408)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    ... 44 more

Я могу это исправить, настроив Spring Instrumentation:

JVM parameter:
-javaagent:/path/to/org.springframework.instrument-3.1.0.M2.jar

2. Eclipselink не удовлетворен Spring Instrumentation:

Ошибка:

(similar error messages repeated many times)

[EL Severe]: 2011-06-20 16:12:57.951--ServerSession(979781372)--Local Exception Stack: 
Exception [EclipseLink-0] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions: 
---------------------------------------------------------

Exception [EclipseLink-60] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The method [_persistence_set_shellType_vh] or [_persistence_get_shellType_vh] is not defined in the object [ps.entity.JudicialArtifactFamily].
Internal Exception: java.lang.NoSuchMethodException: ps.entity.JudicialArtifactFamily._persistence_get_shellType_vh()
Mapping: org.eclipse.persistence.mappings.ManyToOneMapping[shellType]
Descriptor: RelationalDescriptor(ps.entity.JudicialArtifactFamily --> [DatabaseTable(JUDICIAL_ARTIFACT_FAMILY)])

Exception [EclipseLink-218] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: A NullPointerException would have occurred accessing a non-existent weaved _vh_ method [_persistence_get_shellType_vh].  The class was not weaved properly - for EE deployments, check the module order in the application.xml deployment descriptor and verify that the module containing the persistence unit is ahead of any other module that uses it.

Я пытался исправить это с помощью ткача EclipseLink:

-javaagent:/dev/tools/javaagents/eclipselink.jar

Но тогда я получаю то же исключение из задачи № 1.

Библиотечные версии

Я использую:

  • Java 1.6.0_24
  • EclipseLink 2.2.0.v20110202-r8913
  • Пружина 3.1.0 М2

Файлы конфигурации

Вот мой файл persistence.xml:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             version="2.0"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="eclipseLinkHashPU" transaction-type="RESOURCE_LOCAL">
        <class>ps.entity.Artifact</class>
        <class>ps.entity.JudicialArtifactFamily</class>
        <class>ps.entity.ShellType</class>
        <class>ps.entity.SourceArtifact</class>
        <class>ps.entity.Health</class>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>    
            <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
            <property name="eclipselink.ddl-generation.output-mode" value="database"/>
        </properties>
    </persistence-unit>
</persistence>

Вот мое application.xml:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jaxrs="http://cxf.apache.org/schema/jaxrs" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/tx 
           http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://cxf.apache.org/schema/jaxrs
           http://cxf.apache.org/schema/jaxrs.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd          
           http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">

    <context:component-scan base-package="ps">
    </context:component-scan>

    <context:load-time-weaver/>

    <alias alias="entityManagerFactory" name="eclipseLinkEntityManagerFactory"/>

    <bean id="eclipseLinkEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceXmlLocation" value="classpath:eclipselink-persistence.xml" />
        <property name="persistenceUnitName" value="eclipseLinkHashPU" />
        <property name="jpaPropertyMap">
            <map>
                <entry key="eclipselink.logging.level" value="Severe"/>
                <entry key="eclipselink.target-database" value="org.eclipse.persistence.platform.database.oracle.OraclePlatform"/>
                <entry key="javax.persistence.nonJtaDataSource" value-ref="hash1DataSource"/>
                <!-- it's not good that I'm turning weaving off -->
                <!-- <entry key="eclipselink.weaving" value="false"/> -->
            </map>
        </property>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
                <property name="databasePlatform" value="oracle" />
                <property name="database" value="ORACLE" />
                <property name="generateDdl" value="true" />
                <property name="showSql" value="true" />
            </bean>
        </property>
    </bean>

    <!-- datasources, etc -->
</beans>

Ответы [ 4 ]

4 голосов
/ 21 июня 2011

Для ткачества с помощью Spring я считаю, что вам нужно что-то вроде

<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
    <property name="defaultDataSource" ref="dataSource" />
    <property name="dataSources">
        <map>
            <entry>
                <key>
                    <value>jdbc/__default</value>
                </key>
                <ref bean="dataSource" />
            </entry>
            <entry>
                <key>
                    <value>jdbc/jta</value>
                </key>
                <ref bean="dataSource" />
            </entry>
        </map>
    </property>
    <property name="loadTimeWeaver">
        <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
    </property>
</bean>

Здесь есть некоторая информация,

http://wiki.eclipse.org/EclipseLink/Examples/JPA/JPASpring

Убедитесь, что у вас нет доступа к вашемуклассы перед доступом к контексту Spring.

Другое решение - использовать статическое переплетение.

2 голосов
/ 22 октября 2012

Теперь я также использую EclipseLink 2.2 и Spring 3.1, как показано ниже.Моя конфигурация немного отличается от вашей.В вашем eclipseLinkEntityManagerFactory нет конфигурации loadTimeWeaver.Я думаю, все будет в порядке, если вы используете, как показано ниже.

Пожалуйста, попробуйте, как показано ниже, с вашей Oracle DB информацией ..

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:faces="http://www.springframework.org/schema/faces"
       xmlns:int-security="http://www.springframework.org/schema/integration/security"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:sec="http://www.springframework.org/schema/security"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/integration/security http://www.springframework.org/schema/integration/security/spring-integration-security-2.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
        http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/faces http://www.springframework.org/schema/faces/spring-faces-2.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">

    <context:annotation-config/>    
    <context:component-scan base-package="your-package"/>
    <tx:annotation-driven transaction-manager="transactionManager" />
    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="your-driver"/>
        <property name="url" value="your-database-url"/>
        <property name="username" value="your-username"/>
        <property name="password" value="your-passowrd"/>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!--        <property name="dataSource" ref="dataSource"/>-->
        <property name="persistenceUnitName" value="your-persistence-unit-name"/>
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect"/>
        </property>
        <property name="jpaPropertyMap">
            <props>
                <prop key="eclipselink.weaving">false</prop>
            </props>
        </property>

        <property name="loadTimeWeaver">
            <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver">
            </bean>
        </property>
    </bean>

    <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
        <property name="databasePlatform" value="org.eclipse.persistence.platform.database.OraclePlatform" />
        <property name="generateDdl" value="false"/>
        <property name="showSql" value="true"/>
    </bean>
</beans>
1 голос
/ 25 июля 2014

Принимая во внимание инструментарий для модульных тестов, его можно добавить в качестве аргумента VM в плагин maven-surefire-plugin

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <argLine>-javaagent:lib/test/spring-instrument-4.0.2.RELEASE.jar</argLine>
    </configuration>
</plugin>

при условии, что банка с пружинным прибором была помещена в соответствующее место.

(Для этого следующую зависимость можно временно добавить в проект pom.xml

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-instrument</artifactId>
    <scope>test</scope>
</dependency>

и затем после сборки соответствующий артефакт копируется из локального каталога .m2 в каталог lib / test проекта.)

1 голос
/ 28 мая 2012

скопируйте org.springframework.instrument-3.1.0.M2.jar в каталог tomcat/lib и попробуйте снова.

...