cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ntimof...@apache.org
Subject [2/2] cayenne git commit: CAY-2262: Make cayenne-client and related auto loaded CAY-2277: Create ClientRuntime with ClientRuntimeBuilder just like ServerRuntime
Date Fri, 07 Apr 2017 11:29:03 GMT
CAY-2262: Make cayenne-client and related auto loaded
CAY-2277: Create ClientRuntime with ClientRuntimeBuilder just like ServerRuntime


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/6888884a
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/6888884a
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/6888884a

Branch: refs/heads/master
Commit: 6888884af04180c77c77f7a77715458df923cddf
Parents: 5008dce
Author: Nikita Timofeev <stariy95@gmail.com>
Authored: Fri Apr 7 14:28:22 2017 +0300
Committer: Nikita Timofeev <stariy95@gmail.com>
Committed: Fri Apr 7 14:28:22 2017 +0300

----------------------------------------------------------------------
 .../cache/CacheInvalidationModuleProvider.java  |  50 ------
 .../CacheInvalidationServerModuleProvider.java  |  50 ++++++
 ...iguration.server.CayenneServerModuleProvider |  20 +++
 .../org.apache.cayenne.di.spi.ModuleProvider    |  20 ---
 ...enneCacheInvalidationModuleProviderTest.java |   3 +-
 cayenne-client-jetty/pom.xml                    |   7 +
 .../rop/client/JettyClientModuleProvider.java   |  48 ++++++
 ...ation.rop.client.CayenneClientModuleProvider |  20 +++
 .../rop/client/JettyModuleProviderTest.java     |  35 +++++
 .../rop/client/CayenneClientModuleProvider.java |  29 ++++
 .../rop/client/ClientLocalRuntime.java          |   8 +-
 .../configuration/rop/client/ClientModule.java  |  25 ++-
 .../configuration/rop/client/ClientRuntime.java |  25 ++-
 .../rop/client/ClientRuntimeBuilder.java        | 156 +++++++++++++++++++
 .../rop/client/LocalConnectionProvider.java     |   2 +-
 .../client/MainCayenneClientModuleProvider.java |  46 ++++++
 ...ation.rop.client.CayenneClientModuleProvider |  20 +++
 .../rop/client/ClientLocalRuntimeTest.java      |  12 +-
 .../MainCayenneClientModuleProviderTest.java    |  35 +++++
 .../unit/di/client/ClientCaseModule.java        |  26 ++--
 .../unit/di/client/ClientRuntimeProvider.java   |  46 ++----
 .../cayenne/crypto/CryptoModuleProvider.java    |  47 ------
 .../crypto/CryptoServerModuleProvider.java      |  47 ++++++
 ...iguration.server.CayenneServerModuleProvider |  20 +++
 .../org.apache.cayenne.di.spi.ModuleProvider    |  20 ---
 .../crypto/CryptoModuleProviderTest.java        |   3 +-
 .../cayenne/dbsync/DbSyncModuleProvider.java    |  48 ------
 .../dbsync/DbSyncServerModuleProvider.java      |  48 ++++++
 ...iguration.server.CayenneServerModuleProvider |  20 +++
 .../org.apache.cayenne.di.spi.ModuleProvider    |  20 ---
 .../dbsync/DbSyncModuleProviderTest.java        |   3 +-
 .../org/apache/cayenne/di/spi/ModuleLoader.java |   9 +-
 .../apache/cayenne/di/spi/ModuleProvider.java   |   5 +
 .../cayenne/di/spi/CustomModuleProvider.java    |  26 ++++
 .../apache/cayenne/di/spi/ModuleLoaderTest.java |  65 +++++++-
 ...g.apache.cayenne.di.spi.CustomModuleProvider |  21 +++
 .../cayenne/java8/Java8ModuleProvider.java      |  46 ------
 .../java8/Java8ServerModuleProvider.java        |  46 ++++++
 ...iguration.server.CayenneServerModuleProvider |  20 +++
 .../org.apache.cayenne.di.spi.ModuleProvider    |  20 ---
 .../cayenne/java8/Java8ModuleProviderTest.java  |   3 +-
 .../cayenne/jcache/JCacheModuleProvider.java    |  50 ------
 .../jcache/JCacheServerModuleProvider.java      |  50 ++++++
 ...iguration.server.CayenneServerModuleProvider |  20 +++
 .../org.apache.cayenne.di.spi.ModuleProvider    |  20 ---
 .../jcache/CayenneJCacheModuleProviderTest.java |   3 +-
 .../apache/cayenne/joda/JodaModuleProvider.java |  46 ------
 .../cayenne/joda/JodaServerModuleProvider.java  |  46 ++++++
 ...iguration.server.CayenneServerModuleProvider |  20 +++
 .../org.apache.cayenne.di.spi.ModuleProvider    |  20 ---
 .../cayenne/joda/JodaModuleProviderTest.java    |   3 +-
 .../cayenne/project/ProjectModuleProvider.java  |  46 ------
 .../project/ProjectServerModuleProvider.java    |  46 ++++++
 ...iguration.server.CayenneServerModuleProvider |  20 +++
 .../org.apache.cayenne.di.spi.ModuleProvider    |  20 ---
 .../project/ProjectModuleProviderTest.java      |   3 +-
 cayenne-protostuff/pom.xml                      |  15 +-
 .../ProtostuffServerModuleProvider.java         |  51 ++++++
 .../client/ProtostuffClientModuleProvider.java  |  48 ++++++
 ...ation.rop.client.CayenneClientModuleProvider |  20 +++
 ...iguration.server.CayenneServerModuleProvider |  20 +++
 .../client/ProtostuffModuleProviderTest.java    |  42 +++++
 .../ProtostuffLocalConnectionProvider.java      |   4 +-
 .../cayenne/rop/protostuff/RuntimeBase.java     |  31 ++--
 .../server/CayenneServerModuleProvider.java     |  29 ++++
 .../server/MainCayenneServerModuleProvider.java |  48 ++++++
 .../server/ServerModuleProvider.java            |  48 ------
 .../server/ServerRuntimeBuilder.java            |   2 +-
 ...iguration.server.CayenneServerModuleProvider |  20 +++
 .../org.apache.cayenne.di.spi.ModuleProvider    |  20 ---
 .../server/ServerModuleProviderTest.java        |   2 +-
 .../unit/util/ModuleProviderChecker.java        |  17 +-
 docs/doc/src/main/resources/RELEASE-NOTES.txt   |   1 +
 docs/doc/src/main/resources/UPGRADE.txt         |  23 ++-
 .../cayenne/event/JGroupsModuleProvider.java    |  50 ------
 .../event/JGroupsServerModuleProvider.java      |  50 ++++++
 ...iguration.server.CayenneServerModuleProvider |  20 +++
 .../org.apache.cayenne.di.spi.ModuleProvider    |  20 ---
 .../event/CayenneJGroupsModuleProviderTest.java |   3 +-
 .../apache/cayenne/event/JMSModuleProvider.java |  50 ------
 .../cayenne/event/JMSServerModuleProvider.java  |  50 ++++++
 ...iguration.server.CayenneServerModuleProvider |  20 +++
 .../org.apache.cayenne.di.spi.ModuleProvider    |  20 ---
 .../event/CayenneJMSModuleProviderTest.java     |   3 +-
 .../cayenne/event/XMPPModuleProvider.java       |  50 ------
 .../cayenne/event/XMPPServerModuleProvider.java |  50 ++++++
 ...iguration.server.CayenneServerModuleProvider |  20 +++
 .../org.apache.cayenne.di.spi.ModuleProvider    |  20 ---
 .../event/CayenneXMPPModuleProviderTest.java    |   3 +-
 89 files changed, 1644 insertions(+), 859 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/lifecycle/cache/CacheInvalidationModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/lifecycle/cache/CacheInvalidationModuleProvider.java b/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/lifecycle/cache/CacheInvalidationModuleProvider.java
deleted file mode 100644
index 3696686..0000000
--- a/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/lifecycle/cache/CacheInvalidationModuleProvider.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.lifecycle.cache;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.apache.cayenne.configuration.server.ServerModule;
-import org.apache.cayenne.di.Module;
-import org.apache.cayenne.di.spi.ModuleProvider;
-
-/**
- * @since 4.0
- */
-public class CacheInvalidationModuleProvider implements ModuleProvider {
-
-    @Override
-    public Module module() {
-        return new CacheInvalidationModule();
-    }
-
-    @Override
-    public Class<? extends Module> moduleType() {
-        return CacheInvalidationModule.class;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public Collection<Class<? extends Module>> overrides() {
-        Collection modules = Collections.singletonList(ServerModule.class);
-        return modules;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/lifecycle/cache/CacheInvalidationServerModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/lifecycle/cache/CacheInvalidationServerModuleProvider.java b/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/lifecycle/cache/CacheInvalidationServerModuleProvider.java
new file mode 100644
index 0000000..72af1f3
--- /dev/null
+++ b/cayenne-cache-invalidation/src/main/java/org/apache/cayenne/lifecycle/cache/CacheInvalidationServerModuleProvider.java
@@ -0,0 +1,50 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.lifecycle.cache;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
+import org.apache.cayenne.configuration.server.ServerModule;
+import org.apache.cayenne.di.Module;
+
+/**
+ * @since 4.0
+ */
+public class CacheInvalidationServerModuleProvider implements CayenneServerModuleProvider {
+
+    @Override
+    public Module module() {
+        return new CacheInvalidationModule();
+    }
+
+    @Override
+    public Class<? extends Module> moduleType() {
+        return CacheInvalidationModule.class;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Collection<Class<? extends Module>> overrides() {
+        Collection modules = Collections.singletonList(ServerModule.class);
+        return modules;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-cache-invalidation/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-cache-invalidation/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider b/cayenne-cache-invalidation/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
new file mode 100644
index 0000000..cbfe364
--- /dev/null
+++ b/cayenne-cache-invalidation/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
@@ -0,0 +1,20 @@
+##################################################################
+#   Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+##################################################################
+
+org.apache.cayenne.lifecycle.cache.CacheInvalidationServerModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-cache-invalidation/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-cache-invalidation/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider b/cayenne-cache-invalidation/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider
deleted file mode 100644
index 4fc646c..0000000
--- a/cayenne-cache-invalidation/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider
+++ /dev/null
@@ -1,20 +0,0 @@
-##################################################################
-#   Licensed to the Apache Software Foundation (ASF) under one
-#  or more contributor license agreements.  See the NOTICE file
-#  distributed with this work for additional information
-#  regarding copyright ownership.  The ASF licenses this file
-#  to you under the Apache License, Version 2.0 (the
-#  "License"); you may not use this file except in compliance
-#  with the License.  You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing,
-#  software distributed under the License is distributed on an
-#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-#  KIND, either express or implied.  See the License for the
-#  specific language governing permissions and limitations
-#  under the License.
-##################################################################
-
-org.apache.cayenne.lifecycle.cache.CacheInvalidationModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-cache-invalidation/src/test/java/org/apache/cayenne/lifecycle/cache/CayenneCacheInvalidationModuleProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-cache-invalidation/src/test/java/org/apache/cayenne/lifecycle/cache/CayenneCacheInvalidationModuleProviderTest.java b/cayenne-cache-invalidation/src/test/java/org/apache/cayenne/lifecycle/cache/CayenneCacheInvalidationModuleProviderTest.java
index 4928fd1..78c4ee8 100644
--- a/cayenne-cache-invalidation/src/test/java/org/apache/cayenne/lifecycle/cache/CayenneCacheInvalidationModuleProviderTest.java
+++ b/cayenne-cache-invalidation/src/test/java/org/apache/cayenne/lifecycle/cache/CayenneCacheInvalidationModuleProviderTest.java
@@ -19,6 +19,7 @@
 
 package org.apache.cayenne.lifecycle.cache;
 
+import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
 import org.apache.cayenne.unit.util.ModuleProviderChecker;
 import org.junit.Test;
 
@@ -26,6 +27,6 @@ public class CayenneCacheInvalidationModuleProviderTest {
 
     @Test
     public void testAutoLoadable() {
-        ModuleProviderChecker.testProviderPresent(CacheInvalidationModuleProvider.class);
+        ModuleProviderChecker.testProviderPresent(CacheInvalidationServerModuleProvider.class, CayenneServerModuleProvider.class);
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client-jetty/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-client-jetty/pom.xml b/cayenne-client-jetty/pom.xml
index 96cdd37..d12861b 100644
--- a/cayenne-client-jetty/pom.xml
+++ b/cayenne-client-jetty/pom.xml
@@ -91,6 +91,13 @@
 
         <!--Test dependencies-->
         <dependency>
+            <groupId>org.apache.cayenne</groupId>
+            <artifactId>cayenne-server</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.eclipse.jetty.http2</groupId>
             <artifactId>http2-server</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client-jetty/src/main/java/org/apache/cayenne/configuration/rop/client/JettyClientModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-client-jetty/src/main/java/org/apache/cayenne/configuration/rop/client/JettyClientModuleProvider.java b/cayenne-client-jetty/src/main/java/org/apache/cayenne/configuration/rop/client/JettyClientModuleProvider.java
new file mode 100644
index 0000000..802feb1
--- /dev/null
+++ b/cayenne-client-jetty/src/main/java/org/apache/cayenne/configuration/rop/client/JettyClientModuleProvider.java
@@ -0,0 +1,48 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.configuration.rop.client;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.cayenne.di.Module;
+
+/**
+ * @since 4.0
+ */
+public class JettyClientModuleProvider implements CayenneClientModuleProvider {
+
+    @Override
+    public Module module() {
+        return new ClientJettyHttpModule();
+    }
+
+    @Override
+    public Class<? extends Module> moduleType() {
+        return ClientJettyHttpModule.class;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Collection<Class<? extends Module>> overrides() {
+        Collection modules = Collections.singletonList(ClientModule.class);
+        return modules;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client-jetty/src/main/resources/META-INF/services/org.apache.cayenne.configuration.rop.client.CayenneClientModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-client-jetty/src/main/resources/META-INF/services/org.apache.cayenne.configuration.rop.client.CayenneClientModuleProvider b/cayenne-client-jetty/src/main/resources/META-INF/services/org.apache.cayenne.configuration.rop.client.CayenneClientModuleProvider
new file mode 100644
index 0000000..2c1d16f
--- /dev/null
+++ b/cayenne-client-jetty/src/main/resources/META-INF/services/org.apache.cayenne.configuration.rop.client.CayenneClientModuleProvider
@@ -0,0 +1,20 @@
+##################################################################
+#   Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+##################################################################
+
+org.apache.cayenne.configuration.rop.client.JettyClientModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client-jetty/src/test/java/org/apache/cayenne/configuration/rop/client/JettyModuleProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client-jetty/src/test/java/org/apache/cayenne/configuration/rop/client/JettyModuleProviderTest.java b/cayenne-client-jetty/src/test/java/org/apache/cayenne/configuration/rop/client/JettyModuleProviderTest.java
new file mode 100644
index 0000000..deb3776
--- /dev/null
+++ b/cayenne-client-jetty/src/test/java/org/apache/cayenne/configuration/rop/client/JettyModuleProviderTest.java
@@ -0,0 +1,35 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.configuration.rop.client;
+
+import org.apache.cayenne.unit.util.ModuleProviderChecker;
+import org.junit.Test;
+
+/**
+ * @since 4.0
+ */
+public class JettyModuleProviderTest {
+
+    @Test
+    public void testClientAutoLoadable() {
+        ModuleProviderChecker.testProviderPresent(JettyClientModuleProvider.class, CayenneClientModuleProvider.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/CayenneClientModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/CayenneClientModuleProvider.java b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/CayenneClientModuleProvider.java
new file mode 100644
index 0000000..b617f9c
--- /dev/null
+++ b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/CayenneClientModuleProvider.java
@@ -0,0 +1,29 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.configuration.rop.client;
+
+import org.apache.cayenne.di.spi.ModuleProvider;
+
+/**
+ * This interface implementations will be used by {@link ClientRuntimeBuilder} to auto-load client modules.
+ * @since 4.0
+ */
+public interface CayenneClientModuleProvider extends ModuleProvider {
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientLocalRuntime.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientLocalRuntime.java b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientLocalRuntime.java
index 2e11a0d..af1ddd5 100644
--- a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientLocalRuntime.java
+++ b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientLocalRuntime.java
@@ -37,10 +37,14 @@ import static java.util.Arrays.asList;
  * connection on top of a server stack.
  *
  * @since 3.1
+ * @deprecated since 4.0, use {@link ClientRuntimeBuilder#local(Injector)}
  */
-// TODO: module auto-loading and ClientLocalRuntimeBuilder
+@Deprecated
 public class ClientLocalRuntime extends ClientRuntime {
 
+    /**
+     * Moved to {@link ClientRuntime#CLIENT_SERVER_CHANNEL_KEY}
+     */
     public static final String CLIENT_SERVER_CHANNEL_KEY = "client-server-channel";
 
     private static Collection<Module> collectModules(
@@ -57,7 +61,7 @@ public class ClientLocalRuntime extends ClientRuntime {
         modules.add(new Module() {
 
             public void configure(Binder binder) {
-                binder.bind(Key.get(DataChannel.class, CLIENT_SERVER_CHANNEL_KEY)).toProviderInstance(
+                binder.bind(Key.get(DataChannel.class, ClientRuntime.CLIENT_SERVER_CHANNEL_KEY)).toProviderInstance(
                         new LocalClientServerChannelProvider(serverInjector));
                 binder.bind(ClientConnection.class).toProviderInstance(new LocalConnectionProvider());
             }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientModule.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientModule.java b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientModule.java
index 519a1d3..efae1c8 100644
--- a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientModule.java
+++ b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientModule.java
@@ -41,11 +41,22 @@ import org.apache.cayenne.rop.http.ClientHessianSerializationServiceProvider;
  * A DI module containing all Cayenne ROP client runtime configurations.
  * 
  * @since 3.1
+ * @since 4.0 this module is auto-loaded by {@link ClientRuntimeBuilder}
  */
 public class ClientModule implements Module {
 
-    protected Map<String, String> properties;
+    /**
+     * @deprecated since 4.0 in favour of {@link ClientRuntimeBuilder}
+     * @see ClientRuntimeBuilder#properties(Map)
+     */
+    @Deprecated
+    protected Map<String, String> properties = null;
 
+    /**
+     * @deprecated since 4.0 in favour of {@link ClientRuntimeBuilder}
+     * @see ClientRuntimeBuilder#properties(Map)
+     */
+    @Deprecated
     public ClientModule(Map<String, String> properties) {
         if (properties == null) {
             throw new NullPointerException("Null 'properties' map");
@@ -54,10 +65,20 @@ public class ClientModule implements Module {
         this.properties = properties;
     }
 
+    /**
+     * @since 4.0
+     */
+    public ClientModule() {
+    }
+
+    @SuppressWarnings("deprecation")
     public void configure(Binder binder) {
 
         // expose user-provided ROP properties as the main properties map
-        ServerModule.contributeProperties(binder).putAll(properties);
+        // binding here is left only for backward compatibility, should go away with the deprecated code.
+        if(properties != null) {
+            ServerModule.contributeProperties(binder).putAll(properties);
+        }
 
         binder.bind(ObjectContextFactory.class).to(CayenneContextFactory.class);
         binder.bind(ROPSerializationService.class).toProvider(ClientHessianSerializationServiceProvider.class);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientRuntime.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientRuntime.java b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientRuntime.java
index 7e54c8c..2bd113f 100644
--- a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientRuntime.java
+++ b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientRuntime.java
@@ -33,16 +33,33 @@ import static java.util.Arrays.asList;
  * A user application entry point to Cayenne stack on the ROP client.
  * 
  * @since 3.1
+ * @since 4.0 preferred way to create this class is with {@link ClientRuntime#builder()} method.
  */
-// TODO: module auto-loading and ClientRuntimeBuilder
 public class ClientRuntime extends CayenneRuntime {
 
+	/**
+	 * @since 4.0 moved from deprecated ClientLocalRuntime class
+	 */
+	public static final String CLIENT_SERVER_CHANNEL_KEY = "client-server-channel";
+
+	/**
+	 * Creates new builder of client runtime
+	 * @return client runtime builder
+	 *
+	 * @since 4.0
+	 */
+	public static ClientRuntimeBuilder builder() {
+		return new ClientRuntimeBuilder();
+	}
+
+	@Deprecated
 	private static Collection<Module> collectModules(Map<String, String> properties, Module... extraModules) {
 
 		Collection<Module> modules = extraModules != null ? asList(extraModules) : Collections.<Module>emptyList();
 		return collectModules(properties, modules);
 	}
 
+	@Deprecated
 	private static Collection<Module> collectModules(Map<String, String> properties, Collection<Module> extraModules) {
 		Collection<Module> modules = new ArrayList<>();
 		modules.add(new ClientModule(properties));
@@ -61,7 +78,10 @@ public class ClientRuntime extends CayenneRuntime {
 	 * etc. Recognized property keys are defined in {@link ClientModule}. An
 	 * optional array of extra modules may contain service overrides and/or user
 	 * services.
+	 *
+	 * @deprecated since 4.0, use {@link ClientRuntime#builder()} instead.
 	 */
+	@Deprecated
 	public ClientRuntime(Map<String, String> properties, Collection<Module> extraModules) {
 		this(collectModules(properties, extraModules));
 	}
@@ -73,7 +93,10 @@ public class ClientRuntime extends CayenneRuntime {
 	 * etc. Recognized property keys are defined in {@link ClientModule}. An
 	 * optional collection of extra modules may contain service overrides and/or
 	 * user services.
+	 *
+	 * @deprecated since 4.0, use {@link ClientRuntime#builder()} instead.
 	 */
+	@Deprecated
 	public ClientRuntime(Map<String, String> properties, Module... extraModules) {
 		this(collectModules(properties, extraModules));
 	}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientRuntimeBuilder.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientRuntimeBuilder.java b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientRuntimeBuilder.java
new file mode 100644
index 0000000..743da78
--- /dev/null
+++ b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientRuntimeBuilder.java
@@ -0,0 +1,156 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.configuration.rop.client;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cayenne.DataChannel;
+import org.apache.cayenne.configuration.server.ServerModule;
+import org.apache.cayenne.di.Binder;
+import org.apache.cayenne.di.Injector;
+import org.apache.cayenne.di.Key;
+import org.apache.cayenne.di.Module;
+import org.apache.cayenne.di.spi.ModuleLoader;
+import org.apache.cayenne.remote.ClientConnection;
+
+
+/**
+ * <p>
+ * A convenience class to assemble custom ClientRuntime.
+ * It allows to easily configure custom modules and create local runtime.
+ * </p>
+ * <p>
+ * To create this builder use {@link ClientRuntime#builder()} method.
+ * </p>
+ *
+ * @since 4.0
+ */
+public class ClientRuntimeBuilder {
+
+    private List<Module> modules;
+    private boolean autoLoadModules;
+    private boolean local;
+    Injector serverInjector;
+    private Map<String, String> properties;
+
+    ClientRuntimeBuilder() {
+        modules = new ArrayList<>();
+        autoLoadModules = true;
+        local = false;
+        properties = null;
+    }
+
+    /**
+     * Disables DI module auto-loading. By default auto-loading is enabled based on
+     * {@link org.apache.cayenne.di.spi.ModuleLoader} service provider interface.
+     * If you decide to disable auto-loading, make sure you provide all the modules that you need.
+     *
+     * @return this builder instance.
+     */
+    public ClientRuntimeBuilder disableModulesAutoLoading() {
+        this.autoLoadModules = false;
+        return this;
+    }
+
+    public ClientRuntimeBuilder addModule(Module module) {
+        modules.add(module);
+        return this;
+    }
+
+    public ClientRuntimeBuilder addModules(Collection<Module> modules) {
+        this.modules.addAll(modules);
+        return this;
+    }
+
+    /**
+     * @param properties contributed to {@link ServerModule}
+     * @return this builder
+     */
+    public ClientRuntimeBuilder properties(Map<String, String> properties) {
+        this.properties = properties;
+        return this;
+    }
+
+    /**
+     * Create {@link ClientRuntime} that provides an ROP stack based on a local
+     * connection on top of a server stack.
+     *
+     * @param serverInjector server injector
+     * @return this builder
+     */
+    public ClientRuntimeBuilder local(Injector serverInjector) {
+        this.local = true;
+        this.serverInjector = serverInjector;
+        return this;
+    }
+
+    public ClientRuntime build() {
+        Collection<Module> allModules = new ArrayList<>();
+
+        // first load default or auto-loaded modules...
+        allModules.addAll(autoLoadModules ? autoLoadedModules() : defaultModules());
+
+        // custom modules override default and auto-loaded ...
+        allModules.addAll(modules);
+
+        // builder modules override default, auto-loaded and custom modules...
+        allModules.addAll(builderModules());
+
+        return new ClientRuntime(allModules);
+    }
+
+    private Collection<? extends Module> autoLoadedModules() {
+        return new ModuleLoader().load(CayenneClientModuleProvider.class);
+    }
+
+    private Collection<? extends Module> defaultModules() {
+        return Collections.singleton(new ClientModule());
+    }
+
+    private Collection<? extends Module> builderModules() {
+        Collection<Module> modules = new ArrayList<>();
+
+        if(properties != null) {
+            modules.add(new Module() {
+                @Override
+                public void configure(Binder binder) {
+                    ServerModule.contributeProperties(binder).putAll(properties);
+                }
+            });
+        }
+
+        if(local) {
+            modules.add(new Module() {
+                @Override
+                public void configure(Binder binder) {
+                    binder.bind(Key.get(DataChannel.class, ClientRuntime.CLIENT_SERVER_CHANNEL_KEY))
+                            .toProviderInstance(new LocalClientServerChannelProvider(serverInjector));
+                    binder.bind(ClientConnection.class).toProviderInstance(new LocalConnectionProvider());
+                }
+            });
+        }
+
+        return modules;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/LocalConnectionProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/LocalConnectionProvider.java b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/LocalConnectionProvider.java
index bb430db..c4cb03c 100644
--- a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/LocalConnectionProvider.java
+++ b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/LocalConnectionProvider.java
@@ -30,7 +30,7 @@ import org.apache.cayenne.remote.service.LocalConnection;
  */
 public class LocalConnectionProvider implements Provider<ClientConnection> {
 
-    @Inject(ClientLocalRuntime.CLIENT_SERVER_CHANNEL_KEY)
+    @Inject(ClientRuntime.CLIENT_SERVER_CHANNEL_KEY)
     protected Provider<DataChannel> clientServerChannelProvider;
 
     public ClientConnection get() throws ConfigurationException {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/MainCayenneClientModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/MainCayenneClientModuleProvider.java b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/MainCayenneClientModuleProvider.java
new file mode 100644
index 0000000..ea58207
--- /dev/null
+++ b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/MainCayenneClientModuleProvider.java
@@ -0,0 +1,46 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.configuration.rop.client;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.cayenne.di.Module;
+
+/**
+ * @since 4.0
+ */
+public class MainCayenneClientModuleProvider implements CayenneClientModuleProvider {
+
+    @Override
+    public Module module() {
+        return new ClientModule();
+    }
+
+    @Override
+    public Class<? extends Module> moduleType() {
+        return ClientModule.class;
+    }
+
+    @Override
+    public Collection<Class<? extends Module>> overrides() {
+        return Collections.emptyList();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client/src/main/resources/META-INF/services/org.apache.cayenne.configuration.rop.client.CayenneClientModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-client/src/main/resources/META-INF/services/org.apache.cayenne.configuration.rop.client.CayenneClientModuleProvider b/cayenne-client/src/main/resources/META-INF/services/org.apache.cayenne.configuration.rop.client.CayenneClientModuleProvider
new file mode 100644
index 0000000..0fe164d
--- /dev/null
+++ b/cayenne-client/src/main/resources/META-INF/services/org.apache.cayenne.configuration.rop.client.CayenneClientModuleProvider
@@ -0,0 +1,20 @@
+##################################################################
+#   Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+##################################################################
+
+org.apache.cayenne.configuration.rop.client.MainCayenneClientModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client/src/test/java/org/apache/cayenne/configuration/rop/client/ClientLocalRuntimeTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/configuration/rop/client/ClientLocalRuntimeTest.java b/cayenne-client/src/test/java/org/apache/cayenne/configuration/rop/client/ClientLocalRuntimeTest.java
index d581104..1e9dbe6 100644
--- a/cayenne-client/src/test/java/org/apache/cayenne/configuration/rop/client/ClientLocalRuntimeTest.java
+++ b/cayenne-client/src/test/java/org/apache/cayenne/configuration/rop/client/ClientLocalRuntimeTest.java
@@ -31,7 +31,6 @@ import org.apache.cayenne.remote.service.LocalConnection;
 import org.junit.Test;
 
 import java.util.Collection;
-import java.util.Collections;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -50,8 +49,10 @@ public class ClientLocalRuntimeTest {
 			}
 		};
 
-		ClientLocalRuntime runtime = new ClientLocalRuntime(DIBootstrap.createInjector(serverModule),
-				Collections.<String, String> emptyMap());
+		ClientRuntime runtime = ClientRuntime.builder()
+				.disableModulesAutoLoading()
+				.local(DIBootstrap.createInjector(serverModule))
+				.build();
 		Collection<Module> cmodules = runtime.getModules();
 		assertEquals(2, cmodules.size());
 
@@ -79,8 +80,9 @@ public class ClientLocalRuntimeTest {
 			}
 		};
 
-		ClientLocalRuntime runtime = new ClientLocalRuntime(DIBootstrap.createInjector(serverModule),
-				Collections.EMPTY_MAP);
+		ClientRuntime runtime = ClientRuntime.builder()
+				.local(DIBootstrap.createInjector(serverModule))
+				.build();
 
 		ClientConnection connection = runtime.getConnection();
 		assertNotNull(connection);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client/src/test/java/org/apache/cayenne/configuration/rop/client/MainCayenneClientModuleProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/configuration/rop/client/MainCayenneClientModuleProviderTest.java b/cayenne-client/src/test/java/org/apache/cayenne/configuration/rop/client/MainCayenneClientModuleProviderTest.java
new file mode 100644
index 0000000..3067a50
--- /dev/null
+++ b/cayenne-client/src/test/java/org/apache/cayenne/configuration/rop/client/MainCayenneClientModuleProviderTest.java
@@ -0,0 +1,35 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.configuration.rop.client;
+
+import org.apache.cayenne.unit.util.ModuleProviderChecker;
+import org.junit.Test;
+
+/**
+ * @since 4.0
+ */
+public class MainCayenneClientModuleProviderTest {
+
+    @Test
+    public void testAutoLoadable() {
+        ModuleProviderChecker.testProviderPresent(MainCayenneClientModuleProvider.class, CayenneClientModuleProvider.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientCaseModule.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientCaseModule.java b/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientCaseModule.java
index 284e89d..38b8db4 100644
--- a/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientCaseModule.java
+++ b/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientCaseModule.java
@@ -42,27 +42,21 @@ public class ClientCaseModule implements Module {
 
         // singletons
 
-        binder.bind(UnitTestLifecycleManager.class).toInstance(
-                new ClientCaseLifecycleManager(testScope));
-        binder.bind(Key.get(DataChannelInterceptor.class, ClientCase.ROP_CLIENT_KEY)).to(
-                ClientServerDataChannelInterceptor.class);
+        binder.bind(UnitTestLifecycleManager.class).toInstance(new ClientCaseLifecycleManager(testScope));
+        binder.bind(Key.get(DataChannelInterceptor.class, ClientCase.ROP_CLIENT_KEY))
+                .to(ClientServerDataChannelInterceptor.class);
 
         // test-scoped objects
 
-        binder.bind(ClientCaseProperties.class).to(ClientCaseProperties.class).in(
-                testScope);
+        binder.bind(ClientCaseProperties.class).to(ClientCaseProperties.class).in(testScope);
 
-        binder.bind(ClientRuntime.class).toProvider(ClientRuntimeProvider.class).in(
-                testScope);
+        binder.bind(ClientRuntime.class).toProvider(ClientRuntimeProvider.class).in(testScope);
 
-        binder.bind(Key.get(ObjectContext.class, ClientCase.ROP_CLIENT_KEY)).toProvider(
-                ClientCaseObjectContextProvider.class).in(testScope);
-        binder.bind(CayenneContext.class).toProvider(
-                ClientCaseCayenneContextProvider.class).in(testScope);
+        binder.bind(Key.get(ObjectContext.class, ClientCase.ROP_CLIENT_KEY))
+                .toProvider(ClientCaseObjectContextProvider.class).in(testScope);
+        binder.bind(CayenneContext.class).toProvider(ClientCaseCayenneContextProvider.class).in(testScope);
 
-        binder.bind(ClientServerChannel.class).toProvider(
-                ClientServerChannelProvider.class).in(testScope);
-        binder.bind(ClientConnection.class).toProvider(
-                ClientCaseClientConnectionProvider.class).in(testScope);
+        binder.bind(ClientServerChannel.class).toProvider(ClientServerChannelProvider.class).in(testScope);
+        binder.bind(ClientConnection.class).toProvider(ClientCaseClientConnectionProvider.class).in(testScope);
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientRuntimeProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientRuntimeProvider.java b/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientRuntimeProvider.java
index 595cb4e..ed74f4c 100644
--- a/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientRuntimeProvider.java
+++ b/cayenne-client/src/test/java/org/apache/cayenne/unit/di/client/ClientRuntimeProvider.java
@@ -20,53 +20,37 @@ package org.apache.cayenne.unit.di.client;
 
 import org.apache.cayenne.ConfigurationException;
 import org.apache.cayenne.DataChannel;
-import org.apache.cayenne.configuration.rop.client.ClientLocalRuntime;
 import org.apache.cayenne.configuration.rop.client.ClientRuntime;
+import org.apache.cayenne.configuration.rop.client.LocalConnectionProvider;
 import org.apache.cayenne.configuration.server.ServerRuntime;
 import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.di.Injector;
 import org.apache.cayenne.di.Key;
 import org.apache.cayenne.di.Module;
 import org.apache.cayenne.di.Provider;
+import org.apache.cayenne.remote.ClientConnection;
 
 public class ClientRuntimeProvider implements Provider<ClientRuntime> {
 
-    @Inject
     // injecting provider to make this provider independent from scoping of ServerRuntime
+    @Inject
     protected Provider<ServerRuntime> serverRuntimeProvider;
 
     @Inject
     protected ClientCaseProperties clientCaseProperties;
 
     public ClientRuntime get() throws ConfigurationException {
-        Injector serverInjector = serverRuntimeProvider.get().getInjector();
-        return new ClientLocalRuntime(serverInjector, clientCaseProperties
-                .getRuntimeProperties(), new ClientExtraModule(serverInjector));
-    }
-
-    class ClientExtraModule implements Module {
-
-        private Injector serverInjector;
-
-        ClientExtraModule(Injector serverInjector) {
-            this.serverInjector = serverInjector;
-        }
-
-        public void configure(Binder binder) {
-
-            // these are the objects overriding standard ClientLocalModule definitions or
-            // dependencies needed by such overrides
-
-            // add an interceptor between client and server parts to capture and inspect
-            // the traffic
-            binder
-                    .bind(
-                            Key.get(
-                                    DataChannel.class,
-                                    ClientLocalRuntime.CLIENT_SERVER_CHANNEL_KEY))
-                    .toProviderInstance(
-                            new InterceptingClientServerChannelProvider(serverInjector));
-        }
+        return ClientRuntime.builder()
+                .properties(clientCaseProperties.getRuntimeProperties())
+                .addModule(new Module() {
+                    public void configure(Binder binder) {
+                        // add an interceptor between client and server parts to capture and inspect the traffic
+                        binder.bind(Key.get(DataChannel.class, ClientRuntime.CLIENT_SERVER_CHANNEL_KEY))
+                                .toProviderInstance(new InterceptingClientServerChannelProvider(serverRuntimeProvider.get().getInjector()));
+                        // create local connection
+                        binder.bind(ClientConnection.class).toProviderInstance(new LocalConnectionProvider());
+                    }
+                })
+                .build();
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleProvider.java b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleProvider.java
deleted file mode 100644
index c65b4df..0000000
--- a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleProvider.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *    Licensed to the Apache Software Foundation (ASF) under one
- *    or more contributor license agreements.  See the NOTICE file
- *    distributed with this work for additional information
- *    regarding copyright ownership.  The ASF licenses this file
- *    to you under the Apache License, Version 2.0 (the
- *    "License"); you may not use this file except in compliance
- *    with the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing,
- *    software distributed under the License is distributed on an
- *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *    KIND, either express or implied.  See the License for the
- *    specific language governing permissions and limitations
- *    under the License.
- */
-package org.apache.cayenne.crypto;
-
-import org.apache.cayenne.di.Module;
-import org.apache.cayenne.di.spi.ModuleProvider;
-
-import java.util.Collection;
-import java.util.Collections;
-
-/**
- * @since 4.0
- */
-public class CryptoModuleProvider implements ModuleProvider {
-
-    @Override
-    public Module module() {
-        return new CryptoModule();
-    }
-
-    @Override
-    public Class<? extends Module> moduleType() {
-        return CryptoModule.class;
-    }
-
-    @Override
-    public Collection<Class<? extends Module>> overrides() {
-        // we don't override anything, we only decorate ServerModule services...
-        return Collections.emptyList();
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoServerModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoServerModuleProvider.java b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoServerModuleProvider.java
new file mode 100644
index 0000000..9fe8bc8
--- /dev/null
+++ b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoServerModuleProvider.java
@@ -0,0 +1,47 @@
+/*
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ */
+package org.apache.cayenne.crypto;
+
+import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
+import org.apache.cayenne.di.Module;
+
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * @since 4.0
+ */
+public class CryptoServerModuleProvider implements CayenneServerModuleProvider {
+
+    @Override
+    public Module module() {
+        return new CryptoModule();
+    }
+
+    @Override
+    public Class<? extends Module> moduleType() {
+        return CryptoModule.class;
+    }
+
+    @Override
+    public Collection<Class<? extends Module>> overrides() {
+        // we don't override anything, we only decorate ServerModule services...
+        return Collections.emptyList();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-crypto/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-crypto/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider b/cayenne-crypto/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
new file mode 100644
index 0000000..994f773
--- /dev/null
+++ b/cayenne-crypto/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
@@ -0,0 +1,20 @@
+##################################################################
+#   Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+##################################################################
+
+org.apache.cayenne.crypto.CryptoServerModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-crypto/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-crypto/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider b/cayenne-crypto/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider
deleted file mode 100644
index 7a649a3..0000000
--- a/cayenne-crypto/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider
+++ /dev/null
@@ -1,20 +0,0 @@
-##################################################################
-#   Licensed to the Apache Software Foundation (ASF) under one
-#  or more contributor license agreements.  See the NOTICE file
-#  distributed with this work for additional information
-#  regarding copyright ownership.  The ASF licenses this file
-#  to you under the Apache License, Version 2.0 (the
-#  "License"); you may not use this file except in compliance
-#  with the License.  You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing,
-#  software distributed under the License is distributed on an
-#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-#  KIND, either express or implied.  See the License for the
-#  specific language governing permissions and limitations
-#  under the License.
-##################################################################
-
-org.apache.cayenne.crypto.CryptoModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleProviderTest.java b/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleProviderTest.java
index 80db1fc..7121e5a 100644
--- a/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleProviderTest.java
+++ b/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleProviderTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.cayenne.crypto;
 
+import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
 import org.apache.cayenne.unit.util.ModuleProviderChecker;
 import org.junit.Test;
 
@@ -25,6 +26,6 @@ public class CryptoModuleProviderTest {
 
     @Test
     public void testProviderPresent() {
-        ModuleProviderChecker.testProviderPresent(CryptoModuleProvider.class);
+        ModuleProviderChecker.testProviderPresent(CryptoServerModuleProvider.class, CayenneServerModuleProvider.class);
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/DbSyncModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/DbSyncModuleProvider.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/DbSyncModuleProvider.java
deleted file mode 100644
index fb0cb8d..0000000
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/DbSyncModuleProvider.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *    Licensed to the Apache Software Foundation (ASF) under one
- *    or more contributor license agreements.  See the NOTICE file
- *    distributed with this work for additional information
- *    regarding copyright ownership.  The ASF licenses this file
- *    to you under the Apache License, Version 2.0 (the
- *    "License"); you may not use this file except in compliance
- *    with the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing,
- *    software distributed under the License is distributed on an
- *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *    KIND, either express or implied.  See the License for the
- *    specific language governing permissions and limitations
- *    under the License.
- */
-package org.apache.cayenne.dbsync;
-
-import org.apache.cayenne.di.Module;
-import org.apache.cayenne.di.spi.ModuleProvider;
-
-import java.util.Collection;
-import java.util.Collections;
-
-/**
- * Auto-loading provider for {@link DbSyncModule}.
- *
- * @since 4.0
- */
-public class DbSyncModuleProvider implements ModuleProvider {
-
-    @Override
-    public Module module() {
-        return new DbSyncModule();
-    }
-
-    @Override
-    public Class<? extends Module> moduleType() {
-        return DbSyncModule.class;
-    }
-
-    @Override
-    public Collection<Class<? extends Module>> overrides() {
-        return Collections.emptyList();
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/DbSyncServerModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/DbSyncServerModuleProvider.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/DbSyncServerModuleProvider.java
new file mode 100644
index 0000000..8111a03
--- /dev/null
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/DbSyncServerModuleProvider.java
@@ -0,0 +1,48 @@
+/*
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ */
+package org.apache.cayenne.dbsync;
+
+import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
+import org.apache.cayenne.di.Module;
+
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * Auto-loading provider for {@link DbSyncModule}.
+ *
+ * @since 4.0
+ */
+public class DbSyncServerModuleProvider implements CayenneServerModuleProvider {
+
+    @Override
+    public Module module() {
+        return new DbSyncModule();
+    }
+
+    @Override
+    public Class<? extends Module> moduleType() {
+        return DbSyncModule.class;
+    }
+
+    @Override
+    public Collection<Class<? extends Module>> overrides() {
+        return Collections.emptyList();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-dbsync/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider b/cayenne-dbsync/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
new file mode 100644
index 0000000..1f69f64
--- /dev/null
+++ b/cayenne-dbsync/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
@@ -0,0 +1,20 @@
+##################################################################
+#   Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+##################################################################
+
+org.apache.cayenne.dbsync.DbSyncServerModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-dbsync/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider b/cayenne-dbsync/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider
deleted file mode 100644
index 1dfd1a0..0000000
--- a/cayenne-dbsync/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider
+++ /dev/null
@@ -1,20 +0,0 @@
-##################################################################
-#   Licensed to the Apache Software Foundation (ASF) under one
-#  or more contributor license agreements.  See the NOTICE file
-#  distributed with this work for additional information
-#  regarding copyright ownership.  The ASF licenses this file
-#  to you under the Apache License, Version 2.0 (the
-#  "License"); you may not use this file except in compliance
-#  with the License.  You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing,
-#  software distributed under the License is distributed on an
-#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-#  KIND, either express or implied.  See the License for the
-#  specific language governing permissions and limitations
-#  under the License.
-##################################################################
-
-org.apache.cayenne.dbsync.DbSyncModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/DbSyncModuleProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/DbSyncModuleProviderTest.java b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/DbSyncModuleProviderTest.java
index bc7cd19..e11fced 100644
--- a/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/DbSyncModuleProviderTest.java
+++ b/cayenne-dbsync/src/test/java/org/apache/cayenne/dbsync/DbSyncModuleProviderTest.java
@@ -18,12 +18,13 @@
  */
 package org.apache.cayenne.dbsync;
 
+import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
 import org.apache.cayenne.unit.util.ModuleProviderChecker;
 import org.junit.Test;
 
 public class DbSyncModuleProviderTest {
     @Test
     public void testProviderPresent() {
-        ModuleProviderChecker.testProviderPresent(DbSyncModuleProvider.class);
+        ModuleProviderChecker.testProviderPresent(DbSyncServerModuleProvider.class, CayenneServerModuleProvider.class);
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ModuleLoader.java
----------------------------------------------------------------------
diff --git a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ModuleLoader.java b/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ModuleLoader.java
index 8ea771e..850fd8a 100644
--- a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ModuleLoader.java
+++ b/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ModuleLoader.java
@@ -31,27 +31,28 @@ import java.util.ServiceLoader;
 
 /**
  * Auto-loads DI modules using ServiceLoader. To make a module auto-loadable, you will need to ship the jar with a file
- * "META-INF/services/org.apache.cayenne.di.spi.ModuleProvider" that contains provider implementation for the module in
+ * "META-INF/services/&lt;full.provider.class.name&gt;" that contains provider implementation for the module in
  * question.
  *
+ * @see ModuleProvider
  * @since 4.0
  */
 public class ModuleLoader {
 
     /**
      * Auto-loads all modules declared on classpath. Modules are loaded from the SPI declarations stored in
-     * "META-INF/services/org.apache.cayenne.di.spi.ModuleProvider", and then sorted in the order of override dependency.
+     * "META-INF/services/&lt;full.provider.class.name&gt;", and then sorted in the order of override dependency.
      *
      * @return a sorted collection of auto-loadable modules.
      * @throws DIRuntimeException if auto-loaded modules have circular override dependencies.
      */
-    public List<Module> load() {
+    public List<Module> load(Class<? extends ModuleProvider> providerClass) {
 
         // map providers by class
 
         Map<Class<? extends Module>, ModuleProvider> providers = new HashMap<>();
 
-        for (ModuleProvider provider : ServiceLoader.load(ModuleProvider.class)) {
+        for (ModuleProvider provider : ServiceLoader.load(providerClass)) {
 
             ModuleProvider existing = providers.put(provider.moduleType(), provider);
             if (existing != null && !existing.getClass().equals(provider.getClass())) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ModuleProvider.java b/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ModuleProvider.java
index 679b593..d7e0e36 100644
--- a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ModuleProvider.java
+++ b/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ModuleProvider.java
@@ -23,7 +23,12 @@ import org.apache.cayenne.di.Module;
 import java.util.Collection;
 
 /**
+ * <p>
  * Provider of modules used by module auto-loading mechanism to identify and load modules.
+ * </p>
+ * <p>
+ * Multiple providers can be created by inheriting from this interface and using it with {@link ModuleLoader}
+ *</p>
  *
  * @since 4.0
  */

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-di/src/test/java/org/apache/cayenne/di/spi/CustomModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-di/src/test/java/org/apache/cayenne/di/spi/CustomModuleProvider.java b/cayenne-di/src/test/java/org/apache/cayenne/di/spi/CustomModuleProvider.java
new file mode 100644
index 0000000..cbf9cac
--- /dev/null
+++ b/cayenne-di/src/test/java/org/apache/cayenne/di/spi/CustomModuleProvider.java
@@ -0,0 +1,26 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.di.spi;
+
+/**
+ * @since 4.0
+ */
+public interface CustomModuleProvider extends ModuleProvider {
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-di/src/test/java/org/apache/cayenne/di/spi/ModuleLoaderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-di/src/test/java/org/apache/cayenne/di/spi/ModuleLoaderTest.java b/cayenne-di/src/test/java/org/apache/cayenne/di/spi/ModuleLoaderTest.java
index c86e8db..9d0cb87 100644
--- a/cayenne-di/src/test/java/org/apache/cayenne/di/spi/ModuleLoaderTest.java
+++ b/cayenne-di/src/test/java/org/apache/cayenne/di/spi/ModuleLoaderTest.java
@@ -36,7 +36,7 @@ public class ModuleLoaderTest {
     @Test
     public void testLoad() {
 
-        List<Module> modules = new ModuleLoader().load();
+        List<Module> modules = new ModuleLoader().load(ModuleProvider.class);
         assertEquals(4, modules.size());
         assertTrue(String.valueOf(modules.get(0)), modules.get(0) instanceof Module3);
         assertTrue(String.valueOf(modules.get(1)), modules.get(1) instanceof Module4);
@@ -48,6 +48,17 @@ public class ModuleLoaderTest {
         assertEquals(Integer.valueOf(56), i.getInstance(Integer.class));
     }
 
+    @Test
+    public void testLoadCustom() {
+        List<Module> modules = new ModuleLoader().load(CustomModuleProvider.class);
+        assertEquals(2, modules.size());
+        assertTrue(String.valueOf(modules.get(0)), modules.get(0) instanceof Module5);
+        assertTrue(String.valueOf(modules.get(1)), modules.get(1) instanceof Module6);
+
+        Injector i = DIBootstrap.createInjector(modules);
+        assertEquals(Integer.valueOf(66), i.getInstance(Integer.class));
+    }
+
     public static class Module1 implements Module {
 
         @Override
@@ -80,6 +91,20 @@ public class ModuleLoaderTest {
         }
     }
 
+    public static class Module5 implements Module {
+        @Override
+        public void configure(Binder binder) {
+            binder.bind(Integer.class).toInstance(56);
+        }
+    }
+
+    public static class Module6 implements Module {
+        @Override
+        public void configure(Binder binder) {
+            binder.bind(Integer.class).toInstance(66);
+        }
+    }
+
     public static class ModuleProvider1 implements ModuleProvider {
 
         @Override
@@ -158,4 +183,42 @@ public class ModuleLoaderTest {
             return c;
         }
     }
+
+    public static class ModuleProvider5 implements CustomModuleProvider {
+
+        @Override
+        public Module module() {
+            return new Module5();
+        }
+
+        @Override
+        public Class<? extends Module> moduleType() {
+            return Module5.class;
+        }
+
+        @Override
+        public Collection<Class<? extends Module>> overrides() {
+            return Collections.emptyList();
+        }
+    }
+
+    public static class ModuleProvider6 implements CustomModuleProvider {
+
+        @Override
+        public Module module() {
+            return new Module6();
+        }
+
+        @Override
+        public Class<? extends Module> moduleType() {
+            return Module6.class;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Collection<Class<? extends Module>> overrides() {
+            Collection c = Collections.singletonList(Module5.class);
+            return c;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-di/src/test/resources/META-INF/services/org.apache.cayenne.di.spi.CustomModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-di/src/test/resources/META-INF/services/org.apache.cayenne.di.spi.CustomModuleProvider b/cayenne-di/src/test/resources/META-INF/services/org.apache.cayenne.di.spi.CustomModuleProvider
new file mode 100644
index 0000000..a647316
--- /dev/null
+++ b/cayenne-di/src/test/resources/META-INF/services/org.apache.cayenne.di.spi.CustomModuleProvider
@@ -0,0 +1,21 @@
+##################################################################
+#   Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+##################################################################
+
+org.apache.cayenne.di.spi.ModuleLoaderTest$ModuleProvider5
+org.apache.cayenne.di.spi.ModuleLoaderTest$ModuleProvider6
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-java8/src/main/java/org/apache/cayenne/java8/Java8ModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-java8/src/main/java/org/apache/cayenne/java8/Java8ModuleProvider.java b/cayenne-java8/src/main/java/org/apache/cayenne/java8/Java8ModuleProvider.java
deleted file mode 100644
index f8fe1b6..0000000
--- a/cayenne-java8/src/main/java/org/apache/cayenne/java8/Java8ModuleProvider.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *    Licensed to the Apache Software Foundation (ASF) under one
- *    or more contributor license agreements.  See the NOTICE file
- *    distributed with this work for additional information
- *    regarding copyright ownership.  The ASF licenses this file
- *    to you under the Apache License, Version 2.0 (the
- *    "License"); you may not use this file except in compliance
- *    with the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing,
- *    software distributed under the License is distributed on an
- *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *    KIND, either express or implied.  See the License for the
- *    specific language governing permissions and limitations
- *    under the License.
- */
-package org.apache.cayenne.java8;
-
-import org.apache.cayenne.di.Module;
-import org.apache.cayenne.di.spi.ModuleProvider;
-
-import java.util.Collection;
-import java.util.Collections;
-
-/**
- * @since 4.0
- */
-public class Java8ModuleProvider implements ModuleProvider {
-
-    @Override
-    public Module module() {
-        return new Java8Module();
-    }
-
-    @Override
-    public Class<? extends Module> moduleType() {
-        return Java8Module.class;
-    }
-
-    @Override
-    public Collection<Class<? extends Module>> overrides() {
-        return Collections.emptyList();
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-java8/src/main/java/org/apache/cayenne/java8/Java8ServerModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-java8/src/main/java/org/apache/cayenne/java8/Java8ServerModuleProvider.java b/cayenne-java8/src/main/java/org/apache/cayenne/java8/Java8ServerModuleProvider.java
new file mode 100644
index 0000000..5351a36
--- /dev/null
+++ b/cayenne-java8/src/main/java/org/apache/cayenne/java8/Java8ServerModuleProvider.java
@@ -0,0 +1,46 @@
+/*
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ */
+package org.apache.cayenne.java8;
+
+import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
+import org.apache.cayenne.di.Module;
+
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * @since 4.0
+ */
+public class Java8ServerModuleProvider implements CayenneServerModuleProvider {
+
+    @Override
+    public Module module() {
+        return new Java8Module();
+    }
+
+    @Override
+    public Class<? extends Module> moduleType() {
+        return Java8Module.class;
+    }
+
+    @Override
+    public Collection<Class<? extends Module>> overrides() {
+        return Collections.emptyList();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-java8/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-java8/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider b/cayenne-java8/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
new file mode 100644
index 0000000..68a42dc
--- /dev/null
+++ b/cayenne-java8/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider
@@ -0,0 +1,20 @@
+##################################################################
+#   Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+##################################################################
+
+org.apache.cayenne.java8.Java8ServerModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-java8/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-java8/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider b/cayenne-java8/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider
deleted file mode 100644
index 143cc5d..0000000
--- a/cayenne-java8/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider
+++ /dev/null
@@ -1,20 +0,0 @@
-##################################################################
-#   Licensed to the Apache Software Foundation (ASF) under one
-#  or more contributor license agreements.  See the NOTICE file
-#  distributed with this work for additional information
-#  regarding copyright ownership.  The ASF licenses this file
-#  to you under the Apache License, Version 2.0 (the
-#  "License"); you may not use this file except in compliance
-#  with the License.  You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing,
-#  software distributed under the License is distributed on an
-#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-#  KIND, either express or implied.  See the License for the
-#  specific language governing permissions and limitations
-#  under the License.
-##################################################################
-
-org.apache.cayenne.java8.Java8ModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/6888884a/cayenne-java8/src/test/java/org/apache/cayenne/java8/Java8ModuleProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-java8/src/test/java/org/apache/cayenne/java8/Java8ModuleProviderTest.java b/cayenne-java8/src/test/java/org/apache/cayenne/java8/Java8ModuleProviderTest.java
index 4c4df57..a080230 100644
--- a/cayenne-java8/src/test/java/org/apache/cayenne/java8/Java8ModuleProviderTest.java
+++ b/cayenne-java8/src/test/java/org/apache/cayenne/java8/Java8ModuleProviderTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.cayenne.java8;
 
+import org.apache.cayenne.configuration.server.CayenneServerModuleProvider;
 import org.apache.cayenne.unit.util.ModuleProviderChecker;
 import org.junit.Test;
 
@@ -25,6 +26,6 @@ public class Java8ModuleProviderTest {
 
     @Test
     public void testProviderPresent() {
-        ModuleProviderChecker.testProviderPresent(Java8ModuleProvider.class);
+        ModuleProviderChecker.testProviderPresent(Java8ServerModuleProvider.class, CayenneServerModuleProvider.class);
     }
 }


Mime
View raw message