代码之家  ›  专栏  ›  技术社区  ›  egervari

scala会影响AspectJ/Spring AOP吗?当调用@Configurable时运行测试时,我遇到了线程锁定问题

  •  0
  • egervari  · 技术社区  · 15 年前

    我有一个奇怪的问题,当我使用maven运行测试时,每当测试方法调用一个带有注释@Configurable的对象时,它就会锁定。我可以使用AspectJ Weaver插件在IDEA中很好地运行测试(非常明显),但是我不能使用maven(无论是在IDEA中执行还是在终端中执行)。

    更奇怪的是,如果我按ctrl-c,它不会终止进程。它只是将一个500meg进程永久保存在内存中,直到我在Ubuntu中使用系统监视器杀死它。

    直到我将Scala添加到我的Java项目中,这个问题才发生。注意,我并不是在编译Scala代码——只是包含了用Scala编译的jar,我还将Scala编译器/库jar作为类路径的一部分。

    基本上,Maven将运行一系列测试,然后挂起:

    Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.206 sec
    Running jobprep.domain.student.ActiveQuestionTests
    Tests run: 26, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.065 sec
    Running jobprep.domain.sysadmin.WebpageValidationTests
    Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.225 sec
    Running jobprep.domain.question.openended.OpenEndedStudentSubmissionDeserializerTests
    

    当谈到OpenEndStudentSubmissionDeserializerTests时,它会冻结。这似乎是OpenEndedStudentSubmissionDeserializer使用@Configurable的原因。如果我注释掉测试类并再次运行测试,它将冻结在下一个使用@Configurable的测试类上。

    编辑 :这很有趣,如果我告诉maven在“jobprep.domain.question.openended”包中运行测试,它可以100%工作。如果我告诉它运行“jobprep.domain”中的所有内容,它仍然可以工作!如果我让它运行“jobprep”中的所有内容,那么问题就会发生。

    谈到这个根包,Scala、AspectJ、Spring等有什么我应该注意的吗?

    在Maven中,如果我告诉surefire只加载我的测试的一个子集,它就会工作。我的测试套件中1096个测试中有893个 运行 通过 . 但这并不完美,因为我需要让剩下的测试继续工作:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.6</version>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.8.1</version>
            </dependency>
        </dependencies>
        <configuration>
            <includes>
                <include>**/dao/*Tests.java</include>
                <include>**/domain/*Tests.java</include>
                <include>**/domain/**/*Tests.java</include>
                <include>**/service/*Tests.java</include>
                <include>**/service/**/*Tests.java</include>
                <include>**/validator/*Tests.java</include>
            </includes>
            <excludes>
                <exclude>**/Abstract*Tests*.java</exclude>
                <exclude>**/DatabaseTests.java</exclude>
                <exclude>**/ControllerTests.java</exclude>
                <exclude>**/ValidationTests.java</exclude>
            </excludes>
            <skipTests>false</skipTests>
        </configuration>
    </plugin>
    

    很糟糕,我必须如此精细,但我不知道有任何其他方法来解决这个问题。

    不管怎样,添加这一行后,它就会像以前一样锁定在openendedsubmissionderserializertests:

    <include>**/controllers/*Tests.java</include>
    

    你知道什么很奇怪吗?如果我运行控制器的测试 只有 ,有效!该死的!这是否意味着他们都是分开跑,而不是一起跑?!?

    无论如何,当maven frezes,如果我在linux中按CTRL-\n而不是CTRL-C,就会发生以下情况:

    "com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1" daemon prio=10 tid=0x00007f190cb1e800 nid=0x77d in Object.wait() [0x00007f191015b000]
       java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00007f191b06e4b8> (a com.mchange.v2.async.ThreadPoolAsynchronousRunner)
        at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
        - locked <0x00007f191b06e4b8> (a com.mchange.v2.async.ThreadPoolAsynchronousRunner)
    
    "com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0" daemon prio=10 tid=0x00007f190c7fb800 nid=0x77c in Object.wait() [0x00007f191025c000]
       java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00007f191b06e4b8> (a com.mchange.v2.async.ThreadPoolAsynchronousRunner)
        at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
        - locked <0x00007f191b06e4b8> (a com.mchange.v2.async.ThreadPoolAsynchronousRunner)
    
    "Timer-0" daemon prio=10 tid=0x00007f190d396800 nid=0x77b in Object.wait() [0x00007f191035d000]
       java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00007f191b073aa8> (a java.util.TaskQueue)
        at java.util.TimerThread.mainLoop(Timer.java:509)
        - locked <0x00007f191b073aa8> (a java.util.TaskQueue)
        at java.util.TimerThread.run(Timer.java:462)
    
    "Low Memory Detector" daemon prio=10 tid=0x00007f190c025800 nid=0x740 runnable [0x0000000000000000]
       java.lang.Thread.State: RUNNABLE
    
    "CompilerThread1" daemon prio=10 tid=0x00007f190c023000 nid=0x73f waiting on condition [0x0000000000000000]
       java.lang.Thread.State: RUNNABLE
    
    "CompilerThread0" daemon prio=10 tid=0x00007f190c020000 nid=0x73e waiting on condition [0x0000000000000000]
       java.lang.Thread.State: RUNNABLE
    
    "Signal Dispatcher" daemon prio=10 tid=0x00007f190c01e000 nid=0x73d waiting on condition [0x0000000000000000]
       java.lang.Thread.State: RUNNABLE
    
    "Finalizer" daemon prio=10 tid=0x0000000040c03800 nid=0x73c in Object.wait() [0x00007f19119e8000]
       java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00007f19181046f8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
        - locked <0x00007f19181046f8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
    
    "Reference Handler" daemon prio=10 tid=0x0000000040c01000 nid=0x73b in Object.wait() [0x00007f1911ae9000]
       java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00007f1918104670> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:485)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
        - locked <0x00007f1918104670> (a java.lang.ref.Reference$Lock)
    
    "main" prio=10 tid=0x0000000040b78800 nid=0x735 waiting on condition [0x00007f193bc5e000]
       java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00007f191d8b6a58> (a java.util.concurrent.CountDownLatch$Sync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:811)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:969)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1281)
        at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:207)
        at org.hsqldb.lib.CountUpDownLatch.await(Unknown Source)
        at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
        at org.hsqldb.Session.execute(Unknown Source)
        - locked <0x00007f191d8b6358> (a org.hsqldb.Session)
        at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source)
        at org.hsqldb.jdbc.JDBCPreparedStatement.executeQuery(Unknown Source)
        - locked <0x00007f19313c0b70> (a org.hsqldb.jdbc.JDBCPreparedStatement)
        at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
        at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
        at org.hibernate.loader.Loader.getResultSet(Loader.java:1869)
        at org.hibernate.loader.Loader.doQuery(Loader.java:718)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:270)
        at org.hibernate.loader.Loader.loadEntity(Loader.java:1953)
        at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:86)
        at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:76)
        at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3270)
        at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:496)
        at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:477)
        at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:227)
        at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:269)
        at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:152)
        at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1080)
        at org.hibernate.impl.SessionImpl.get(SessionImpl.java:997)
        at org.hibernate.impl.SessionImpl.get(SessionImpl.java:990)
        at org.springframework.orm.hibernate3.HibernateTemplate$1.doInHibernate(HibernateTemplate.java:519)
        at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
        at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
        at org.springframework.orm.hibernate3.HibernateTemplate.get(HibernateTemplate.java:512)
        at org.springframework.orm.hibernate3.HibernateTemplate.get(HibernateTemplate.java:506)
        at jobprep.dao.BaseDaoSupport.find(BaseDaoSupport.java:65)
        at jobprep.dao.BaseDaoSupport.mandatoryFind(BaseDaoSupport.java:69)
        at jobprep.domain.question.openended.OpenEndedStudentSubmissionDeserializer.parseActiveQuestion(OpenEndedStudentSubmissionDeserializer.java:42)
        at jobprep.domain.question.openended.OpenEndedStudentSubmissionDeserializer.deserialize(OpenEndedStudentSubmissionDeserializer.java:30)
        at jobprep.domain.question.openended.OpenEndedStudentSubmissionDeserializerTests.deserialize(OpenEndedStudentSubmissionDeserializerTests.java:44)
        at jobprep.domain.question.openended.OpenEndedStudentSubmissionDeserializerTests.deserializeWithNoText(OpenEndedStudentSubmissionDeserializerTests.java:24)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
        at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
        at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
        at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
        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:70)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
        at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:115)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:102)
        at org.apache.maven.surefire.Surefire.run(Surefire.java:180)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
        at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
    
    "VM Thread" prio=10 tid=0x0000000040bfc800 nid=0x73a runnable 
    
    "GC task thread#0 (ParallelGC)" prio=10 tid=0x0000000040b8b800 nid=0x736 runnable 
    
    "GC task thread#1 (ParallelGC)" prio=10 tid=0x0000000040b8d800 nid=0x737 runnable 
    
    "GC task thread#2 (ParallelGC)" prio=10 tid=0x0000000040b8f000 nid=0x738 runnable 
    
    "GC task thread#3 (ParallelGC)" prio=10 tid=0x0000000040b91000 nid=0x739 runnable 
    
    "VM Periodic Task Thread" prio=10 tid=0x00007f190c028800 nid=0x741 waiting on condition 
    
    JNI global references: 1517
    
    Heap
     PSYoungGen      total 126336K, used 74112K [0x00007f192d220000, 0x00007f19378c0000, 0x00007f1937cc0000)
      eden space 82880K, 88% used [0x00007f192d220000,0x00007f19319620d0,0x00007f1932310000)
      from space 43456K, 2% used [0x00007f1932310000,0x00007f193242e040,0x00007f1934d80000)
      to   space 41728K, 0% used [0x00007f1935000000,0x00007f1935000000,0x00007f19378c0000)
     PSOldGen        total 278464K, used 184803K [0x00007f1917cc0000, 0x00007f1928cb0000, 0x00007f192d220000)
      object space 278464K, 66% used [0x00007f1917cc0000,0x00007f1923138df8,0x00007f1928cb0000)
     PSPermGen       total 86016K, used 57644K [0x00007f19128c0000, 0x00007f1917cc0000, 0x00007f1917cc0000)
      object space 86016K, 67% used [0x00007f19128c0000,0x00007f191610b3c8,0x00007f1917cc0000)
    

    这里是aop.xml:

    <aspectj>
        <weaver options="-showWeaveInfo -XmessageHandlerClass:org.springframework.aop.aspectj.AspectJWeaverMessageHandler">
            <include within="jobprep.domain.question.finite.FiniteStudentSubmissionDeserializer"/>
            <include within="jobprep.domain.question.openended.OpenEndedQuestion"/>
            <include within="jobprep.domain.question.openended.OpenEndedResult"/>
            <include within="jobprep.domain.question.openended.OpenEndedStudentSubmissionDeserializer"/>
            <include within="jobprep.domain.question.category.CategoryStudentSubmissionDeserializer"/>
            <include within="jobprep.domain.question.fill.FillInTheBlankStudentSubmissionDeserializer"/>
            <include within="jobprep.domain.keywords.GroupedKeywords"/>
        </weaver>
    </aspectj>
    

    下面是让aspectj工作的maven插件,我知道它确实工作了很长时间:

            <!-- AspectJ -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <complianceLevel>1.6</complianceLevel>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                </configuration>
            </plugin>
    

    我能找人帮忙吗?我需要给你们什么信息?

    我害怕构建这个项目并部署到服务器上,即使所有的测试都在IDE中工作。。。因为如果Aspects/AOP在测试中锁定,那么如果我使用maven构建和打包项目,它可能就不起作用。

    2 回复  |  直到 15 年前
        1
  •  2
  •   ramnivas    15 年前

    @Configurable类型是否扩展了Scala类?如果您可以发布示例代码(或者理想情况下是一个简单的Maven项目)来展示@Configurable类和Scala类是如何交互的,那么这将有助于解决这个问题。

        2
  •  0
  •   Will Sargent    15 年前

    我猜是的,aspectj干扰了scala类。注意Scala有许多内部和外部类,而aspectj显然是 not terribly bright about determining what the outer class is .

    尝试添加

      <weaver>
        <exclude>scala..*</exclude>
      </weaver>
    

    去你的aop.xml文件看看会发生什么。