diff --git a/src/main/java/com/avaje/ebean/config/ClassLoadConfig.java b/src/main/java/com/avaje/ebean/config/ClassLoadConfig.java
new file mode 100644
index 000000000..ca0a75c74
--- /dev/null
+++ b/src/main/java/com/avaje/ebean/config/ClassLoadConfig.java
@@ -0,0 +1,143 @@
+package com.avaje.ebean.config;
+
+
+/**
+ * Helper to find classes taking into account the context class loader.
+ */
+public class ClassLoadConfig {
+
+ protected final ClassLoaderContext context;
+
+ /**
+ * Construct with the default classLoader search with context classLoader first.
+ */
+ public ClassLoadConfig() {
+ this(null);
+ }
+
+ /**
+ * Specify the classLoader to use for class detection and new instance creation.
+ */
+ public ClassLoadConfig(ClassLoader classLoader) {
+ this.context = new ClassLoaderContext(classLoader);
+ }
+
+ /**
+ * Return true if the Java.time types are available and should be supported.
+ */
+ public boolean isJavaTimePresent() {
+ return isPresent("java.time.LocalDate");
+ }
+
+ /**
+ * Return true if the Joda types are available and should be supported.
+ */
+ public boolean isJodaTimePresent() {
+ return isPresent("org.joda.time.LocalDateTime");
+ }
+
+ /**
+ * Return true if javax validation annotations like Size and NotNull are present.
+ */
+ public boolean isJavaxValidationAnnotationsPresent() {
+ return isPresent("javax.validation.constraints.NotNull");
+ }
+
+ /**
+ * Return true if Jackson annotations like JsonIgnore are present.
+ */
+ public boolean isJacksonAnnotationsPresent() {
+ return isPresent("com.fasterxml.jackson.annotation.JsonIgnore");
+ }
+
+ /**
+ * Return true if Jackson ObjectMapper is present.
+ */
+ public boolean isJacksonObjectMapperPresent() {
+ return isPresent("com.fasterxml.jackson.databind.ObjectMapper");
+ }
+
+ /**
+ * Return a new instance of the class using the default constructor.
+ */
+ public Object newInstance(String className) {
+
+ try {
+ Class> cls = forName(className);
+ return cls.newInstance();
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Error constructing " + className, e);
+ }
+ }
+
+ /**
+ * Return true if the given class is present.
+ */
+ protected boolean isPresent(String className) {
+ try {
+ forName(className);
+ return true;
+ } catch (Throwable ex) {
+ // Class or one of its dependencies is not present...
+ return false;
+ }
+ }
+
+ /**
+ * Load a class taking into account a context class loader (if present).
+ */
+ protected Class> forName(String name) throws ClassNotFoundException {
+ return context.forName(name);
+ }
+
+ /**
+ * Wraps the preferred, caller and context class loaders.
+ */
+ protected class ClassLoaderContext {
+
+ /**
+ * Optional - if set only use this classLoader (no fallback).
+ */
+ protected final ClassLoader preferredLoader;
+
+ protected final ClassLoader contextLoader;
+
+ protected final ClassLoader callerLoader;
+
+ ClassLoaderContext(ClassLoader preferredLoader) {
+ this.preferredLoader = preferredLoader;
+ this.callerLoader = ServerConfig.class.getClassLoader();
+ this.contextLoader = contextLoader();
+ }
+
+ ClassLoader contextLoader() {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ return (loader != null) ? loader: callerLoader;
+ }
+
+ Class> forName(String name) throws ClassNotFoundException {
+
+ if (preferredLoader != null) {
+ // only use the explicitly set classLoader
+ return classForName(name, preferredLoader);
+ }
+ try {
+ // try the context loader first
+ return classForName(name, contextLoader);
+ } catch (ClassNotFoundException e) {
+ if (callerLoader == contextLoader) {
+ throw e;
+ } else {
+ // fallback to the caller classLoader
+ return classForName(name, callerLoader);
+ }
+ }
+ }
+
+ Class> classForName(String name, ClassLoader classLoader) throws ClassNotFoundException {
+ return Class.forName(name, true, classLoader);
+ }
+
+ }
+}
+
diff --git a/src/main/java/com/avaje/ebean/config/ServerConfig.java b/src/main/java/com/avaje/ebean/config/ServerConfig.java
index 546883eb7..ff255ffbe 100644
--- a/src/main/java/com/avaje/ebean/config/ServerConfig.java
+++ b/src/main/java/com/avaje/ebean/config/ServerConfig.java
@@ -21,7 +21,6 @@ import com.avaje.ebean.event.changelog.ChangeLogRegister;
import com.avaje.ebean.event.readaudit.ReadAuditLogger;
import com.avaje.ebean.event.readaudit.ReadAuditPrepare;
import com.avaje.ebean.meta.MetaInfoManager;
-import com.avaje.ebeaninternal.api.ClassUtil;
import com.fasterxml.jackson.core.JsonFactory;
import javax.sql.DataSource;
@@ -235,6 +234,11 @@ public class ServerConfig {
*/
private DbMigrationConfig migrationConfig = new DbMigrationConfig();
+ /**
+ * The ClassLoadConfig used to detect Joda, Java8, Jackson etc and create plugin instances given a className.
+ */
+ private ClassLoadConfig classLoadConfig = new ClassLoadConfig();
+
/**
* Set to true if the DataSource uses autoCommit.
*
@@ -2030,6 +2034,22 @@ public class ServerConfig {
this.persistenceContextScope = persistenceContextScope;
}
+ /**
+ * Return the ClassLoadConfig which is used to detect Joda, Java8 types etc and also
+ * create new instances of plugins given a className.
+ */
+ public ClassLoadConfig getClassLoadConfig() {
+ return classLoadConfig;
+ }
+
+ /**
+ * Set the ClassLoadConfig which is used to detect Joda, Java8 types etc and also
+ * create new instances of plugins given a className.
+ */
+ public void setClassLoadConfig(ClassLoadConfig classLoadConfig) {
+ this.classLoadConfig = classLoadConfig;
+ }
+
/**
* Load settings from ebean.properties.
*/
@@ -2093,7 +2113,7 @@ public class ServerConfig {
* @param classname the implementation class as per properties
*/
protected T createInstance(Class pluginType, String classname) {
- return classname == null ? null : (T) ClassUtil.newInstance(classname);
+ return classname == null ? null : (T) classLoadConfig.newInstance(classname);
}
/**
diff --git a/src/main/java/com/avaje/ebeaninternal/api/ClassLoadContext.java b/src/main/java/com/avaje/ebeaninternal/api/ClassLoadContext.java
deleted file mode 100644
index e0666d9b7..000000000
--- a/src/main/java/com/avaje/ebeaninternal/api/ClassLoadContext.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package com.avaje.ebeaninternal.api;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Wraps the caller and context class loaders.
- *
- * Helper for ClassUtil.
- *
- *
- * @author rbygrave
- */
-class ClassLoadContext {
-
- private static final Logger logger = LoggerFactory.getLogger(ClassLoadContext.class);
-
- private final ClassLoader callerLoader;
-
- private final ClassLoader contextLoader;
-
- private final boolean preferContext;
-
- private boolean ambiguous;
-
- public static ClassLoadContext of(Class> caller, boolean preferContext) {
- return new ClassLoadContext(caller, preferContext);
- }
-
- /**
- * This constructor is package-private to restrict instantiation to
- */
- ClassLoadContext(final Class> caller, boolean preferContext) {
- if (caller == null) {
- throw new IllegalArgumentException("caller is null");
- }
- this.callerLoader = caller.getClassLoader();
- this.contextLoader = Thread.currentThread().getContextClassLoader();
- this.preferContext = preferContext;
- }
-
- public Class> forName(String name) throws ClassNotFoundException {
-
- ClassLoader defaultLoader = getDefault(preferContext);
-
- try {
- return Class.forName(name, true, defaultLoader);
- } catch (ClassNotFoundException e) {
- if (callerLoader == defaultLoader) {
- throw e;
- } else {
- return Class.forName(name, true, callerLoader);
- }
- }
- }
-
-
- /**
- * Return the expected class loader to use.
- *
- * Works on the assumption that the child of the caller or context class
- * loader is preferred.
- *
- */
- public ClassLoader getDefault(boolean preferContext) {
-
- if (contextLoader == null) {
- if (logger.isDebugEnabled()) {
- logger.debug("No Context ClassLoader, using " + callerLoader.getClass().getName());
- }
- return callerLoader;
- }
- if (contextLoader == callerLoader) {
- if (logger.isDebugEnabled()) {
- logger.debug("Context and Caller ClassLoader's same instance of " + contextLoader.getClass().getName());
- }
- return callerLoader;
- }
-
- if (isChild(contextLoader, callerLoader)) {
- if (logger.isDebugEnabled()) {
- logger.debug("Caller ClassLoader " + callerLoader.getClass().getName()
- + " child of ContextLoader " + contextLoader.getClass().getName());
- }
- return callerLoader;
-
- } else if (isChild(callerLoader, contextLoader)) {
- if (logger.isDebugEnabled()) {
- logger.debug("Context ClassLoader " + contextLoader.getClass().getName()
- + " child of Caller ClassLoader " + callerLoader.getClass().getName());
- }
- return contextLoader;
-
- } else {
- // ambiguous case, perhaps both null
- logger.debug("Ambiguous ClassLoader choice preferContext:" + preferContext
- + " Context:" + contextLoader.getClass().getName() + " Caller:" + callerLoader.getClass().getName());
- ambiguous = true;
- return preferContext ? contextLoader : callerLoader;
- }
- }
-
- /**
- * Return true if the 'default' class loader is ambiguous.
- */
- public boolean isAmbiguous() {
- return ambiguous;
- }
-
- /**
- * Return the ClassLoader of the caller.
- */
- public ClassLoader getCallerLoader() {
- return callerLoader;
- }
-
- /**
- * Return the Thread Context ClassLoader.
- */
- public ClassLoader getContextLoader() {
- return contextLoader;
- }
-
- /**
- * Return the ClassLoader for this class.
- */
- public ClassLoader getThisLoader() {
- return this.getClass().getClassLoader();
- }
-
- /**
- * Returns 'true' if 'loader2' is a delegation child of 'loader1' [or if
- * 'loader1'=='loader2'].
- */
- private boolean isChild(final ClassLoader loader1, ClassLoader loader2) {
-
- for (; loader2 != null; loader2 = loader2.getParent()) {
- if (loader2 == loader1) {
- return true;
- }
- }
-
- return false;
- }
-
-}
\ No newline at end of file
diff --git a/src/main/java/com/avaje/ebeaninternal/api/ClassUtil.java b/src/main/java/com/avaje/ebeaninternal/api/ClassUtil.java
index b5b9d66d0..380abe714 100644
--- a/src/main/java/com/avaje/ebeaninternal/api/ClassUtil.java
+++ b/src/main/java/com/avaje/ebeaninternal/api/ClassUtil.java
@@ -6,79 +6,60 @@ package com.avaje.ebeaninternal.api;
*/
public class ClassUtil {
- /**
- * Load a class taking into account a context class loader (if present).
- */
- public static Class> forName(String name, Class> caller) throws ClassNotFoundException {
-
- if (caller == null) {
- caller = ClassUtil.class;
- }
- ClassLoadContext ctx = ClassLoadContext.of(caller, true);
- return ctx.forName(name);
- }
-
- /**
- * Return true if javax validation annotations like Size and NotNull are present.
- */
- public static boolean isJavaxValidationAnnotationsPresent() {
- return isPresent("javax.validation.constraints.NotNull", null);
- }
-
- /**
- * Return true if Jackson annotations like JsonIgnore are present.
- */
- public static boolean isJacksonAnnotationsPresent() {
- return isPresent("com.fasterxml.jackson.annotation.JsonIgnore", null);
- }
-
- /**
- * Return true if Jackson ObjectMapper is present.
- */
- public static boolean isJacksonObjectMapperPresent() {
- return isPresent("com.fasterxml.jackson.databind.ObjectMapper", null);
- }
-
-
- /**
- * Return true if the given class is present.
- */
- public static boolean isPresent(String className) {
- return isPresent(className, null);
- }
-
- /**
- * Return true if the given class is present.
- */
- public static boolean isPresent(String className, Class> caller) {
- try {
- forName(className, caller);
- return true;
- } catch (Throwable ex) {
- // Class or one of its dependencies is not present...
- return false;
- }
- }
-
/**
* Return a new instance of the class using the default constructor.
*/
public static Object newInstance(String className) {
- return newInstance(className, null);
- }
-
- /**
- * Return a new instance of the class using the default constructor.
- */
- public static Object newInstance(String className, Class> caller) {
try {
- Class> cls = forName(className, caller);
+ Class> cls = forName(className);
return cls.newInstance();
} catch (Exception e) {
String msg = "Error constructing " + className;
throw new IllegalArgumentException(msg, e);
}
}
+
+ /**
+ * Load a class taking into account a context class loader (if present).
+ */
+ private static Class> forName(String name) throws ClassNotFoundException {
+ return new ClassLoadContext().forName(name);
+ }
+
+
+ /**
+ * Helper to wrap the context and caller classLoaders (to use/try both).
+ */
+ static class ClassLoadContext {
+
+ private final ClassLoader contextLoader;
+
+ private final ClassLoader callerLoader;
+
+ ClassLoadContext() {
+ this.callerLoader = ClassUtil.class.getClassLoader();
+ this.contextLoader = contextLoader();
+ }
+
+ ClassLoader contextLoader() {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ return (loader != null) ? loader: callerLoader;
+ }
+
+ public Class> forName(String name) throws ClassNotFoundException {
+
+ try {
+ return Class.forName(name, true, contextLoader);
+ } catch (ClassNotFoundException e) {
+ if (callerLoader == contextLoader) {
+ throw e;
+ } else {
+ return Class.forName(name, true, callerLoader);
+ }
+ }
+ }
+
+ }
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultContainer.java b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultContainer.java
index 9ce4609d3..12b3be352 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultContainer.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultContainer.java
@@ -20,6 +20,7 @@ import com.avaje.ebeaninternal.server.cluster.ClusterManager;
import com.avaje.ebeaninternal.server.lib.ShutdownManager;
import com.avaje.ebeaninternal.server.lib.sql.DataSourceAlert;
import com.avaje.ebeaninternal.server.lib.sql.DataSourcePool;
+import com.avaje.ebeaninternal.server.lib.sql.DataSourcePoolListener;
import com.avaje.ebeaninternal.server.lib.sql.SimpleDataSourceAlert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -311,7 +312,17 @@ public class DefaultContainer implements SpiContainer {
}
DataSourceAlert notify = new SimpleDataSourceAlert();
- return new DataSourcePool(notify, config.getName(), dsConfig);
+ DataSourcePoolListener listener = createListener(config, dsConfig);
+
+ return new DataSourcePool(notify, config.getName(), dsConfig, listener);
+ }
+
+ /**
+ * Create and return a DataSourcePoolListener if it has been specified.
+ */
+ private DataSourcePoolListener createListener(ServerConfig config, DataSourceConfig dsConfig) {
+ String poolListener = dsConfig.getPoolListener();
+ return poolListener != null ? (DataSourcePoolListener) config.getClassLoadConfig().newInstance(poolListener) : null;
}
/**
diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/InternalConfiguration.java b/src/main/java/com/avaje/ebeaninternal/server/core/InternalConfiguration.java
index cee293377..1eff41bc6 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/core/InternalConfiguration.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/core/InternalConfiguration.java
@@ -357,6 +357,6 @@ public class InternalConfiguration {
}
public GeneratedPropertyFactory getGeneratedPropertyFactory() {
- return new GeneratedPropertyFactory(serverConfig.getCurrentUserProvider());
+ return new GeneratedPropertyFactory(serverConfig);
}
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocManyJsonHelp.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocManyJsonHelp.java
index e6d30d68f..3ed83be20 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocManyJsonHelp.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocManyJsonHelp.java
@@ -31,7 +31,7 @@ public class BeanPropertyAssocManyJsonHelp {
*/
public BeanPropertyAssocManyJsonHelp(BeanPropertyAssocMany> many) {
this.many = many;
- this.jsonTransient = !ClassUtil.isJacksonObjectMapperPresent() ? null : new BeanPropertyAssocManyJsonTransient();
+ this.jsonTransient = new BeanPropertyAssocManyJsonTransient();
}
/**
@@ -81,9 +81,6 @@ public class BeanPropertyAssocManyJsonHelp {
*/
private void jsonReadTransientUsingObjectMapper(ReadJson readJson, EntityBean parentBean) throws IOException {
- if (jsonTransient == null) {
- throw new IllegalStateException("Jackson ObjectMapper is required to read this Transient property "+many.getFullBeanName());
- }
jsonTransient.jsonReadUsingObjectMapper(many, readJson, parentBean);
}
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/GeneratedPropertyFactory.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/GeneratedPropertyFactory.java
index db33ffe8e..5810f61ee 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/GeneratedPropertyFactory.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/GeneratedPropertyFactory.java
@@ -3,7 +3,9 @@ package com.avaje.ebeaninternal.server.deploy.generatedproperty;
import java.math.BigDecimal;
import java.util.HashSet;
+import com.avaje.ebean.config.ClassLoadConfig;
import com.avaje.ebean.config.CurrentUserProvider;
+import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
/**
@@ -13,9 +15,9 @@ public class GeneratedPropertyFactory {
private final CounterFactory counterFactory = new CounterFactory();
- private final InsertTimestampFactory insertFactory = new InsertTimestampFactory();
+ private final InsertTimestampFactory insertFactory;
- private final UpdateTimestampFactory updateFactory = new UpdateTimestampFactory();
+ private final UpdateTimestampFactory updateFactory;
private final HashSet numberTypes = new HashSet();
@@ -23,8 +25,15 @@ public class GeneratedPropertyFactory {
private final GeneratedWhoCreated generatedWhoCreated;
- public GeneratedPropertyFactory(CurrentUserProvider currentUserProvider) {
+ private final ClassLoadConfig classLoadConfig;
+ public GeneratedPropertyFactory(ServerConfig serverConfig) {
+
+ this.classLoadConfig = serverConfig.getClassLoadConfig();
+ this.insertFactory = new InsertTimestampFactory(classLoadConfig);
+ this.updateFactory = new UpdateTimestampFactory(classLoadConfig);
+
+ CurrentUserProvider currentUserProvider = serverConfig.getCurrentUserProvider();
if (currentUserProvider != null) {
generatedWhoCreated = new GeneratedWhoCreated(currentUserProvider);
generatedWhoModified = new GeneratedWhoModified(currentUserProvider);
@@ -44,7 +53,11 @@ public class GeneratedPropertyFactory {
numberTypes.add(BigDecimal.class.getName());
}
- private boolean isNumberType(String typeClassName) {
+ public ClassLoadConfig getClassLoadConfig() {
+ return classLoadConfig;
+ }
+
+ private boolean isNumberType(String typeClassName) {
return numberTypes.contains(typeClassName);
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/InsertTimestampFactory.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/InsertTimestampFactory.java
index fe9c5b37b..c9866f42e 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/InsertTimestampFactory.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/InsertTimestampFactory.java
@@ -9,7 +9,7 @@ import java.util.Map;
import javax.persistence.PersistenceException;
-import com.avaje.ebeaninternal.api.ClassUtil;
+import com.avaje.ebean.config.ClassLoadConfig;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
/**
@@ -21,25 +21,25 @@ public class InsertTimestampFactory {
final Map, GeneratedProperty> map = new HashMap, GeneratedProperty>();
- public InsertTimestampFactory() {
+ public InsertTimestampFactory(ClassLoadConfig classLoadConfig) {
map.put(Timestamp.class, new GeneratedInsertTimestamp());
map.put(java.util.Date.class, new GeneratedInsertDate());
map.put(Long.class, longTime);
map.put(long.class, longTime);
- if (ClassUtil.isPresent("java.time.LocalDate", this.getClass())) {
+ if (classLoadConfig.isJavaTimePresent()) {
map.put(LocalDateTime.class, new GeneratedInsertJavaTime.LocalDT());
map.put(OffsetDateTime.class, new GeneratedInsertJavaTime.OffsetDT());
map.put(ZonedDateTime.class, new GeneratedInsertJavaTime.ZonedDT());
}
- if (ClassUtil.isPresent("org.joda.time.LocalDateTime", this.getClass())) {
+ if (classLoadConfig.isJodaTimePresent()) {
map.put(org.joda.time.LocalDateTime.class, new GeneratedInsertJodaTime.LocalDT());
map.put(org.joda.time.DateTime.class, new GeneratedInsertJodaTime.DateTimeDT());
}
}
- public void setInsertTimestamp(DeployBeanProperty property) {
+ public void setInsertTimestamp(DeployBeanProperty property) {
property.setGeneratedProperty(createInsertTimestamp(property));
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/UpdateTimestampFactory.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/UpdateTimestampFactory.java
index 979352638..4b118ca08 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/UpdateTimestampFactory.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/UpdateTimestampFactory.java
@@ -9,7 +9,7 @@ import java.util.Map;
import javax.persistence.PersistenceException;
-import com.avaje.ebeaninternal.api.ClassUtil;
+import com.avaje.ebean.config.ClassLoadConfig;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
/**
@@ -21,18 +21,18 @@ public class UpdateTimestampFactory {
final Map, GeneratedProperty> map = new HashMap, GeneratedProperty>();
- public UpdateTimestampFactory() {
+ public UpdateTimestampFactory(ClassLoadConfig classLoadConfig) {
map.put(Timestamp.class, new GeneratedUpdateTimestamp());
map.put(java.util.Date.class, new GeneratedUpdateDate());
map.put(Long.class, longTime);
map.put(long.class, longTime);
- if (ClassUtil.isPresent("java.time.LocalDate", this.getClass())) {
+ if (classLoadConfig.isJavaTimePresent()) {
map.put(LocalDateTime.class, new GeneratedUpdateJavaTime.LocalDT());
map.put(OffsetDateTime.class, new GeneratedUpdateJavaTime.OffsetDT());
map.put(ZonedDateTime.class, new GeneratedUpdateJavaTime.ZonedDT());
}
- if (ClassUtil.isPresent("org.joda.time.LocalDateTime", this.getClass())) {
+ if (classLoadConfig.isJodaTimePresent()) {
map.put(org.joda.time.LocalDateTime.class, new GeneratedUpdateJodaTime.LocalDT());
map.put(org.joda.time.DateTime.class, new GeneratedUpdateJodaTime.DateTimeDT());
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/ReadAnnotations.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/ReadAnnotations.java
index e9b1b122f..e1bc81db2 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/ReadAnnotations.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/ReadAnnotations.java
@@ -1,6 +1,5 @@
package com.avaje.ebeaninternal.server.deploy.parse;
-import com.avaje.ebeaninternal.api.ClassUtil;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager;
import com.avaje.ebeaninternal.server.deploy.generatedproperty.GeneratedPropertyFactory;
@@ -37,8 +36,8 @@ public class ReadAnnotations {
this.generatedPropFactory = generatedPropFactory;
this.asOfViewSuffix = asOfViewSuffix;
this.versionsBetweenSuffix = versionsBetweenSuffix;
- this.javaxValidationAnnotations = ClassUtil.isJavaxValidationAnnotationsPresent();
- this.jacksonAnnotations = ClassUtil.isJacksonAnnotationsPresent();
+ this.javaxValidationAnnotations = generatedPropFactory.getClassLoadConfig().isJavaxValidationAnnotationsPresent();
+ this.jacksonAnnotations = generatedPropFactory.getClassLoadConfig().isJacksonAnnotationsPresent();
}
/**
diff --git a/src/main/java/com/avaje/ebeaninternal/server/lib/sql/DataSourcePool.java b/src/main/java/com/avaje/ebeaninternal/server/lib/sql/DataSourcePool.java
index e49013275..c69983ac4 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/lib/sql/DataSourcePool.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/lib/sql/DataSourcePool.java
@@ -171,10 +171,14 @@ public class DataSourcePool implements DataSource {
private final Runnable heartbeatRunnable = new HeartBeatRunnable();
public DataSourcePool(DataSourceAlert notify, String name, DataSourceConfig params) {
+ this(notify, name, params, null);
+ }
+
+ public DataSourcePool(DataSourceAlert notify, String name, DataSourceConfig params, DataSourcePoolListener listener) {
this.notify = notify;
this.name = name;
- this.poolListener = createPoolListener(params.getPoolListener());
+ this.poolListener = listener;
this.autoCommit = params.isAutoCommit();
this.transactionIsolation = params.getIsolationLevel();
@@ -238,20 +242,6 @@ public class DataSourcePool implements DataSource {
throw new SQLFeatureNotSupportedException("We do not support java.util.logging");
}
- /**
- * Create the DataSourcePoolListener if there is one.
- */
- private DataSourcePoolListener createPoolListener(String cn) {
- if (cn == null) {
- return null;
- }
- try {
- return (DataSourcePoolListener) ClassUtil.newInstance(cn, this.getClass());
- } catch (Exception e) {
- throw new IllegalArgumentException(e);
- }
- }
-
private void initialise() throws SQLException {
String transIsolation = TransactionIsolation.getLevelDescription(transactionIsolation);
diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/DefaultTypeManager.java b/src/main/java/com/avaje/ebeaninternal/server/type/DefaultTypeManager.java
index 0a81879f1..203f8f0d3 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/type/DefaultTypeManager.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/type/DefaultTypeManager.java
@@ -162,13 +162,13 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
this.typeMap = new ConcurrentHashMap, ScalarType>>();
this.nativeMap = new ConcurrentHashMap>();
- this.objectMapperPresent = ClassUtil.isJacksonObjectMapperPresent();
+ this.objectMapperPresent = config.getClassLoadConfig().isJacksonObjectMapperPresent();
this.extraTypeFactory = new DefaultTypeFactory(config);
initialiseStandard(jsonDateTime, config);
initialiseJavaTimeTypes(jsonDateTime, config);
- initialiseJodaTypes(jsonDateTime);
+ initialiseJodaTypes(jsonDateTime, config);
initialiseJacksonTypes(config);
if (isPostgres(config.getDatabasePlatform())) {
@@ -738,7 +738,7 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
*/
protected void initialiseJacksonTypes(ServerConfig config) {
- if (ClassUtil.isPresent("com.fasterxml.jackson.databind.ObjectMapper", this.getClass())) {
+ if (config.getClassLoadConfig().isJacksonObjectMapperPresent()) {
logger.trace("Registering JsonNode type support");
@@ -765,7 +765,7 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
}
protected void initialiseJavaTimeTypes(JsonConfig.DateTime mode, ServerConfig config) {
- if (ClassUtil.isPresent("java.time.LocalDate", this.getClass())) {
+ if (config.getClassLoadConfig().isJavaTimePresent()) {
logger.debug("Registering java.time data types");
typeMap.put(java.time.LocalDate.class, new ScalarTypeLocalDate());
typeMap.put(java.time.LocalDateTime.class, new ScalarTypeLocalDateTime(mode));
@@ -796,10 +796,10 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
* Detect if Joda classes are in the classpath and if so register the Joda
* data types.
*/
- protected void initialiseJodaTypes(JsonConfig.DateTime mode) {
+ protected void initialiseJodaTypes(JsonConfig.DateTime mode, ServerConfig config) {
// detect if Joda classes are in the classpath
- if (ClassUtil.isPresent("org.joda.time.LocalDateTime", this.getClass())) {
+ if (config.getClassLoadConfig().isJodaTimePresent()) {
// Joda classes are in the classpath so register the types
logger.debug("Registering Joda data types");
typeMap.put(LocalDateTime.class, new ScalarTypeJodaLocalDateTime(mode));
diff --git a/src/main/java/com/avaje/ebeaninternal/server/util/ClassPathSearch.java b/src/main/java/com/avaje/ebeaninternal/server/util/ClassPathSearch.java
index 2ca1d7ec5..1182d46b9 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/util/ClassPathSearch.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/util/ClassPathSearch.java
@@ -75,7 +75,7 @@ public class ClassPathSearch implements ClassPathSearchService {
if (classPathReaderCN != null) {
// use a user defined classPathReader
logger.info("Using [" + classPathReaderCN + "] to read the searchable class path");
- classPathReader = (ClassPathReader) ClassUtil.newInstance(classPathReaderCN, this.getClass());
+ classPathReader = (ClassPathReader) ClassUtil.newInstance(classPathReaderCN);
}
Object[] rawClassPaths = classPathReader.readPath(classLoader);
diff --git a/src/test/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/InsertTimestampFactoryTest.java b/src/test/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/InsertTimestampFactoryTest.java
index 8aca43860..47cf87ced 100644
--- a/src/test/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/InsertTimestampFactoryTest.java
+++ b/src/test/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/InsertTimestampFactoryTest.java
@@ -1,5 +1,6 @@
package com.avaje.ebeaninternal.server.deploy.generatedproperty;
+import com.avaje.ebean.config.ClassLoadConfig;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
import org.junit.Test;
@@ -11,7 +12,7 @@ import static org.junit.Assert.*;
public class InsertTimestampFactoryTest {
- InsertTimestampFactory factory = new InsertTimestampFactory();
+ InsertTimestampFactory factory = new InsertTimestampFactory(new ClassLoadConfig());
@Test
public void test_createdTimestamp_LocalDateTime() {
diff --git a/src/test/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/UpdateTimestampFactoryTest.java b/src/test/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/UpdateTimestampFactoryTest.java
index f861efe63..956da2a07 100644
--- a/src/test/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/UpdateTimestampFactoryTest.java
+++ b/src/test/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/UpdateTimestampFactoryTest.java
@@ -1,5 +1,6 @@
package com.avaje.ebeaninternal.server.deploy.generatedproperty;
+import com.avaje.ebean.config.ClassLoadConfig;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
import org.junit.Test;
@@ -12,7 +13,7 @@ import static org.junit.Assert.*;
public class UpdateTimestampFactoryTest {
- UpdateTimestampFactory factory = new UpdateTimestampFactory();
+ UpdateTimestampFactory factory = new UpdateTimestampFactory(new ClassLoadConfig());
@Test
public void test_createdTimestamp_LocalDateTime() {