├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── README.md ├── examples ├── pom.xml ├── vertx-guice-config │ ├── README.md │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── englishtown │ │ │ └── vertx │ │ │ └── guice │ │ │ └── examples │ │ │ ├── ConfigBinder.java │ │ │ ├── ConfigDependency.java │ │ │ └── ConfigVerticle.java │ │ └── test │ │ └── java │ │ └── com │ │ └── englishtown │ │ └── vertx │ │ └── guice │ │ └── examples │ │ └── integration │ │ └── ConfigVerticleTest.java └── vertx-guice-simple │ ├── pom.xml │ └── src │ ├── main │ └── java │ │ └── com │ │ └── englishtown │ │ └── vertx │ │ └── guice │ │ └── examples │ │ ├── Binder.java │ │ ├── MyDependency.java │ │ ├── SimpleVerticle.java │ │ └── impl │ │ └── MyDependencyImpl.java │ └── test │ └── java │ └── com │ └── englishtown │ └── vertx │ └── guice │ └── examples │ └── integration │ └── SimpleVerticleTest.java ├── pom.xml └── vertx-guice ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── englishtown │ │ └── vertx │ │ └── guice │ │ ├── GuiceVerticleFactory.java │ │ ├── GuiceVerticleLoader.java │ │ └── GuiceVertxBinder.java └── resources │ └── META-INF │ └── services │ └── io.vertx.core.spi.VerticleFactory └── test ├── java └── com │ └── englishtown │ └── vertx │ └── guice │ ├── BootstrapBinder.java │ ├── DefaultMyDependency.java │ ├── DefaultMyDependency2.java │ ├── GuiceVerticleFactoryTest.java │ ├── GuiceVerticleLoaderTest.java │ ├── MockLogDelegateFactory.java │ ├── MyDependency.java │ ├── MyDependency2.java │ ├── TestGuiceVerticle.java │ └── integration │ ├── CustomBinder.java │ ├── DependencyInjectionVerticle.java │ ├── DependencyInjectionVerticle2.java │ ├── DummyVerticle.java │ ├── IntegrationTestVerticle.java │ └── NOPBinder.java └── resources └── UncompiledDIVerticle.java /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.iml 3 | *.ipr 4 | *.iws 5 | .classpath 6 | .project 7 | .settings/ 8 | 9 | .gradle/ 10 | build/ 11 | target/ 12 | 13 | mods/ 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright © 2016 Englishtown 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the “Software”), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vert.x Guice Extensions 2 | Enable Verticle dependency injection using Guice. Deploy your verticle with the `java-guice:` prefix to use the `GuiceVerticleFactory`. 3 | 4 | [![Build Status](http://img.shields.io/travis/ef-labs/vertx-guice.svg?maxAge=2592000&style=flat-square)](https://travis-ci.org/ef-labs/vertx-guice) 5 | [![Maven Central](https://img.shields.io/maven-central/v/com.englishtown.vertx/vertx-guice.svg?maxAge=2592000&style=flat-square)](https://maven-badges.herokuapp.com/maven-central/com.englishtown.vertx/vertx-guice/) 6 | 7 | ## License 8 | http://englishtown.mit-license.org/ 9 | 10 | 11 | ## Configuration 12 | 13 | Either provide a com.englishtown.vertx.guice.BootstrapBinder that implements com.google.inject.Module, or via vert.x config, provide a custom class name. 14 | 15 | ```json 16 | { 17 | "guice_binder": "my.custom.bootstrap.Binder" 18 | } 19 | ``` 20 | 21 | ## Example 22 | 23 | ```java 24 | package com.englishtown.vertx.guice; 25 | 26 | import com.englishtown.configuration.ConfigValueManager; 27 | import com.englishtown.configuration.OtherBinder1; 28 | import com.englishtown.configuration.OtherBinder2; 29 | import com.englishtown.configuration.impl.PropertiesConfigValueManager; 30 | import com.google.inject.AbstractModule; 31 | 32 | import javax.inject.Singleton; 33 | 34 | public class BootstrapBinder extends AbstractModule { 35 | 36 | @Override 37 | protected void configure() { 38 | 39 | // Configure bindings 40 | bind(ConfigValueManager.class).to(PropertiesConfigValueManager.class).in(Singleton.class); 41 | 42 | // Install other binders 43 | install(new OtherBinder1(), new OtherBinder2()); 44 | 45 | } 46 | 47 | } 48 | ``` 49 | -------------------------------------------------------------------------------- /examples/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | vertx-guice-examples 5 | pom 6 | 7 | 8 | vertx-guice-parent 9 | com.englishtown.vertx 10 | 2.4.0-SNAPSHOT 11 | 12 | 4.0.0 13 | 14 | 15 | vertx-guice-simple 16 | vertx-guice-config 17 | 18 | 19 | 20 | 21 | com.englishtown.vertx 22 | vertx-guice 23 | ${project.version} 24 | 25 | 26 | io.vertx 27 | vertx-core 28 | ${vertx.version} 29 | test-jar 30 | test 31 | 32 | 33 | 34 | 35 | 36 | 37 | maven-deploy-plugin 38 | 39 | true 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /examples/vertx-guice-config/README.md: -------------------------------------------------------------------------------- 1 | # vertx-guice-config 2 | 3 | An example using Named annotations to inject configuration. 4 | 5 | Inspired by @hiddenbyte in issue #8 6 | 7 | -------------------------------------------------------------------------------- /examples/vertx-guice-config/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | vertx-guice-config 6 | 7 | 8 | vertx-guice-examples 9 | com.englishtown.vertx 10 | 2.4.0-SNAPSHOT 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/vertx-guice-config/src/main/java/com/englishtown/vertx/guice/examples/ConfigBinder.java: -------------------------------------------------------------------------------- 1 | package com.englishtown.vertx.guice.examples; 2 | 3 | import com.google.inject.AbstractModule; 4 | import com.google.inject.name.Names; 5 | import io.vertx.core.Vertx; 6 | import io.vertx.core.json.JsonObject; 7 | 8 | /** 9 | * Guice config module 10 | */ 11 | public class ConfigBinder extends AbstractModule { 12 | 13 | public static final String GUICE_CONFIG = "guice_config"; 14 | public static final String ROOT_PATH = "config"; 15 | 16 | @Override 17 | protected void configure() { 18 | 19 | JsonObject config = Vertx.currentContext().config().getJsonObject(GUICE_CONFIG); 20 | if (config != null) { 21 | bindConfig(config, ROOT_PATH); 22 | } 23 | 24 | } 25 | 26 | private void bindConfig(JsonObject config, String path) { 27 | bind(JsonObject.class).annotatedWith(Names.named(path)).toInstance(config); 28 | 29 | config 30 | .stream() 31 | .filter(entry -> entry.getValue() instanceof JsonObject) 32 | .forEach(entry -> bindConfig((JsonObject) entry.getValue(), String.format("%s.%s", path, entry.getKey()))); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/vertx-guice-config/src/main/java/com/englishtown/vertx/guice/examples/ConfigDependency.java: -------------------------------------------------------------------------------- 1 | package com.englishtown.vertx.guice.examples; 2 | 3 | import io.vertx.core.json.JsonObject; 4 | 5 | import javax.inject.Inject; 6 | import javax.inject.Named; 7 | 8 | /** 9 | * Dependency using named annotations to inject config 10 | */ 11 | public class ConfigDependency { 12 | 13 | private JsonObject config; 14 | 15 | @Inject 16 | public ConfigDependency(@Named("config.api") JsonObject config) { 17 | this.config = config; 18 | } 19 | 20 | public JsonObject getConfig() { 21 | return config; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/vertx-guice-config/src/main/java/com/englishtown/vertx/guice/examples/ConfigVerticle.java: -------------------------------------------------------------------------------- 1 | package com.englishtown.vertx.guice.examples; 2 | 3 | import io.vertx.core.AbstractVerticle; 4 | import io.vertx.core.Handler; 5 | import io.vertx.core.eventbus.Message; 6 | 7 | import javax.inject.Inject; 8 | 9 | /** 10 | * Simple Guice Verticle 11 | */ 12 | public class ConfigVerticle extends AbstractVerticle implements Handler> { 13 | 14 | private final ConfigDependency dependency; 15 | 16 | public static final String EB_ADDRESS = "et.address"; 17 | 18 | /** 19 | * DI constructor 20 | * 21 | * @param dependency 22 | */ 23 | @Inject 24 | public ConfigVerticle(ConfigDependency dependency) { 25 | this.dependency = dependency; 26 | } 27 | 28 | /** 29 | * If your verticle does a simple, synchronous start-up then override this method and put your start-up 30 | * code in there. 31 | * 32 | * @throws Exception 33 | */ 34 | @Override 35 | public void start() throws Exception { 36 | 37 | if (dependency == null) { 38 | throw new IllegalStateException("Dependency was not injected!"); 39 | } 40 | 41 | vertx.eventBus().consumer(EB_ADDRESS, this); 42 | 43 | super.start(); 44 | } 45 | 46 | /** 47 | * Something has happened, so handle it. 48 | * 49 | * @param msg the event to handle 50 | */ 51 | @Override 52 | public void handle(Message msg) { 53 | msg.reply(dependency.getConfig()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /examples/vertx-guice-config/src/test/java/com/englishtown/vertx/guice/examples/integration/ConfigVerticleTest.java: -------------------------------------------------------------------------------- 1 | package com.englishtown.vertx.guice.examples.integration; 2 | 3 | import com.englishtown.vertx.guice.examples.ConfigBinder; 4 | import com.englishtown.vertx.guice.examples.ConfigVerticle; 5 | import io.vertx.core.DeploymentOptions; 6 | import io.vertx.core.json.JsonObject; 7 | import io.vertx.test.core.VertxTestBase; 8 | import org.junit.Test; 9 | 10 | import java.util.concurrent.CompletableFuture; 11 | import java.util.concurrent.TimeUnit; 12 | 13 | /** 14 | * Integration test for {@link ConfigVerticle} 15 | */ 16 | public class ConfigVerticleTest extends VertxTestBase { 17 | 18 | private JsonObject apiConfig; 19 | 20 | @Override 21 | public void setUp() throws Exception { 22 | super.setUp(); 23 | 24 | CompletableFuture future = new CompletableFuture<>(); 25 | apiConfig = new JsonObject() 26 | .put("a", "b") 27 | .put("b", 123) 28 | .put("c", true); 29 | 30 | JsonObject config = new JsonObject() 31 | .put("guice_binder", ConfigBinder.class.getName()) 32 | .put(ConfigBinder.GUICE_CONFIG, new JsonObject() 33 | .put("api", apiConfig)); 34 | 35 | vertx.deployVerticle("java-guice:" + ConfigVerticle.class.getName(), new DeploymentOptions().setConfig(config), result -> { 36 | if (result.succeeded()) { 37 | future.complete(null); 38 | } else { 39 | future.completeExceptionally(result.cause()); 40 | } 41 | }); 42 | 43 | future.get(200, TimeUnit.SECONDS); 44 | 45 | } 46 | 47 | @Test 48 | public void testHandle() throws Exception { 49 | 50 | vertx.eventBus().send(ConfigVerticle.EB_ADDRESS, null, result -> { 51 | 52 | if (result.failed()) { 53 | result.cause().printStackTrace(); 54 | fail(); 55 | return; 56 | } 57 | 58 | assertEquals(apiConfig, result.result().body()); 59 | testComplete(); 60 | 61 | }); 62 | 63 | await(); 64 | } 65 | } -------------------------------------------------------------------------------- /examples/vertx-guice-simple/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | vertx-guice-examples 5 | com.englishtown.vertx 6 | 2.4.0-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | vertx-guice-simple 11 | 12 | -------------------------------------------------------------------------------- /examples/vertx-guice-simple/src/main/java/com/englishtown/vertx/guice/examples/Binder.java: -------------------------------------------------------------------------------- 1 | package com.englishtown.vertx.guice.examples; 2 | 3 | import com.englishtown.vertx.guice.examples.impl.MyDependencyImpl; 4 | import com.google.inject.AbstractModule; 5 | 6 | import javax.inject.Singleton; 7 | 8 | /** 9 | * Guice module 10 | */ 11 | public class Binder extends AbstractModule { 12 | /** 13 | * Configures a {@link Binder} via the exposed methods. 14 | */ 15 | @Override 16 | protected void configure() { 17 | bind(MyDependency.class).to(MyDependencyImpl.class).in(Singleton.class); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/vertx-guice-simple/src/main/java/com/englishtown/vertx/guice/examples/MyDependency.java: -------------------------------------------------------------------------------- 1 | package com.englishtown.vertx.guice.examples; 2 | 3 | /** 4 | * An injectable dependency 5 | */ 6 | public interface MyDependency { 7 | } 8 | -------------------------------------------------------------------------------- /examples/vertx-guice-simple/src/main/java/com/englishtown/vertx/guice/examples/SimpleVerticle.java: -------------------------------------------------------------------------------- 1 | package com.englishtown.vertx.guice.examples; 2 | 3 | import io.vertx.core.AbstractVerticle; 4 | import io.vertx.core.Handler; 5 | import io.vertx.core.eventbus.Message; 6 | 7 | import javax.inject.Inject; 8 | 9 | /** 10 | * Simple Guice Verticle 11 | */ 12 | public class SimpleVerticle extends AbstractVerticle implements Handler> { 13 | 14 | private final MyDependency dependency; 15 | 16 | public static final String EB_ADDRESS = "et.address"; 17 | 18 | /** 19 | * DI constructor 20 | * 21 | * @param dependency 22 | */ 23 | @Inject 24 | public SimpleVerticle(MyDependency dependency) { 25 | this.dependency = dependency; 26 | } 27 | 28 | /** 29 | * If your verticle does a simple, synchronous start-up then override this method and put your start-up 30 | * code in there. 31 | * 32 | * @throws Exception 33 | */ 34 | @Override 35 | public void start() throws Exception { 36 | 37 | if (dependency == null) { 38 | throw new IllegalStateException("Dependency was not injected!"); 39 | } 40 | 41 | vertx.eventBus().consumer(EB_ADDRESS, this); 42 | 43 | super.start(); 44 | } 45 | 46 | /** 47 | * Something has happened, so handle it. 48 | * 49 | * @param msg the event to handle 50 | */ 51 | @Override 52 | public void handle(Message msg) { 53 | msg.reply(dependency.getClass().getName()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /examples/vertx-guice-simple/src/main/java/com/englishtown/vertx/guice/examples/impl/MyDependencyImpl.java: -------------------------------------------------------------------------------- 1 | package com.englishtown.vertx.guice.examples.impl; 2 | 3 | import com.englishtown.vertx.guice.examples.MyDependency; 4 | 5 | /** 6 | * Default implementation of {@link MyDependency} 7 | */ 8 | public class MyDependencyImpl implements MyDependency { 9 | } 10 | -------------------------------------------------------------------------------- /examples/vertx-guice-simple/src/test/java/com/englishtown/vertx/guice/examples/integration/SimpleVerticleTest.java: -------------------------------------------------------------------------------- 1 | package com.englishtown.vertx.guice.examples.integration; 2 | 3 | import com.englishtown.vertx.guice.examples.Binder; 4 | import com.englishtown.vertx.guice.examples.SimpleVerticle; 5 | import com.englishtown.vertx.guice.examples.impl.MyDependencyImpl; 6 | import io.vertx.core.DeploymentOptions; 7 | import io.vertx.core.json.JsonObject; 8 | import io.vertx.test.core.VertxTestBase; 9 | import org.junit.Test; 10 | 11 | import java.util.concurrent.CompletableFuture; 12 | import java.util.concurrent.TimeUnit; 13 | 14 | /** 15 | * Integration test for {@link SimpleVerticle} 16 | */ 17 | public class SimpleVerticleTest extends VertxTestBase { 18 | 19 | @Override 20 | public void setUp() throws Exception { 21 | super.setUp(); 22 | 23 | CompletableFuture future = new CompletableFuture<>(); 24 | 25 | JsonObject config = new JsonObject().put("guice_binder", Binder.class.getName()); 26 | 27 | vertx.deployVerticle("java-guice:" + SimpleVerticle.class.getName(), new DeploymentOptions().setConfig(config), result -> { 28 | if (result.succeeded()) { 29 | future.complete(null); 30 | } else { 31 | future.completeExceptionally(result.cause()); 32 | } 33 | }); 34 | 35 | future.get(2, TimeUnit.SECONDS); 36 | 37 | } 38 | 39 | @Test 40 | public void testHandle() throws Exception { 41 | 42 | vertx.eventBus().send(SimpleVerticle.EB_ADDRESS, null, result -> { 43 | 44 | if (result.failed()) { 45 | result.cause().printStackTrace(); 46 | fail(); 47 | return; 48 | } 49 | 50 | assertEquals(MyDependencyImpl.class.getName(), result.result().body()); 51 | testComplete(); 52 | 53 | }); 54 | 55 | await(); 56 | } 57 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | vertx-guice-parent 6 | pom 7 | 2.4.0-SNAPSHOT 8 | 9 | 10 | com.englishtown.vertx 11 | oss-parent-vertx 12 | 2.2.0 13 | 14 | 15 | 16 | vertx-guice 17 | examples 18 | 19 | 20 | 21 | 22 | 4.1.0 23 | 3.3.0 24 | 25 | 26 | 27 | 28 | 29 | org.mockito 30 | mockito-core 31 | test 32 | 33 | 34 | 35 | 36 | 37 | 38 | com.google.inject 39 | guice 40 | ${guice.version} 41 | 42 | 43 | 44 | 45 | Provides a VerticleFactory that uses Guice for dependency injection. 46 | 2013 47 | 48 | 49 | 50 | sling.englishtown.com 51 | dav:https://sling.englishtown.com/content/docs/${project.groupId}/${project.artifactId}/${project.version} 52 | 53 | 54 | 55 | 56 | scm:git:ssh://git@github.com/englishtown/${project.artifactId}.git 57 | scm:git:ssh://git@github.com/englishtown/${project.artifactId}.git 58 | HEAD 59 | https://github.com/englishtown/${project.artifactId} 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /vertx-guice/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 4.0.0 6 | vertx-guice 7 | 8 | 9 | vertx-guice-parent 10 | com.englishtown.vertx 11 | 2.4.0-SNAPSHOT 12 | 13 | 14 | 15 | 16 | com.google.inject 17 | guice 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /vertx-guice/src/main/java/com/englishtown/vertx/guice/GuiceVerticleFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * Copyright © 2016 Englishtown 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the “Software”), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | */ 23 | 24 | package com.englishtown.vertx.guice; 25 | 26 | import com.google.inject.Injector; 27 | import io.vertx.core.Verticle; 28 | import io.vertx.core.impl.JavaVerticleFactory; 29 | import io.vertx.core.spi.VerticleFactory; 30 | 31 | import java.lang.reflect.Constructor; 32 | 33 | /** 34 | * Extends the default vert.x {@link JavaVerticleFactory} using Guice for dependency injection. 35 | */ 36 | public class GuiceVerticleFactory implements VerticleFactory { 37 | 38 | public static final String PREFIX = "java-guice"; 39 | 40 | private Injector injector; 41 | 42 | /** 43 | * Returns the current parent injector 44 | * 45 | * @return 46 | */ 47 | public Injector getInjector() { 48 | if (injector == null) { 49 | injector = createInjector(); 50 | } 51 | return injector; 52 | } 53 | 54 | /** 55 | * Sets the parent injector 56 | * 57 | * @param injector 58 | * @return 59 | */ 60 | public GuiceVerticleFactory setInjector(Injector injector) { 61 | this.injector = injector; 62 | return this; 63 | } 64 | 65 | @Override 66 | public String prefix() { 67 | return PREFIX; 68 | } 69 | 70 | /** 71 | * {@inheritDoc} 72 | */ 73 | @Override 74 | public Verticle createVerticle(String verticleName, ClassLoader classLoader) throws Exception { 75 | verticleName = VerticleFactory.removePrefix(verticleName); 76 | 77 | // Use the provided class loader to create an instance of GuiceVerticleLoader. This is necessary when working with vert.x IsolatingClassLoader 78 | @SuppressWarnings("unchecked") 79 | Class loader = (Class) classLoader.loadClass(GuiceVerticleLoader.class.getName()); 80 | Constructor ctor = loader.getConstructor(String.class, ClassLoader.class, Injector.class); 81 | 82 | if (ctor == null) { 83 | throw new IllegalStateException("Could not find GuiceVerticleLoader constructor"); 84 | } 85 | 86 | return ctor.newInstance(verticleName, classLoader, getInjector()); 87 | } 88 | 89 | protected Injector createInjector() { 90 | return null; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /vertx-guice/src/main/java/com/englishtown/vertx/guice/GuiceVerticleLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * Copyright © 2016 Englishtown 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the “Software”), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | */ 23 | 24 | package com.englishtown.vertx.guice; 25 | 26 | import com.google.inject.Guice; 27 | import com.google.inject.Injector; 28 | import com.google.inject.Key; 29 | import com.google.inject.Module; 30 | import io.vertx.core.*; 31 | import io.vertx.core.impl.verticle.CompilingClassLoader; 32 | import io.vertx.core.json.JsonArray; 33 | import io.vertx.core.json.JsonObject; 34 | import io.vertx.core.logging.Logger; 35 | import io.vertx.core.logging.LoggerFactory; 36 | 37 | import java.util.ArrayList; 38 | import java.util.List; 39 | 40 | /** 41 | * Guice Verticle to lazy load the real verticle with DI 42 | */ 43 | public class GuiceVerticleLoader extends AbstractVerticle { 44 | 45 | private Logger logger = LoggerFactory.getLogger(GuiceVerticleLoader.class); 46 | 47 | private final String verticleName; 48 | private final ClassLoader classLoader; 49 | private final Injector parent; 50 | private Verticle realVerticle; 51 | 52 | public static final String CONFIG_BOOTSTRAP_BINDER_NAME = "guice_binder"; 53 | public static final String BOOTSTRAP_BINDER_NAME = "com.englishtown.vertx.guice.BootstrapBinder"; 54 | 55 | public GuiceVerticleLoader(String verticleName, ClassLoader classLoader, Injector parent) { 56 | this.verticleName = verticleName; 57 | this.classLoader = classLoader; 58 | this.parent = parent; 59 | } 60 | 61 | /** 62 | * Initialise the verticle.

63 | * This is called by Vert.x when the verticle instance is deployed. Don't call it yourself. 64 | * 65 | * @param vertx the deploying Vert.x instance 66 | * @param context the context of the verticle 67 | */ 68 | @Override 69 | public void init(Vertx vertx, Context context) { 70 | super.init(vertx, context); 71 | 72 | try { 73 | // Create the real verticle and init 74 | realVerticle = createRealVerticle(); 75 | realVerticle.init(vertx, context); 76 | 77 | } catch (Throwable t) { 78 | if (t instanceof RuntimeException) { 79 | throw (RuntimeException) t; 80 | } 81 | throw new RuntimeException(t); 82 | } 83 | } 84 | 85 | /** 86 | * Override this method to signify that start is complete sometime _after_ the start() method has returned 87 | * This is useful if your verticle deploys other verticles or modules and you don't want this verticle to 88 | * be considered started until the other modules and verticles have been started. 89 | * 90 | * @param startedResult When you are happy your verticle is started set the result 91 | * @throws Exception 92 | */ 93 | @Override 94 | public void start(Future startedResult) throws Exception { 95 | // Start the real verticle 96 | realVerticle.start(startedResult); 97 | } 98 | 99 | /** 100 | * Vert.x calls the stop method when the verticle is undeployed. 101 | * Put any cleanup code for your verticle in here 102 | * 103 | * @throws Exception 104 | */ 105 | @Override 106 | public void stop(Future stopFuture) throws Exception { 107 | // Stop the real verticle 108 | if (realVerticle != null) { 109 | realVerticle.stop(stopFuture); 110 | realVerticle = null; 111 | } 112 | } 113 | 114 | public String getVerticleName() { 115 | return verticleName; 116 | } 117 | 118 | public Verticle createRealVerticle() throws Exception { 119 | String className = verticleName; 120 | Class clazz; 121 | 122 | if (className.endsWith(".java")) { 123 | CompilingClassLoader compilingLoader = new CompilingClassLoader(classLoader, className); 124 | className = compilingLoader.resolveMainClassName(); 125 | clazz = compilingLoader.loadClass(className); 126 | } else { 127 | clazz = classLoader.loadClass(className); 128 | } 129 | Verticle verticle = createRealVerticle(clazz); 130 | return verticle; 131 | } 132 | 133 | private Verticle createRealVerticle(Class clazz) throws Exception { 134 | 135 | JsonObject config = config(); 136 | Object field = config.getValue(CONFIG_BOOTSTRAP_BINDER_NAME); 137 | JsonArray bootstrapNames; 138 | List bootstraps = new ArrayList<>(); 139 | 140 | if (field instanceof JsonArray) { 141 | bootstrapNames = (JsonArray) field; 142 | } else { 143 | bootstrapNames = new JsonArray().add((field == null ? BOOTSTRAP_BINDER_NAME : field)); 144 | } 145 | 146 | for (int i = 0; i < bootstrapNames.size(); i++) { 147 | String bootstrapName = bootstrapNames.getString(i); 148 | try { 149 | Class bootstrapClass = classLoader.loadClass(bootstrapName); 150 | Object obj = bootstrapClass.newInstance(); 151 | 152 | if (obj instanceof Module) { 153 | bootstraps.add((Module) obj); 154 | } else { 155 | logger.error("Class " + bootstrapName 156 | + " does not implement Module."); 157 | } 158 | } catch (ClassNotFoundException e) { 159 | if (parent == null) { 160 | logger.warn("Guice bootstrap binder class " + bootstrapName 161 | + " was not found. Are you missing injection bindings?"); 162 | } 163 | } 164 | } 165 | 166 | // Add vert.x binder if not already bound 167 | if (parent == null || parent.getExistingBinding(Key.get(Vertx.class)) == null) { 168 | bootstraps.add(new GuiceVertxBinder(vertx)); 169 | } 170 | 171 | // Each verticle factory will have it's own (child) injector instance 172 | Injector injector = parent == null ? Guice.createInjector(bootstraps) : parent.createChildInjector(bootstraps); 173 | return (Verticle) injector.getInstance(clazz); 174 | } 175 | 176 | } 177 | -------------------------------------------------------------------------------- /vertx-guice/src/main/java/com/englishtown/vertx/guice/GuiceVertxBinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * Copyright © 2016 Englishtown 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the “Software”), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | */ 23 | 24 | package com.englishtown.vertx.guice; 25 | 26 | import com.google.inject.AbstractModule; 27 | import io.vertx.core.Vertx; 28 | 29 | /** 30 | * Guice {@link AbstractModule} for vertx and container injections 31 | */ 32 | public class GuiceVertxBinder extends AbstractModule { 33 | 34 | private final Vertx vertx; 35 | 36 | public GuiceVertxBinder(Vertx vertx) { 37 | this.vertx = vertx; 38 | } 39 | 40 | /** 41 | * {@inheritDoc} 42 | */ 43 | @Override 44 | protected void configure() { 45 | bind(Vertx.class).toInstance(vertx); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /vertx-guice/src/main/resources/META-INF/services/io.vertx.core.spi.VerticleFactory: -------------------------------------------------------------------------------- 1 | com.englishtown.vertx.guice.GuiceVerticleFactory -------------------------------------------------------------------------------- /vertx-guice/src/test/java/com/englishtown/vertx/guice/BootstrapBinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * Copyright © 2016 Englishtown 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the “Software”), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | */ 23 | 24 | package com.englishtown.vertx.guice; 25 | 26 | import com.google.inject.AbstractModule; 27 | 28 | /** 29 | * BootstrapBinder implementation 30 | */ 31 | public class BootstrapBinder extends AbstractModule { 32 | /** 33 | * Implement to provide binding definitions using the exposed binding 34 | * methods. 35 | */ 36 | @Override 37 | protected void configure() { 38 | bind(MyDependency.class).to(DefaultMyDependency.class); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /vertx-guice/src/test/java/com/englishtown/vertx/guice/DefaultMyDependency.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * Copyright © 2016 Englishtown 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the “Software”), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | */ 23 | 24 | package com.englishtown.vertx.guice; 25 | 26 | import io.vertx.core.Vertx; 27 | 28 | import javax.inject.Inject; 29 | 30 | public class DefaultMyDependency implements MyDependency { 31 | 32 | @SuppressWarnings("unused") 33 | private final Vertx vertx; 34 | 35 | @Inject 36 | public DefaultMyDependency(Vertx vertx) { 37 | this.vertx = vertx; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /vertx-guice/src/test/java/com/englishtown/vertx/guice/DefaultMyDependency2.java: -------------------------------------------------------------------------------- 1 | package com.englishtown.vertx.guice; 2 | 3 | public class DefaultMyDependency2 implements MyDependency2 { 4 | } 5 | -------------------------------------------------------------------------------- /vertx-guice/src/test/java/com/englishtown/vertx/guice/GuiceVerticleFactoryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * Copyright © 2016 Englishtown 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the “Software”), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | */ 23 | 24 | package com.englishtown.vertx.guice; 25 | 26 | import com.google.inject.Injector; 27 | import io.vertx.core.Context; 28 | import io.vertx.core.Verticle; 29 | import io.vertx.core.Vertx; 30 | import io.vertx.core.json.JsonObject; 31 | import org.junit.Before; 32 | import org.junit.Test; 33 | import org.junit.runner.RunWith; 34 | import org.mockito.Mock; 35 | import org.mockito.runners.MockitoJUnitRunner; 36 | 37 | import static org.hamcrest.CoreMatchers.instanceOf; 38 | import static org.junit.Assert.*; 39 | import static org.mockito.Mockito.mock; 40 | import static org.mockito.Mockito.when; 41 | 42 | /** 43 | * Unit tests for {@link GuiceVerticleFactory} 44 | */ 45 | @RunWith(MockitoJUnitRunner.class) 46 | public class GuiceVerticleFactoryTest { 47 | 48 | private GuiceVerticleFactory factory; 49 | 50 | @Before 51 | public void setUp() throws Exception { 52 | factory = new GuiceVerticleFactory(); 53 | } 54 | 55 | @Test 56 | public void testPrefix() { 57 | assertEquals("java-guice", factory.prefix()); 58 | } 59 | 60 | @Test 61 | public void testCreateVerticle() throws Exception { 62 | String identifier = GuiceVerticleFactory.PREFIX + ":" + TestGuiceVerticle.class.getName(); 63 | Verticle verticle = factory.createVerticle(identifier, this.getClass().getClassLoader()); 64 | assertThat(verticle, instanceOf(GuiceVerticleLoader.class)); 65 | 66 | GuiceVerticleLoader loader = (GuiceVerticleLoader) verticle; 67 | assertEquals(TestGuiceVerticle.class.getName(), loader.getVerticleName()); 68 | } 69 | 70 | @Test 71 | public void testSetInjector() throws Exception { 72 | 73 | assertNull(factory.getInjector()); 74 | 75 | Injector injector = mock(Injector.class); 76 | factory.setInjector(injector); 77 | 78 | assertEquals(injector, factory.getInjector()); 79 | 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /vertx-guice/src/test/java/com/englishtown/vertx/guice/GuiceVerticleLoaderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * Copyright © 2016 Englishtown 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the “Software”), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | */ 23 | 24 | package com.englishtown.vertx.guice; 25 | 26 | import com.englishtown.vertx.guice.integration.CustomBinder; 27 | import com.englishtown.vertx.guice.integration.DependencyInjectionVerticle; 28 | import com.englishtown.vertx.guice.integration.DummyVerticle; 29 | import com.google.common.collect.Lists; 30 | import com.google.inject.Guice; 31 | import com.google.inject.Injector; 32 | import com.google.inject.Module; 33 | import io.vertx.core.Context; 34 | import io.vertx.core.Future; 35 | import io.vertx.core.Verticle; 36 | import io.vertx.core.Vertx; 37 | import io.vertx.core.json.JsonObject; 38 | import io.vertx.core.spi.logging.LogDelegate; 39 | import org.junit.Before; 40 | import org.junit.BeforeClass; 41 | import org.junit.Test; 42 | import org.junit.runner.RunWith; 43 | import org.mockito.ArgumentCaptor; 44 | import org.mockito.Captor; 45 | import org.mockito.Mock; 46 | import org.mockito.Mockito; 47 | import org.mockito.runners.MockitoJUnitRunner; 48 | 49 | import java.util.List; 50 | 51 | import static org.junit.Assert.assertEquals; 52 | import static org.mockito.Mockito.*; 53 | 54 | /** 55 | * Unit tests for {@link GuiceVerticleLoader} 56 | */ 57 | @RunWith(MockitoJUnitRunner.class) 58 | public class GuiceVerticleLoaderTest { 59 | 60 | private JsonObject config = new JsonObject(); 61 | private static LogDelegate logger; 62 | 63 | @Mock 64 | private Vertx vertx; 65 | @Mock 66 | private Context context; 67 | @Mock 68 | private Injector parent; 69 | @Mock 70 | private Injector child; 71 | @Mock 72 | private Verticle verticle; 73 | @Mock 74 | private Future future; 75 | @Captor 76 | private ArgumentCaptor> modulesCaptor; 77 | @Captor 78 | private ArgumentCaptor> classCaptor; 79 | 80 | @BeforeClass 81 | public static void setUpOnce() { 82 | logger = MockLogDelegateFactory.getLogDelegate(); 83 | } 84 | 85 | @Before 86 | public void setUp() { 87 | MockLogDelegateFactory.reset(); 88 | when(context.config()).thenReturn(config); 89 | when(parent.createChildInjector(Mockito.>any())).thenReturn(child); 90 | when(child.getInstance(any(Class.class))).thenReturn(verticle); 91 | } 92 | 93 | private GuiceVerticleLoader doTest(String main) throws Exception { 94 | 95 | ClassLoader cl = Thread.currentThread().getContextClassLoader(); 96 | GuiceVerticleLoader loader = new GuiceVerticleLoader(main, cl, parent); 97 | loader.init(vertx, context); 98 | loader.start(future); 99 | 100 | verify(verticle).init(eq(vertx), eq(context)); 101 | verify(verticle).start(future); 102 | verify(parent).createChildInjector(modulesCaptor.capture()); 103 | verify(child).getInstance(classCaptor.capture()); 104 | 105 | loader.stop(future); 106 | verify(verticle).stop(eq(future)); 107 | 108 | return loader; 109 | } 110 | 111 | private List getModules() { 112 | return Lists.newArrayList(modulesCaptor.getValue()); 113 | } 114 | 115 | @Test 116 | public void testStart_Compiled() throws Exception { 117 | 118 | String main = DependencyInjectionVerticle.class.getName(); 119 | doTest(main); 120 | 121 | verifyZeroInteractions(logger); 122 | assertEquals(DependencyInjectionVerticle.class, classCaptor.getValue()); 123 | 124 | } 125 | 126 | @Test 127 | public void testStart_Uncompiled() throws Exception { 128 | 129 | String main = "UncompiledDIVerticle.java"; 130 | doTest(main); 131 | 132 | verifyZeroInteractions(logger); 133 | assertEquals("UncompiledDIVerticle", classCaptor.getValue().getName()); 134 | 135 | } 136 | 137 | @Test 138 | public void testStart_Custom_Binder() throws Exception { 139 | 140 | config.put("guice_binder", CustomBinder.class.getName()); 141 | 142 | String main = DependencyInjectionVerticle.class.getName(); 143 | doTest(main); 144 | 145 | verifyZeroInteractions(logger); 146 | assertEquals(DependencyInjectionVerticle.class, classCaptor.getValue()); 147 | 148 | List modules = getModules(); 149 | assertEquals(2, modules.size()); 150 | assertEquals(CustomBinder.class, modules.get(0).getClass()); 151 | 152 | } 153 | 154 | @Test 155 | public void testStart_Not_A_Binder() throws Exception { 156 | 157 | String binder = String.class.getName(); 158 | config.put("guice_binder", binder); 159 | 160 | String main = DependencyInjectionVerticle.class.getName(); 161 | doTest(main); 162 | 163 | verify(logger).error(eq("Class " + binder + " does not implement Module.")); 164 | assertEquals(1, getModules().size()); 165 | 166 | } 167 | 168 | @Test 169 | public void testStart_Class_Not_Found_Binder() throws Exception { 170 | parent = null; 171 | String binder = "com.englishtown.INVALID_BINDER"; 172 | config.put("guice_binder", binder); 173 | 174 | String main = DummyVerticle.class.getName(); 175 | ClassLoader cl = Thread.currentThread().getContextClassLoader(); 176 | GuiceVerticleLoader loader = new GuiceVerticleLoader(main, cl, parent); 177 | loader.init(vertx, context); 178 | loader.start(future); 179 | loader.stop(future); 180 | 181 | verify(logger).warn(eq("Guice bootstrap binder class " + binder + " was not found. Are you missing injection bindings?")); 182 | } 183 | 184 | @Test 185 | public void testStart_Class_Not_Found_Binder_With_Parent() throws Exception { 186 | String binder = "com.englishtown.INVALID_BINDER"; 187 | config.put("guice_binder", binder); 188 | 189 | String main = DependencyInjectionVerticle.class.getName(); 190 | doTest(main); 191 | 192 | verifyZeroInteractions(logger); 193 | assertEquals(1, getModules().size()); 194 | } 195 | 196 | } 197 | -------------------------------------------------------------------------------- /vertx-guice/src/test/java/com/englishtown/vertx/guice/MockLogDelegateFactory.java: -------------------------------------------------------------------------------- 1 | package com.englishtown.vertx.guice; 2 | 3 | import io.vertx.core.logging.LoggerFactory; 4 | import io.vertx.core.spi.logging.LogDelegate; 5 | import io.vertx.core.spi.logging.LogDelegateFactory; 6 | import org.mockito.Mockito; 7 | 8 | import static org.mockito.Mockito.mock; 9 | 10 | public class MockLogDelegateFactory implements LogDelegateFactory { 11 | 12 | private static LogDelegate logDelegate = mock(LogDelegate.class); 13 | 14 | static { 15 | // Use our own test logger factory / logger instead. We can't use powermock to statically mock the 16 | // LoggerFactory since javassist 1.18.x contains a bug that prevents the usage of powermock. 17 | System.setProperty(LoggerFactory.LOGGER_DELEGATE_FACTORY_CLASS_NAME, MockLogDelegateFactory.class.getName()); 18 | LoggerFactory.removeLogger(GuiceVerticleLoader.class.getName()); 19 | LoggerFactory.initialise(); 20 | } 21 | 22 | public static LogDelegate getLogDelegate() { 23 | return logDelegate; 24 | } 25 | 26 | public static void reset() { 27 | Mockito.reset(logDelegate); 28 | } 29 | 30 | @Override 31 | public LogDelegate createDelegate(String name) { 32 | return logDelegate; 33 | } 34 | } -------------------------------------------------------------------------------- /vertx-guice/src/test/java/com/englishtown/vertx/guice/MyDependency.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * Copyright © 2016 Englishtown 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the “Software”), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | */ 23 | 24 | package com.englishtown.vertx.guice; 25 | 26 | public interface MyDependency { 27 | } 28 | -------------------------------------------------------------------------------- /vertx-guice/src/test/java/com/englishtown/vertx/guice/MyDependency2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * Copyright © 2016 Englishtown 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the “Software”), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | */ 23 | 24 | package com.englishtown.vertx.guice; 25 | 26 | /** 27 | * Created with IntelliJ IDEA. 28 | * User: adriangonzalez 29 | * Date: 4/5/13 30 | * Time: 3:49 PM 31 | * To change this template use File | Settings | File Templates. 32 | */ 33 | public interface MyDependency2 { 34 | } 35 | -------------------------------------------------------------------------------- /vertx-guice/src/test/java/com/englishtown/vertx/guice/TestGuiceVerticle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * Copyright © 2016 Englishtown 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the “Software”), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | */ 23 | 24 | package com.englishtown.vertx.guice; 25 | 26 | import io.vertx.core.AbstractVerticle; 27 | 28 | import javax.inject.Inject; 29 | 30 | /** 31 | * Created with IntelliJ IDEA. 32 | * User: adriangonzalez 33 | * Date: 4/5/13 34 | * Time: 3:49 PM 35 | * To change this template use File | Settings | File Templates. 36 | */ 37 | public class TestGuiceVerticle extends AbstractVerticle { 38 | 39 | private final MyDependency dependency; 40 | 41 | @Inject 42 | public TestGuiceVerticle(MyDependency dependency) { 43 | this.dependency = dependency; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /vertx-guice/src/test/java/com/englishtown/vertx/guice/integration/CustomBinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * Copyright © 2016 Englishtown 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the “Software”), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | */ 23 | 24 | package com.englishtown.vertx.guice.integration; 25 | 26 | import com.englishtown.vertx.guice.DefaultMyDependency; 27 | import com.englishtown.vertx.guice.MyDependency; 28 | import com.google.inject.AbstractModule; 29 | 30 | /** 31 | * Custom Guice binder 32 | */ 33 | public class CustomBinder extends AbstractModule { 34 | @Override 35 | protected void configure() { 36 | bind(MyDependency.class).to(DefaultMyDependency.class); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /vertx-guice/src/test/java/com/englishtown/vertx/guice/integration/DependencyInjectionVerticle.java: -------------------------------------------------------------------------------- 1 | package com.englishtown.vertx.guice.integration; 2 | 3 | import com.englishtown.vertx.guice.MyDependency; 4 | import io.vertx.core.AbstractVerticle; 5 | 6 | import javax.inject.Inject; 7 | 8 | import static org.junit.Assert.assertNotNull; 9 | 10 | /** 11 | * Verticle with dependencies injected 12 | */ 13 | public class DependencyInjectionVerticle extends AbstractVerticle { 14 | 15 | public static final String EB_ADDRESS = "et.address"; 16 | 17 | private final MyDependency myDependency; 18 | 19 | @Inject 20 | public DependencyInjectionVerticle(MyDependency myDependency) { 21 | this.myDependency = myDependency; 22 | assertNotNull(myDependency); 23 | } 24 | 25 | @Override 26 | public void start() throws Exception { 27 | vertx.eventBus() 28 | .consumer(EB_ADDRESS) 29 | .handler(msg -> msg.reply(myDependency.getClass().getName())); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /vertx-guice/src/test/java/com/englishtown/vertx/guice/integration/DependencyInjectionVerticle2.java: -------------------------------------------------------------------------------- 1 | package com.englishtown.vertx.guice.integration; 2 | 3 | import static org.junit.Assert.assertNotNull; 4 | import io.vertx.core.AbstractVerticle; 5 | 6 | import javax.inject.Inject; 7 | 8 | import com.englishtown.vertx.guice.MyDependency2; 9 | 10 | /** 11 | * Verticle with dependencies injected 12 | */ 13 | public class DependencyInjectionVerticle2 extends AbstractVerticle { 14 | 15 | @SuppressWarnings("unused") 16 | private final MyDependency2 myDependency; 17 | 18 | @Inject 19 | public DependencyInjectionVerticle2(MyDependency2 myDependency) { 20 | this.myDependency = myDependency; 21 | assertNotNull(myDependency); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /vertx-guice/src/test/java/com/englishtown/vertx/guice/integration/DummyVerticle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the confidential unpublished intellectual property of EMC Corporation, 3 | * and includes without limitation exclusive copyright and trade secret rights 4 | * of EMC throughout the world. 5 | */ 6 | package com.englishtown.vertx.guice.integration; 7 | 8 | import io.vertx.core.AbstractVerticle; 9 | 10 | /** 11 | * Verticle with no dependencies inejected. 12 | */ 13 | public class DummyVerticle extends AbstractVerticle { 14 | 15 | public DummyVerticle() { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /vertx-guice/src/test/java/com/englishtown/vertx/guice/integration/IntegrationTestVerticle.java: -------------------------------------------------------------------------------- 1 | package com.englishtown.vertx.guice.integration; 2 | 3 | import com.englishtown.vertx.guice.*; 4 | import com.google.inject.AbstractModule; 5 | import com.google.inject.Guice; 6 | import com.google.inject.Injector; 7 | import io.vertx.core.DeploymentOptions; 8 | import io.vertx.core.Verticle; 9 | import io.vertx.core.Vertx; 10 | import io.vertx.core.json.JsonObject; 11 | import io.vertx.test.core.VertxTestBase; 12 | import org.junit.Test; 13 | 14 | import javax.inject.Inject; 15 | import javax.inject.Singleton; 16 | import java.util.concurrent.CompletableFuture; 17 | import java.util.concurrent.ExecutionException; 18 | 19 | /** 20 | * Integration test to show a verticle deployed with a injection constructor 21 | */ 22 | public class IntegrationTestVerticle extends VertxTestBase { 23 | 24 | @Test 25 | public void testDependencyInjection_Succeed() throws Exception { 26 | deployVerticle(DependencyInjectionVerticle.class).get(); 27 | } 28 | 29 | @Test(expected = ExecutionException.class) 30 | public void testDependencyInjection_Fail() throws Exception { 31 | deployVerticle(DependencyInjectionVerticle2.class).get(); 32 | } 33 | 34 | @Test 35 | public void testDependencyInjection_ParentInjector() throws Exception { 36 | 37 | Injector parent = Guice.createInjector(new AbstractModule() { 38 | @Override 39 | protected void configure() { 40 | bind(MyDependency2.class).to(DefaultMyDependency2.class).in(Singleton.class); 41 | } 42 | }); 43 | 44 | getFactory().setInjector(parent); 45 | deployVerticle(DependencyInjectionVerticle2.class).get(); 46 | 47 | } 48 | 49 | @Test 50 | public void testDependencyInjection_ParentInjector_Vertx() throws Exception { 51 | 52 | Injector parent = Guice.createInjector(new GuiceVertxBinder(vertx), new AbstractModule() { 53 | @Override 54 | protected void configure() { 55 | bind(MyDependency.class).to(CustomMyDependency.class).in(Singleton.class); 56 | } 57 | }); 58 | 59 | getFactory().setInjector(parent); 60 | 61 | DeploymentOptions options = new DeploymentOptions() 62 | .setConfig(new JsonObject() 63 | .put(GuiceVerticleLoader.CONFIG_BOOTSTRAP_BINDER_NAME, NOPBinder.class.getName())); 64 | 65 | deployVerticle(DependencyInjectionVerticle.class, options).get(); 66 | 67 | vertx.eventBus() 68 | .send(DependencyInjectionVerticle.EB_ADDRESS, null, result -> { 69 | if (result.succeeded()) { 70 | assertEquals(CustomMyDependency.class.getName(), result.result().body()); 71 | testComplete(); 72 | } else { 73 | fail(result.cause()); 74 | } 75 | }); 76 | 77 | await(); 78 | } 79 | 80 | @Test 81 | public void testDependencyInjection_Uncompiled() throws Exception { 82 | deployVerticle("UncompiledDIVerticle.java").get(); 83 | } 84 | 85 | private GuiceVerticleFactory getFactory() { 86 | return vertx.verticleFactories() 87 | .stream() 88 | .filter(f -> f instanceof GuiceVerticleFactory) 89 | .map(f -> (GuiceVerticleFactory) f) 90 | .findFirst() 91 | .orElseThrow(() -> new IllegalStateException("Could not find the guice verticle factory...")); 92 | } 93 | 94 | private CompletableFuture deployVerticle(Class clazz) { 95 | return deployVerticle(clazz, new DeploymentOptions()); 96 | } 97 | 98 | private CompletableFuture deployVerticle(Class clazz, DeploymentOptions options) { 99 | return deployVerticle(clazz.getName(), options); 100 | } 101 | 102 | private CompletableFuture deployVerticle(String name) { 103 | return deployVerticle(name, new DeploymentOptions()); 104 | } 105 | 106 | private CompletableFuture deployVerticle(String name, DeploymentOptions options) { 107 | CompletableFuture future = new CompletableFuture<>(); 108 | 109 | vertx.deployVerticle(GuiceVerticleFactory.PREFIX + ":" + name, options, result -> { 110 | if (result.succeeded()) { 111 | future.complete(result.result()); 112 | } else { 113 | future.completeExceptionally(result.cause()); 114 | } 115 | }); 116 | 117 | return future; 118 | } 119 | 120 | private static class CustomMyDependency extends DefaultMyDependency { 121 | 122 | @Inject 123 | public CustomMyDependency(Vertx vertx) { 124 | super(vertx); 125 | } 126 | 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /vertx-guice/src/test/java/com/englishtown/vertx/guice/integration/NOPBinder.java: -------------------------------------------------------------------------------- 1 | package com.englishtown.vertx.guice.integration; 2 | 3 | import com.google.inject.AbstractModule; 4 | import com.google.inject.Binder; 5 | 6 | /** 7 | * NOP binder 8 | */ 9 | public class NOPBinder extends AbstractModule { 10 | /** 11 | * Configures a {@link Binder} via the exposed methods. 12 | */ 13 | @Override 14 | protected void configure() { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /vertx-guice/src/test/resources/UncompiledDIVerticle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * Copyright © 2016 Englishtown 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the “Software”), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | */ 23 | 24 | import static org.junit.Assert.assertNotNull; 25 | import io.vertx.core.AbstractVerticle; 26 | import javax.inject.Inject; 27 | import com.englishtown.vertx.guice.MyDependency; 28 | 29 | public class UncompiledDIVerticle extends AbstractVerticle { 30 | 31 | private final MyDependency myDependency; 32 | 33 | @Inject 34 | public UncompiledDIVerticle(MyDependency myDependency) { 35 | this.myDependency = myDependency; 36 | assertNotNull(myDependency); 37 | } 38 | } --------------------------------------------------------------------------------