Merge pull request #12 from ksperling/agent-autoconfig

Agent autoconfig and misc changes
This commit is contained in:
Rob Bygrave
2016-12-19 13:07:30 +13:00
committed by GitHub
10 changed files with 169 additions and 47 deletions
+37 -38
View File
@@ -9,20 +9,21 @@
</parent>
<groupId>io.ebean</groupId>
<artifactId>ebean-springtxn</artifactId>
<name>ebean-springtxn</name>
<artifactId>ebean-spring</artifactId>
<name>ebean-spring</name>
<version>10.1.1-SNAPSHOT</version>
<packaging>jar</packaging>
<description>Support for Spring transaction use with Ebean</description>
<description>Ebean support for Spring and Spring Boot</description>
<properties>
<spring.framework.version>4.3.4.RELEASE</spring.framework.version>
<spring.boot.version>1.4.2.RELEASE</spring.boot.version>
</properties>
<url>http://ebean-orm.github.io/</url>
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/avaje-ebeanorm-spring.git</developerConnection>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean-spring.git</developerConnection>
</scm>
<dependencies>
@@ -30,46 +31,31 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>[1.7,)</version>
<scope>provided</scope>
</dependency>
<!-- Provided: Bring in explicitly -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>10.1.1</version>
<scope>provided</scope>
<version>[10,)</version>
</dependency>
<!-- Optional: Add to use AgentLoaderSupport -->
<!-- Optional: Add to use EbeanAgentAutoConfiguration -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-agent</artifactId>
<version>10.1.1</version>
<scope>provided</scope>
<version>[10,)</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- Optional: Add to use AgentLoaderSupport -->
<!--<dependency>-->
<!--<groupId>org.avaje</groupId>-->
<!--<artifactId>avaje-agentloader</artifactId>-->
<!--<version>2.1.2</version>-->
<!--<scope>provided</scope>-->
<!--</dependency>-->
<!-- Provided: Spring, bring in explicitly -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.framework.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
<dependency>
<groupId>org.avaje</groupId>
<artifactId>avaje-agentloader</artifactId>
<version>2.1.2</version>
<optional>true</optional>
</dependency>
<!-- Provided: Spring, Spring Boot -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
@@ -83,6 +69,13 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${spring.boot.version}</version>
<scope>provided</scope>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>org.springframework</groupId>
@@ -97,6 +90,13 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>${spring.boot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.avaje.composite</groupId>
<artifactId>avaje-composite-testing-ebean</artifactId>
@@ -135,15 +135,15 @@
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<archive>
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
</archive>
<!-- Manifest-only JAR hides the true classpath from the AgentLoader -->
<useManifestOnlyJar>false</useManifestOnlyJar>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings
@@ -159,7 +159,7 @@
<pluginExecutionFilter>
<groupId>io.ebean</groupId>
<artifactId>ebean-maven-plugin</artifactId>
<versionRange>[10,11)</versionRange>
<versionRange>[1,)</versionRange>
<goals>
<goal>enhance</goal>
</goals>
@@ -172,7 +172,6 @@
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
@@ -0,0 +1,69 @@
package io.ebean.spring.boot;
import org.avaje.agentloader.AgentLoader;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
/**
* Loads the Ebean enhancement agent early in the Spring Boot startup process,
* if it is present on the classpath.
* <p>
* Note that using this mechanism is only recommended for development;
* production applications should ideally be enhanced at build time, or at least
* load the agent via the <code>javaagent</code> JVM option. When the agent is
* loaded at runtime via this class, any entity classes that have already been
* loaded won't be enhanced and will fail to work correctly.
* <p>
* For unit tests and similar cases where Spring Boot auto-configuration may not
* be active, loading of the agent can be triggered manually via
* {@link #enable()}.
*/
@Configuration
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass(AgentLoader.class)
public class EbeanAgentAutoConfiguration implements BeanFactoryPostProcessor, PriorityOrdered {
public EbeanAgentAutoConfiguration() {
load(); // Spring has already evaluated the @ConditionalOnClass
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// We're not actually doing anything with the BeanFactory, but implementing
// BeanFactoryPostProcessor ensures we get instantiated early, ideally
// before anybody has a chance to load any entity classes we want to
// enhance.
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
private static void load() {
AgentLoader.loadAgentFromClasspath("ebean-agent", "debug=1");
}
/**
* Loads the Ebean agent if the agent-loader and the agent itself are present
* on the classpath, or does nothing otherwise.
* <p>
* Do not call this method from a static initializer as this can lead to a JVM
* deadlock (the agent attach thread will attempt to acquire the class loader
* lock, which is held during static initialization).
*/
public static void enable() {
try {
load();
} catch (NoClassDefFoundError e) {
/* ignored */
}
}
}
@@ -17,7 +17,7 @@
* along with Ebean; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package io.ebean.springtxn;
package io.ebean.spring.txn;
import io.ebean.config.ExternalTransactionManager;
import io.ebeaninternal.api.SpiTransaction;
@@ -18,7 +18,7 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package io.ebean.springtxn;
package io.ebean.spring.txn;
import org.springframework.jdbc.datasource.ConnectionHolder;
@@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
io.ebean.spring.boot.EbeanAgentAutoConfiguration
@@ -0,0 +1,35 @@
package io.ebean.spring.boot;
import io.ebean.bean.EntityBean;
import org.junit.Test;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.unenhanced.Boondoggle;
import org.unenhanced.Wotsit;
import static org.assertj.core.api.StrictAssertions.assertThat;
@SpringBootTest(webEnvironment=WebEnvironment.NONE)
public class EbeanAgentAutoConfigurationTest extends AbstractJUnit4SpringContextTests {
static {
// Validate our test setup. Agent should not be loaded yet, so 'Boondoggle'
// should have been enhanced neither at build time nor at load time.
assertThat(EntityBean.class.isAssignableFrom(Boondoggle.class)).isFalse();
}
@Configuration
@EnableAutoConfiguration
public static class Config {
/* no beans needed for this test */
}
@Test
public void testAgentIsWorking() {
// Wotsit is outside of the org.example package that's being enhanced
// at build time, so should be picked up by the agent only.
assertThat(EntityBean.class.isAssignableFrom(Wotsit.class)).isTrue();
}
}
@@ -0,0 +1,11 @@
package org.unenhanced;
import javax.persistence.Entity;
import javax.persistence.Id;
// Not in org.example, i.e. not enhanced at build time
@Entity
public class Boondoggle {
@Id
public String name;
}
+11
View File
@@ -0,0 +1,11 @@
package org.unenhanced;
import javax.persistence.Entity;
import javax.persistence.Id;
// Not in org.example, i.e. not enhanced at build time
@Entity
public class Wotsit {
@Id
public String name;
}
+1 -1
View File
@@ -6,7 +6,7 @@
<!-- Default abstract Ebean Server configuration -->
<bean id="defaultEbeanServerConfig" class="io.ebean.config.ServerConfig" abstract="true">
<property name="externalTransactionManager">
<bean class="io.ebean.springtxn.SpringAwareJdbcTransactionManager"/>
<bean class="io.ebean.spring.txn.SpringAwareJdbcTransactionManager"/>
</property>
<property name="namingConvention">
<bean class="io.ebean.config.UnderscoreNamingConvention"/>
+1 -6
View File
@@ -8,11 +8,6 @@
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!--<bean class="com.avaje.ebean.springsupport.AgentLoaderSupport">-->
<!--<property name="debug" value="1" />-->
<!--<property name="packages" value="com.avaje.test.springsupport.**" />-->
<!--</bean>-->
<import resource="classpath:default-ebean-server.xml"/>
<!-- Transaktionen via Annotation use Springs @Transactional -->
@@ -24,7 +19,7 @@
<bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="org.h2.Driver" />
<property name="url"
value="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" />
value="jdbc:h2:mem:ebean-testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false" />
</bean>
</constructor-arg>
</bean>