I am about to migrate a project created with an old version of Spring (using XML config) to Spring Boot (using Java config).
The project is using Spring Integration for communication via JMS and AMQP. As far as I understood, I have to replace the
<int:gateway id="someID" service-interface="MyMessageGateway"
default-request-channel="myRequestChannel"
default-reply-channel="myResponseChannel"
default-reply-timeout="20000" />
with
#MessagingGateway(name="someID", defaultRequestChannel = "myRequestChannel",
defaultReplyChannel = "myResponseChannel", defaultReplyTimeout = "20000")
public interface MyMessageGateway{ ...... }
My problem is, that the interface, that is in use now, is placed in a library I can't access.
How can I define this Interface as my MessagingGateway?
Thanks in advance!
I have just tested this trick:
interface IControlBusGateway {
void send(String command);
}
#MessagingGateway(defaultRequestChannel = "controlBus")
interface ControlBusGateway extends IControlBusGateway {
}
...
#Autowired
private IControlBusGateway controlBus;
...
try {
this.bridgeFlow2Input.send(message);
fail("Expected MessageDispatchingException");
}
catch (Exception e) {
assertThat(e, instanceOf(MessageDeliveryException.class));
assertThat(e.getCause(), instanceOf(MessageDispatchingException.class));
assertThat(e.getMessage(), containsString("Dispatcher has no subscribers"));
}
this.controlBus.send("#bridge.start()");
this.bridgeFlow2Input.send(message);
reply = this.bridgeFlow2Output.receive(5000);
assertNotNull(reply);
In other words you can just extends that external interface to your local one. The GatewayProxyFactoryBean will do the proxy magic for you underneath.
Also we have this JIRA for similar use-case: https://jira.spring.io/browse/INT-4134
Use a GatewayProxyFactoryBean; here's a simple example:
#SpringBootApplication
public class So41162166Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(So41162166Application.class, args);
context.getBean(NoAnnotationsAllowed.class).foo("foo");
context.close();
}
#Bean
public GatewayProxyFactoryBean gateway() {
GatewayProxyFactoryBean gateway = new GatewayProxyFactoryBean(NoAnnotationsAllowed.class);
gateway.setDefaultRequestChannel(channel());
return gateway;
}
#Bean
public MessageChannel channel() {
return new DirectChannel();
}
#ServiceActivator(inputChannel = "channel")
public void out(String foo) {
System.out.println(foo);
}
public static interface NoAnnotationsAllowed {
public void foo(String out);
}
}
Related
I have a Spring Boot application with a working configuration where ElasticsearchCustomConversions are used. Works fine.
Inside this application I want to create some standalone src/test/java classes where I can test my ElasticsearchRepository logic. Standalone because starting Spring Boot every time is too time consuming.
I am able to use a ElasticsearchRepository in a standalone java program like:
public class ExampleRepositoryStandaloneTester {
private static ElasticsearchRepositoryFactory factoryBean;
static {
ClientConfiguration clientConfiguration = ClientConfiguration.builder().connectedTo("localhost:9200").build();
RestHighLevelClient client = RestClients.create(clientConfiguration).rest();
ElasticsearchOperations elasticsearchOperations = new ElasticsearchRestTemplate(client);
factoryBean = new ElasticsearchRepositoryFactory(elasticsearchOperations);
}
public static ProductRepository getProductRepository() {
return factoryBean.getRepository(ProductRepository.class);
}
public static void main(String[] args) {
System.out.println("Product count: " + getProductRepository().count());
}}
The count function is really going to my local docker Elastic instance and prints the Product count. So this works.
But, my model needs ElasticsearchCustomConversions and I cannot find a way to properly setup the ElasticsearchRepositoryFactory so that the conversion are configured and used.
Does anyone know how to do this?
Spring Boot v2.3.4.RELEASE
​Spring Data Elasticsearch 4.0.4.RELEASE
Elasticsearch 7.6.2
Versions are dependency managed through a RedHat fuse version so I cannot (easily) upgrade to newer versions.
The following attempt fails with "No converter found capable of converting from type [java.lang.Boolean] to type [com.my.TrueFalseType]":
public class ExampleCustomConversionsTester {
static class ExampleConfigurator extends AbstractElasticsearchConfiguration {
private RestHighLevelClient client;
public ExampleConfigurator(RestHighLevelClient client) {
ExampleConfigurator.this.client = client;
}
#Override
public RestHighLevelClient elasticsearchClient() {
return client;
}
#Override
public ElasticsearchCustomConversions elasticsearchCustomConversions() {
return new ElasticsearchCustomConversions(Collections.singletonList(new TrueFalseTypeConverter()));
}
#ReadingConverter
static class TrueFalseTypeConverter implements Converter<Boolean, TrueFalseType> {
#Override
public TrueFalseType convert(Boolean value) {
return TrueFalseType.fromValue(value.toString());
}
}
}
static {
ClientConfiguration clientConfiguration = ClientConfiguration.builder().connectedTo("localhost:9200").build();
RestHighLevelClient client = RestClients.create(clientConfiguration).rest();
ExampleConfigurator cfg = new ExampleConfigurator(client);
ElasticsearchOperations elasticsearchOperations = new ElasticsearchRestTemplate(cfg.elasticsearchClient());
MappingElasticsearchConverter elasticsearchConverter = (MappingElasticsearchConverter) elasticsearchOperations.getElasticsearchConverter();
elasticsearchConverter.setConversions(cfg.elasticsearchCustomConversions());
factoryBean = new ElasticsearchRepositoryFactory(cfg.elasticsearchOperations(elasticsearchConverter));
}
private static ElasticsearchRepositoryFactory factoryBean;
public static ProductRepository getProductRepository() {
return factoryBean.getRepository(ProductRepository.class);
}
public static void main(String[] args) {
System.out.println("Product count: " + getProductRepository().count());
Page<Product> page = getProductRepository().findProducts(PageRequest.of(0, 10));
}
}
After you set the conversions with
elasticsearchConverter.setConversions(cfg.elasticsearchCustomConversions());
you need to call
elasticsearchConverter.afterPropertiesSet()
as described in the Javadoc for the setConversions method. Normally Spring does this, but as you are not using Spring to setup the beans, you need to do this in your code.
Could someone give me advice, please, how to re-write some method using simple Spring (w/o Boot)?
Here I have some code methods:
1. createInjector
private Injector injector;
someMethod(){
injector = Guice.createInjector(new ExampleClass1(), new ExampleClass2());}
2 setModules(Modules.override
setModules(Modules.override(new ExampleClass3()).with(new ExampleClass4()));
//////////////////////////////////////////////////////////////////
public static void setModules(Module... modules) {
initInjector(modules);
}
private static void initInjector(Module... modules) {
injector = Guice.createInjector(modules);
}
}
Taking the risk that my answer is too general.
Roughly saying you can think Guice modules as equivalent a configuration class with #Configuration annotation, that contains #Bean etc.
The Guice injector can be considered as equivalent to the Spring ApplicationContext.
So for example if we have two configuration files:
#Configuration
public class ConfigA {
#Bean
ExampleClass1 exampleClass1(){
return new ExampleClass1();
}
#Bean
ExampleClass2 exampleClass2(){
return new ExampleClass2();
}
}
#Configuration
public class ConfigB {
#Bean
ExampleClass1 exampleClass1(){
return new ExampleClass1();
}
#Bean
ExampleClass3 exampleClass2(){
return new ExampleClass3();
}
}
And Services ExampleClass4 that you want as alternative of ExampleClass3.
You may use the #Primary annotation
public class ExampleClass4 extends ExampleClass3 {
#Override
public String toString() {
return "ExampleClass4{}";
}
}
#Configuration
public class ConfigC {
#Bean
#Primary
ExampleClass3 exampleClass3(){
return new ExampleClass4();
}
}
So rewriting the app to Spring (core 5.2, not Spring boot) will be:
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ap = initAppContext();
overrideBinding(ap);
System.out.println(ap.getBean(ExampleClass3.class));
//prints ExampleClass4{}
}
private static AnnotationConfigApplicationContext initAppContext() {
AnnotationConfigApplicationContext ap = new AnnotationConfigApplicationContext();
ap.register(ConfigA.class, ConfigB.class);
return ap;
}
private static void overrideBinding(AnnotationConfigApplicationContext ap) {
ap.register(ConfigC.class);
ap.refresh();
}
}
This technic of overriding a binding will work only because ExampleClass3 wasn't defined as primary, if it doesn't that would not work and you need to consider a different approach.
For more information:
https://www.baeldung.com/spring-application-context
https://docs.spring.io/spring-javaconfig/docs/1.0.0.m3/reference/html/modularizing-configurations.html
Override bean definition in java config
I have a Springboot application, where I have some Camel routes configured.
public class CamelConfig {
private static final Logger LOG = LoggerFactory.getLogger(CamelConfig.class);
#Value("${activemq.broker.url:tcp://localhost:61616}")
String brokerUrl;
#Value("${activemq.broker.maxconnections:1}")
int maxConnections;
#Bean
ConnectionFactory jmsConnectionFactory() {
PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory(new ActiveMQConnectionFactory(brokerUrl));
pooledConnectionFactory.setMaxConnections(maxConnections);
return pooledConnectionFactory;
}
#Bean
public RoutesBuilder route() {
LOG.info("Initializing camel routes......................");
return new SpringRouteBuilder() {
#Override
public void configure() throws Exception {
from("activemq:testQueue")
.to("bean:queueEventHandler?method=handleQueueEvent");
}
};
}
}
I want to test this route from activemq:testQueue to queueEventHandler::handleQueueEvent.
I tried different things mentioned here http://camel.apache.org/camel-test.html, but doesn't seem to get it working.
I am trying to do something like this:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = {CamelConfig.class, CamelTestContextBootstrapper.class})
public class CamelRouteConfigTest {
#Produce(uri = "activemq:testQueue")
protected ProducerTemplate template;
#Test
public void testSendMatchingMessage() throws Exception {
template.sendBodyAndHeader("testJson", "foo", "bar");
// Verify handleQueueEvent(...) method is called on bean queueEventHandler by mocking
}
But my ProducerTemplate is always null. I tried auto-wiring CamelContext, for which I get an exception saying it cannot resolve camelContext. But that can be resolved by adding SpringCamelContext.class to #SpringBootTest classes. But my ProducerTemplate is still null.
Please suggest. I am using Camel 2.18 and Spring Boot 1.4.
In Camel 2.22.0 and ongoing, which supports Spring Boot 2 you can use the following template to test your routes with Spring Boot 2 support:
#RunWith(CamelSpringRunner.class)
#SpringBootTest(webEnvironment = WebEnvironment.NONE, classes = {
Route1.class,
Route2.class,
...
})
#EnableAutoConfiguration
#DisableJmx
#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class RouteTest {
#TestConfiguration
static class Config {
#Bean
CamelContextConfiguration contextConfiguration() {
return new CamelContextConfiguration() {
#Override
public void beforeApplicationStart(CamelContext camelContext) {
// configure Camel here
}
#Override
public void afterApplicationStart(CamelContext camelContext) {
// Start your manual routes here
}
};
}
#Bean
RouteBuilder routeBuilder() {
return new RouteBuilder() {
#Override
public void configure() {
from("direct:someEndpoint").to("mock:done");
}
};
}
// further beans ...
}
#Produce(uri = "direct:start")
private ProducerTemplate template;
#EndpointInject(uri = "mock:done")
private MockEndpoint mockDone;
#Test
public void testCamelRoute() throws Exception {
mockDone.expectedMessageCount(1);
Map<String, Object> headers = new HashMap<>();
...
template.sendBodyAndHeaders("test", headers);
mockDone.assertIsSatisfied();
}
}
Spring Boot distinguishes between #Configuration and #TestConfiguration. The primer one will replace any existing configuration, if annotated on a top-level class, while #TestConfiguration will be run in addition to the other configurations.
Further, in larger projects you might run into auto-configuration issues as you can't rely on Spring Boot 2 to configure your custom database pooling or what not correctly or in cases where you have a specific directory structure and the configurations are not located within a direct ancestor directory. In that case it is proabably preferable to omit the #EnableAutoConfiguration annotation. In order to tell Spring to still auto-configure Camel you can simply pass CamelAutoConfiguration.class to the classes mentioned in #SpringBootTest
#SpringBootTest(webEnvironment = WebEnvironment.NONE, classes = {
Route1.class,
Route2.class,
RouteTest.Config.class,
CamelAutoConfiguration.class
}
As no automatic configuration is performed, Spring won't load the test configuration inside your test class nor initialize Camel as well. By adding those configs to the boot classes manually Spring will do it for you.
For one route with MQ and Spring Boot like this:
#Component
public class InboundRoute extends RouteBuilder {
#Override
public void configure() {
JaxbDataFormat personDataFormat = new JaxbDataFormat();
personDataFormat.setContextPath(Person.class.getPackage().getName());
personDataFormat.setPrettyPrint(true);
from("direct:start").id("InboundRoute")
.log("inbound route")
.marshal(personDataFormat)
.to("log:com.company.app?showAll=true&multiline=true")
.convertBodyTo(String.class)
.inOnly("mq:q.empi.deim.in")
.transform(constant("DONE"));
}
}
I use adviceWith in order to replace the endpoint and use only mocks:
#RunWith(CamelSpringBootRunner.class)
#UseAdviceWith
#SpringBootTest(classes = InboundApp.class)
#MockEndpoints("mock:a")
public class InboundRouteCamelTest {
#EndpointInject(uri = "mock:a")
private MockEndpoint mock;
#Produce(uri = "direct:start")
private ProducerTemplate template;
#Autowired
private CamelContext context;
#Test
public void whenInboundRouteIsCalled_thenSuccess() throws Exception {
mock.expectedMinimumMessageCount(1);
RouteDefinition route = context.getRouteDefinition("InboundRoute");
route.adviceWith(context, new AdviceWithRouteBuilder() {
#Override
public void configure() {
weaveByToUri("mq:q.empi.deim.in").replace().to("mock:a");
}
});
context.start();
String response = (String) template.requestBodyAndHeader("direct:start",
getSampleMessage("/SimplePatient.xml"), Exchange.CONTENT_TYPE, MediaType.APPLICATION_XML);
assertThat(response).isEqualTo("DONE");
mock.assertIsSatisfied();
}
private String getSampleMessage(String filename) throws Exception {
return IOUtils
.toString(this.getClass().getResourceAsStream(filename), StandardCharsets.UTF_8.name());
}
}
I use the following dependencies: Spring Boot 2.1.4-RELEASE and Camel 2.23.2. The complete source code is available on Github.
This is how I did this finally:
#RunWith(SpringRunner.class)
public class CamelRouteConfigTest extends CamelTestSupport {
private static final Logger LOG = LoggerFactory.getLogger(CamelRouteConfigTest.class);
private static BrokerService brokerSvc = new BrokerService();
#Mock
private QueueEventHandler queueEventHandler;
#BeforeClass
// Sets up an embedded broker
public static void setUpBroker() throws Exception {
brokerSvc.setBrokerName("TestBroker");
brokerSvc.addConnector("tcp://localhost:61616");
brokerSvc.setPersistent(false);
brokerSvc.setUseJmx(false);
brokerSvc.start();
}
#Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new CamelConfig().route();
}
// properties in .yml has to be loaded manually. Not sure of .properties file
#Override
protected Properties useOverridePropertiesWithPropertiesComponent() {
YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
try {
PropertySource<?> applicationYamlPropertySource = loader.load(
"properties", new ClassPathResource("application.yml"),null);// null indicated common properties for all profiles.
Map source = ((MapPropertySource) applicationYamlPropertySource).getSource();
Properties properties = new Properties();
properties.putAll(source);
return properties;
} catch (IOException e) {
LOG.error("application.yml file cannot be found.");
}
return null;
}
#Override
protected JndiRegistry createRegistry() throws Exception {
JndiRegistry jndi = super.createRegistry();
MockitoAnnotations.initMocks(this);
jndi.bind("queueEventHandler", queueEventHandler);
return jndi;
}
#Test
// Sleeping for a few seconds is necessary, because this line template.sendBody runs in a different thread and
// CamelTest takes a few seconds to do the routing.
public void testRoute() throws InterruptedException {
template.sendBody("activemq:productpushevent", "HelloWorld!");
Thread.sleep(2000);
verify(queueEventHandler, times(1)).handleQueueEvent(any());
}
#AfterClass
public static void shutDownBroker() throws Exception {
brokerSvc.stop();
}
}
Did you try using Camel test runner?
#RunWith(CamelSpringJUnit4ClassRunner.class)
If you are using camel-spring-boot dependency, you may know that it uses auto configuration to setup Camel:
CamelAutoConfiguration.java
It means that you may also need to add #EnableAutoConfiguration to your test.
How can I register a custom converter in my MongoTemplate with Spring Boot? I would like to do this only using annotations if possible.
I just register the bean:
#Bean
public MongoCustomConversions mongoCustomConversions() {
List list = new ArrayList<>();
list.add(myNewConverter());
return new MongoCustomConversions(list);
}
Here is a place in source code where I find it
If you only want to override the custom converters portion of the Spring Boot configuration, you only need to create a configuration class that provides a #Bean for the custom converters. This is handy if you don't want to override all of the other Mongo settings (URI, database name, host, port, etc.) that Spring Boot has wired in for you from your application.properties file.
#Configuration
public class MongoConfig
{
#Bean
public CustomConversions customConversions()
{
List<Converter<?, ?>> converterList = new ArrayList<Converter<?, ?>>();
converterList.add(new MyCustomWriterConverter());
return new CustomConversions(converterList);
}
}
This will also only work if you've enabled AutoConfiguration and excluded the DataSourceAutoConfig:
#SpringBootApplication(scanBasePackages = {"com.mypackage"})
#EnableMongoRepositories(basePackages = {"com.mypackage.repository"})
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
public class MyApplication
{
public static void main(String[] args)
{
SpringApplication.run(MyApplication.class, args);
}
}
In this case, I'm setting a URI in the application.properties file and using Spring data repositories:
#mongodb settings
spring.data.mongodb.uri=mongodb://localhost:27017/mydatabase
spring.data.mongodb.repositories.enabled=true
You need to create a configuration class for converter config.
#Configuration
#EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class })
#Profile("!testing")
public class MongoConfig extends AbstractMongoConfiguration {
#Value("${spring.data.mongodb.host}") //if it is stored in application.yml, else hard code it here
private String host;
#Value("${spring.data.mongodb.port}")
private Integer port;
#Override
protected String getDatabaseName() {
return "test";
}
#Bean
public Mongo mongo() throws Exception {
return new MongoClient(host, port);
}
#Override
public String getMappingBasePackage() {
return "com.base.package";
}
#Override
public CustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(new LongToDateTimeConverter());
return new CustomConversions(converters);
}
}
#ReadingConverter
static class LongToDateTimeConverter implements Converter<Long, Date> {
#Override
public Date convert(Long source) {
if (source == null) {
return null;
}
return new Date(source);
}
}
Is there any sample code demonstrating how to use guice-servlet with Jersey 2.0?
https://github.com/Squarespace/jersey2-guice seems to be the first genuine Guice integration for Jersey 2 but it requires version 2.11+.
NOTE: I haven't tested this, but the idea is sound.
Yes, I've adapted an example and it's available here - https://github.com/piersy/jersey2-guice-example-with-test
I've updated the example code now, its got a test using jetty and another using tomcat.
There is a page at HK2 official about correct guice implementation: https://javaee.github.io/hk2/guice-bridge.html
You should create your Injector something like this:
public class GuiceConfig extends ResourceConfig {
#Inject
public GuiceConfig(ServiceLocator serviceLocator) {
this();
GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);
GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
guiceBridge.bridgeGuiceInjector(GuiceListener.createBiDirectionalGuiceBridge(serviceLocator));
}
public GuiceConfig() {
packages(Injections.packages);
addProperties(Injections.propertiesMap);
}
}
And code from the doc should be upgraded like:
#WebListener
public class GuiceListener extends GuiceServletContextListener {
#Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
Locale.setDefault(Locale.ENGLISH);
super.contextInitialized(servletContextEvent);
}
public static volatile Injector injector = null;
#Override
protected Injector getInjector() {
return injector;
}
#SuppressWarnings("unchecked")
private static Module getModule() {
return binder -> {
Injections.singletonInterfaces.forEach((i, c) -> binder.bind(i).to(c).in(Scopes.SINGLETON));
Injections.singletonClasses.forEach(c -> binder.bind(c).in(Scopes.SINGLETON));
};
}
static synchronized Injector createBiDirectionalGuiceBridge(ServiceLocator serviceLocator) {
return GuiceListener.injector = createBiDirectionalGuiceBridge(serviceLocator, getModule());
}
}
Using the maven dependency at your pom.xml
<dependency>
<groupId>org.glassfish.hk2</groupId>
<artifactId>guice-bridge</artifactId>
<version>2.3.0</version>
</dependency>
https://github.com/phxql/jersey2-guice doesn't work with jersey 2.22 and guice 4.0.
This is a minimum working PoC which wires Jersey 2 and Guice together:
https://github.com/phxql/jersey2-guice
I've already done in this sample:
https://github.com/jbescos/tododev
You have to register the class https://github.com/jbescos/tododev/blob/master/jersey2-guice/src/main/java/es/tododev/rest/ApplyGuiceContextFilter.java in your ResourceConfig, and the guice injector binded in an AbstractModule.
#Provider
#PreMatching
public class ApplyGuiceContextFilter implements ContainerRequestFilter, ContainerResponseFilter {
#Inject
public ApplyGuiceContextFilter(ServiceLocator serviceLocator, Injector injector) {
GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);
GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
guiceBridge.bridgeGuiceInjector(injector);
}
#Override
public void filter(final ContainerRequestContext requestContext) throws IOException {
}
#Override
public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext responseContext) throws IOException {}
}
This is the ResouceConfig:
public class RestConfig extends ResourceConfig {
#Inject
public RestConfig() {
this(Guice.createInjector(new Module(){
#Override
public void configure(Binder arg0) {
// TODO Auto-generated method stub
}
}));
}
// Test
public RestConfig(Injector injector) {
packages(ResourceSample.class.getPackage().getName());
register(ApplyGuiceContextFilter.class);
register(new LoggingFilter(Logger.getLogger(LoggingFilter.class.getName()), true));
property(ServerProperties.TRACING, "ALL");
register(new RestBinder(injector));
}
private static class RestBinder extends AbstractBinder{
private final Injector injector;
private RestBinder(Injector injector){
this.injector = injector;
}
#Override
protected void configure() {
bind(injector).to(Injector.class);
}
}
}
GWizard includes a module that gives you out-of-the-box integration between Jersey2 and Guice. Here's an example of a complete JAX-RS service:
public class Main {
#Path("/hello")
public static class HelloResource {
#GET
public String hello() {
return "hello, world";
}
}
public static class MyModule extends AbstractModule {
#Override
protected void configure() {
bind(HelloResource.class);
}
}
public static void main(String[] args) throws Exception {
Guice.createInjector(new MyModule(), new JerseyModule()).getInstance(WebServer.class).startJoin();
}
}
Note that this is based on the Squarespace jersey2-guice adapter, which may not function properly with future point releases of Jersey. GWizard also offers a RESTEasy JAX-RS module, which is preferred.
Here is a blog entry about this that might help: http://blorn.com/post/107397841765/guice-and-jersey-2-the-easy-way
For those interested, there is a sample of guice/jersey integration available at https://github.com/mycom-int/jersey-guice-aop.
Here is an example using Embedded Jetty (it should probably work for Jetty server too)
jetty-jersey-HK2-Guice-boilerplate
If you are planning to use Guice for your application, all Guice components injected into Jersey need to be declared as a binding in the Guice config.
If you don't want to declare every binding in Guice config, there is an adapter here:
guice-bridge-jit-injector