spring-projects / spring-loaded

Java agent that enables class reloading in a running JVM
Apache License 2.0
2.72k stars 515 forks source link

Spring Data repositories crash when app starts with spring loaded #58

Open dsyer opened 10 years ago

dsyer commented 10 years ago

I see other (possibly related) Spring Data issues (#18, #53), but neither seems identical. This one is easy to reproduce as well:

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <dependencies>
                    <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>springloaded</artifactId>
                        <version>1.1.5.RELEASE</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
$ (cd spring-boot-samples/spring-boot-sample-data-jpa/; MAVEN_OPTS=-noverify mvn clean spring-boot:run)
...
<crash>
Caused by: java.lang.NoSuchMethodError: sample.data.jpa.service.HotelRepository.__execute([Ljava.lang.Object;, java.lang.Object, java.lang.String)
    at com.sun.proxy.$Proxy72.<clinit>(Unknown Source)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at java.lang.reflect.Proxy.newInstance(Proxy.java:748)
    at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:739)
    at org.springframework.aop.framework.JdkDynamicAopProxy.getProxy(JdkDynamicAopProxy.java:121)
    at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:111)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:163)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:224)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:210)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:84)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
    ... 36 more
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
...

See also https://github.com/spring-projects/spring-boot/issues/648

aclement commented 10 years ago

I believe this is due to $Proxy types not being automatically being considered reloadable with more recent JDKs because more recent JDKs are adding a package prefix (older JDKs did not). Please try it with a 1.2.0.BUILD-SNAPSHOT which contains the most recent fixes for this.

dsyer commented 10 years ago

Still broken with 1.2.0.BUILD-SNAPSHOT. Should I concentrate on a specific JVM micro version? (Eberhard reports it failing with Java 7 and 8.)

dsyer commented 10 years ago

Also I can confirm what @ewolff reported: it works with a vanilla "java" launcher (and also with "mvn spring-boot:run" but only if you add the agent in MAVEN_OPTS), but not with the "embedded" agent attach in the Maven plugin. Maybe we need some help in the plugin?

aclement commented 10 years ago

I currently would try to fix issues around the most recent micro versions of Java7 and Java8 - this issue isn't related to changes in micro versions though.

Is the spring-boot:run case still adding the agent 'late' ? might be a factor here.

aclement commented 10 years ago

Just saw the comment on the other bug. Yes most likely attaching the agent late is the problem. Some system classes need to be modified, if they happen to get loaded earlier than the agent is attached, SL can't do its job. I'm hesitant to dive into trying to find a way to solve late agent attachment because it'll add even more complexity to the system.

saschaszott commented 10 years ago

I could reproduce the NoSuchMethodError both with 1.2.1.BUILD-SNAPSHOT and 1.2.0.RELEASE (on Java 8). Interestingly, the error does not occur when using the Spring Boot Gradle plugin.

aclement commented 10 years ago

Interestingly, the error does not occur when using the Spring Boot Gradle plugin.

So what is the difference here? Is it a difference between forking and not forking the process? In the former case where the agent can be added from JVM start, things are going to work so much better.

dsyer commented 10 years ago

I imagine that's the difference. Upgrade to the 1.1.0 snapshots (M1 out later this week) if you want to use Maven.