2016-06-14 3 views
0

Я воспользовался всеми возможностями, которые пытались запустить мой проект на Tomcat и нарезать модель (геттеры) и сплести их с помощью AspectJ Load Time Weaver. В принципе, я выполнил все шаги в документации весны http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-atconfigurable. Я также придерживался того же подхода, упомянутого Lazy/Eager loading/fetching in Neo4j/Spring-Data. Мой проект разделен на два основных проекта: - core: spring-data-neo4j (репозиторий и конфигурация), доменная модель в выделенном пакете, LoggingAspect и LazyLoadingAspect. постскриптум Я не использую какую-либо конфигурацию в файлах XML. Я использую только аннотацию. - содержание: веб-приложение, работающее на Tomcat, которое зависит от основного проекта, и я хочу сплести, когда я вызываю методы getter в проекте домена.Lazy Загрузка с использованием данных Spring Neo4j 4 + AspectJ LTW работает на Tomcat

Выполнение самого ядра Я сумел запустить его с использованием плагина maven и добавления зависимостей для aspectj. Но весь ад начинается, когда я переезжаю в Томкат. Я испробовал все возможности, например, с помощью -javaagent, создавать пользовательские context.xml, положили весну-инструмент в кот/Lib папки и т.д. и т.п. Я получаю следующее исключение:

 
java.lang.IllegalStateException: Post-processor tried to replace bean instance of type [com.test.server.graph.domain.model.Sequence] with (proxy) object of type [org.springframework.beans.factory.aspectj.$Proxy96] - not supported for aspect-configured classes! 
    at org.springframework.beans.factory.wiring.BeanConfigurerSupport.checkExposedObject(BeanConfigurerSupport.java:173) 
    at org.springframework.beans.factory.wiring.BeanConfigurerSupport.configureBean(BeanConfigurerSupport.java:143) 
    at org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect.configureBean(AnnotationBeanConfigurerAspect.aj:63) 
    at org.springframework.beans.factory.aspectj.AbstractDependencyInjectionAspect.ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(AbstractDependencyInjectionAspect.aj:88) 
    at com.test.server.graph.domain.model.Sequence.(Sequence.java:29) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422) 
    at org.neo4j.ogm.annotations.EntityFactory.instantiate(EntityFactory.java:135) 
    at org.neo4j.ogm.annotations.EntityFactory.instantiateObjectFromTaxa(EntityFactory.java:110) 
    at org.neo4j.ogm.annotations.EntityFactory.newObject(EntityFactory.java:61) 
    at org.neo4j.ogm.context.GraphEntityMapper.mapNodes(GraphEntityMapper.java:147) 
    at org.neo4j.ogm.context.GraphEntityMapper.mapEntities(GraphEntityMapper.java:132) 
    at org.neo4j.ogm.context.GraphEntityMapper.map(GraphEntityMapper.java:107) 
    at org.neo4j.ogm.context.GraphEntityMapper.map(GraphEntityMapper.java:102) 
    at org.neo4j.ogm.context.RestModelMapper.mapEntity(RestModelMapper.java:157) 
    at org.neo4j.ogm.context.RestModelMapper.map(RestModelMapper.java:76) 
    at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.query(ExecuteQueriesDelegate.java:94) 
    at org.neo4j.ogm.session.delegates.ExecuteQueriesDelegate.query(ExecuteQueriesDelegate.java:73) 
    at org.neo4j.ogm.session.Neo4jSession.query(Neo4jSession.java:313) 
    at org.springframework.data.neo4j.template.Neo4jTemplate.query(Neo4jTemplate.java:217) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) 
    at com.sun.proxy.$Proxy58.query(Unknown Source) 

pom.xml (ядро .project)

<dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-aspects</artifactId> 
     <version>${spring.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.data</groupId> 
     <artifactId>spring-data-neo4j</artifactId> 
     <version>${sdn.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.neo4j</groupId> 
     <artifactId>neo4j-ogm-core</artifactId> 
     <version>2.0.3-SNAPSHOT</version> 
    </dependency> 

Мой класс Configuration (основной проект)

@org.springframework.context.annotation.Configuration 
@ComponentScan(basePackages = "org.test.server.graph") 
@EnableNeo4jRepositories(basePackages = "org.test.server.graph.repository") 
@EnableAspectJAutoProxy 
@EnableSpringConfigured 
public class Neo4jConfig extends Neo4jConfiguration { 
    @Bean 
    public Configuration getConfiguration() { 
     Configuration config = new Configuration(); 
     config.driverConfiguration().setDriverClassName("org.neo4j.ogm.drivers.http.driver.HttpDriver") 
       .setURI(System.getProperty("neo4j.host")).setCredentials(System.getProperty("neo4j.user"),System.getProperty("neo4j.password")); 
     return config; 
    } 

    @Bean 
    public SessionFactory getSessionFactory() { 
     return new SessionFactory(getConfiguration(), "org.test.server.graph.domain"); 
    } 

    @Bean 
    @Scope(value = "prototype") 
    public Session getSession() throws Exception { 
     return super.getSession(); 
    } 
} 

Домен-классы моделей

В соответствии с рекомендациями Спринг документации я аннотированный классы в модели домена

@Configurable

MVC-диспетчерская-сервлет (веб-приложение проекта)

<context:spring-configured /> 
<context:load-time-weaver aspectj-weaving="on" weaver-class="org.springframework.instrument.classloading.tomcat.TomcatLoadTimeWeaver" /> 

Я пробовал работать с помощью автономной установки tomcat-maven-plugin и tomcat (v7 и v8).

- ОБНОВЛЕНИЕ -

Sequence.java

@NodeEntity 
@Configurable 
public class Sequence extends DatabaseObject { 

    @Relationship(type = "hasModifiedResidue", direction = Relationship.OUTGOING) 
    private List<AbstractModifiedResidue> hasModifiedResidue; 

    @Relationship(type = "referenceEntity", direction = Relationship.OUTGOING) 
    private ReferenceSequence referenceEntity; 

    public Sequence() {} 

    //getter and setters 

} 

DatabaseObject.java

@NodeEntity 
@Configurable(
    preConstruction = false 
) 
public abstract class DatabaseObject implements Serializable, Comparable<DatabaseObject> { 

    @GraphId 
    private Long id; 

    // other common attributes + getter and setters, no more annotation 

LazyLoadingAspect

@Aspect 
@Component 
public class LazyFetchAspect { 

    @Autowired 
    private Neo4jOperations neo4jTemplate; 

    @Around("modelGetter()") 
    public Object autoFetch(ProceedingJoinPoint pjp) throws Throwable { 
     System.out.println(" Testing Aspect "); 

     return pjp.proceed(); 
    } 

    @Pointcut("execution(public * com.test.server.graph.domain.model.*.get*(..))") 
    public void modelGetter() { 
    } 
} 
+0

Мое предположение было бы, что AspectJ время загрузки ткачество не работает, когда вы запускаете вещи под Tomcat. Я думаю, вы должны проверить, что нагрузка-время плетения действительно вступает в силу и исправляет вашу конфигурацию до тех пор, пока это не произойдет. Вы также можете рассмотреть возможность использования компиляции во времени (вы можете сделать это с помощью maven, и вы можете использовать Eclipse и компилятор AspectJ). Я имел большой успех, используя '@ Configurable' с ткачеством во время компиляции. Попробуйте запустить JVM Tomcat с аргументом '-javaagent' vm. –

+0

Кроме того, вы должны включить ведение журнала отладки для искателя времени загрузки AspectJ, чтобы вы действительно могли видеть, что он делает. См. Мой [ответ] (http://stackoverflow.com/a/35224749/2699901) по несвязанному вопросу для получения подробной информации о том, как это сделать. –

+0

@ NándorElődFekete. Сам основной проект работает, и я могу увидеть результат «Тестирование аспект» при выполнении. Две вещи для вас, чтобы принять во внимание, я запускаю IntelliJ, который не должен быть проблемой, и я запускаю tomcat с помощью -javaagent. Я включу ведение журнала отладки, и я придумаю обновления. Приветствия. – Gui

ответ

0

Основная проблема, кажется, что вы подаете аспекты к бобам:

Post-processor tried to replace bean instance of type [com.test.server.graph.domain.model.Sequence] with (proxy) object of type [org.springframework.beans.factory.aspectj.$Proxy96] - not supported for aspect-configured classes! 

Это не будет работать, так что вы должны убедиться, что ваши классы моделей являются реальной POJOs и не бобы и исключить их из источника. (Убедитесь, что в domain.model.* нет никакой весенней аннотации) - возможно, если вы опубликуете свой Sequence.java, я могу видеть, что может вызвать конфликт.

С другой стороны, вы должны убедиться, что aspectj предназначен только для моделей, а не для любых компонентов. Поэтому убедитесь, что у вас есть /META-INF/aop.xml, что включает в себя только ваши модели Pojo:

<!DOCTYPE aspectj PUBLIC 
     "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd"> 
    <aspectj> 
     <weaver> 
      <!-- only weave classes in our application-specific packages --> 
      <include within="com.test.server.graph.domain.model.*" /> 
     </weaver> 
     <aspects> 
      <!-- weave in just this aspect --> 
      <aspect name="my.util.aspects.Neo4jFetchAspect" /> 
     </aspects> 
    </aspectj> 

Части моего pom.xml (я имею другую установку теперь - вот почему весной версия так старый):

<dependency> 
     <groupId>org.aspectj</groupId> 
     <artifactId>aspectjrt</artifactId> 
     <version>1.6.12</version> 
    </dependency> 
    <dependency> 
     <groupId>org.aspectj</groupId> 
     <artifactId>aspectjweaver</artifactId> 
     <version>1.6.12</version> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-aspects</artifactId> 
     <version>3.1.1.RELEASE</version> 
    </dependency> 

Я не имею каких-либо специальных плагинов сборки или аналогичных

+0

Спасибо за ваш ответ. Я добавил Классы в качестве обновления в основном вопросе. @Configurable на нем, потому что Spring Documentation говорит. Модель имеет аннотацию Neo4j (SDN4), и я хочу использовать их для применения LazyLoading. Мой graphDB действительно огромный по глубине, если я получу их все для данного объекта, он будет длиться вечно. – Gui

+0

@Guilherme Это может быть конфигурируемая проблема. Я почти уверен, что вы не можете смешивать это. Что произойдет, когда вы удалите аннотацию и убедитесь, что весна не достигает этого класса? – Niko

+0

Я получаю NoSuchMethodError. Каковы зависимости в вашем pom.xml? Или какую конфигурацию вы используете? – Gui

0

После применения всех рекомендованных предложений это мой выход.

2016-06-15 09:15:21,144 INFO [localhost-startStop-1] DispatcherServlet: FrameworkServlet 'mvc-dispatcher': initialization started 
2016-06-15 09:15:21,166 INFO [localhost-startStop-1] XmlWebApplicationContext: Refreshing WebApplicationContext for namespace 'mvc-dispatcher-servlet': startup date [Wed Jun 15 09:15:21 BST 2016]; root of context hierarchy 
2016-06-15 09:15:21,198 INFO [localhost-startStop-1] XmlBeanDefinitionReader: Loading XML bean definitions from ServletContext resource [/WEB-INF/mvc-dispatcher-servlet.xml] 
2016-06-15 09:15:21,683 INFO [localhost-startStop-1] DefaultListableBeanFactory: Overriding bean definition for bean 'org.springframework.context.config.internalBeanConfigurerAspect' with a different definition: replacing [Root bean: class [org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=aspectOf; initMethodName=null; destroyMethodName=null] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.context.annotation.aspectj.SpringConfiguredConfiguration; factoryMethodName=beanConfigurerAspect; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/context/annotation/aspectj/SpringConfiguredConfiguration.class]] 
2016-06-15 09:15:21,866 INFO [localhost-startStop-1] PropertySourcesPlaceholderConfigurer: Loading properties file from class path resource [core.properties] 
2016-06-15 09:15:21,876 INFO [localhost-startStop-1] DefaultContextLoadTimeWeaver: Could not obtain server-specific LoadTimeWeaver: Could not initialize TomcatLoadTimeWeaver because Tomcat API classes are not available 
2016-06-15 09:15:21,877 INFO [localhost-startStop-1] DefaultContextLoadTimeWeaver: Found Spring's JVM agent for instrumentation 
[[email protected]] info AspectJ Weaver Version 1.8.9 built on Monday Mar 14, 2016 at 21:18:16 GMT 
[[email protected]] info register classloader [email protected] 

**[[email protected]] info using configuration /Users/SearchV2/content/target/classes/META-INF/aop.xml** 

**[[email protected]] info using configuration file:/Users/.m2/repository/org/springframework/spring-aspects/4.3.0.RELEASE/spring-aspects-4.3.0.RELEASE.jar!/META-INF/aop.xml** 

** REGISTERING MY ASPECT ** 
[[email protected]] info register aspect com.test.server.graph.aop.LazyFetchAspect 

PostProcessorRegistrationDelegate$BeanPostProcessorChecker: Bean 'neo4jConfig' of type [class com.test.server.graph.config.Neo4jConfig$$EnhancerBySpringCGLIB$$f406a5c8] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 
2016-06-15 09:15:22,267 INFO [localhost-startStop-1] Neo4jConfiguration: Initialising PersistenceExceptionTranslationPostProcessor 
[[email protected]] weaveinfo Join point 'method-execution(java.lang.String com.test.server.graph.domain.model.DatabaseObject.getStId())' in Type 'com.test.server.graph.domain.model.DatabaseObject' (DatabaseObject.java:82) advised by around advice from 'com.test.server.graph.aop.LazyFetchAspect' (LazyFetchAspect.java) 

.... еще много геттеров.

После выполнения некоторых запросов, которые я получаю следующее исключение:

SEVERE: Servlet.service() for servlet [mvc-dispatcher] in context with path [] threw exception [Handler processing failed; nested exception is java.lang.NoSuchMethodError: com.test.server.graph.aop.LazyFetchAspect.aspectOf()Lcom/test/server/graph/aop/LazyFetchAspect;] with root cause 
java.lang.NoSuchMethodError: com.test.server.graph.aop.LazyFetchAspect.aspectOf()Lcom/test/server/graph/aop/LazyFetchAspect; 
    at com.test.server.graph.domain.model.DatabaseObject.getStId(DatabaseObject.java:82) 
Смежные вопросы