Guice and Reflections inside a Jar file

I am experimenting with Google Guice (3.0) and Google Reflections (0.9.6).

I have the following files:

Operation.java:

package com.company1.calculator; public interface Operation { public int apply(int a, int b); } 

Addition.java:

 package com.company1.calculator; public class Addition implements Operation { @Override public int apply(int a, int b) { return a + b; } } 

Other various classes of "operations" distributed over several packages.

CalculatorModule.java:

 package com.company1.calculator; import com.google.inject.AbstractModule; import com.google.inject.multibindings.MapBinder; import org.reflections.Reflections; public class CalculatorModule extends AbstractModule { @Override protected void configure() { Reflections reflections = new Reflections(""); MapBinder<String, Operation> map = MapBinder.newMapBinder(binder(), String.class, Operation.class); for (Class<? extends Operation> o : reflections.getSubTypesOf(Operation.class)) { map.addBinding(o.getSimpleName()).to(o); } } } 

Calculator.java:

 package com.company1.calculator; import com.google.inject.Inject; import java.util.Map; public class Calculator { private Map<String, Operation> operations; @Inject public Calculator(Map<String, Operation> operations) { this.operations = operations; } public void printCalculations(int a, int b) { System.out.println("Calculator: " + a + " " + b); for (String s : operations.keySet()) { System.out.print(s + ": "); System.out.println(operations.get(s).apply(a, b)); } } } 

And finally, App.java:

 package com.company1.calculator; import com.google.inject.Guice; import com.google.inject.Injector; public class App { public static void main(String[] args) { Injector injector = Guice.createInjector(new CalculatorModule()); Calculator c = injector.getInstance(Calculator.class); c.printCalculations(3, 3); } } 

After running App.java inside IntelliJ, I get the following output, as expected:

Calculator: 3 3
Module: 0
Department: 1
Multiplication: 9
Addition: 6

However, when I package this application as a jar, I get only the following output:

Calculator: 3 3

Why is this and how can I fix it? The closest I found was Issue 48 , but this suggests that it has been fixed since May 2011. Of course, that would already have done it in Maven ...

+4
source share
1 answer

I was able to reproduce it exactly as described. The problem is that the default Reflections constructor tries to find the location on the disk where each given parameter can be found. When transferring "" in the IDE, it finds the / bin directory, and when started from / tmp / so 8780228.jar finds / tmp / (breakpoint in ConfigurationBuilder.java:87)

A simple workaround is to provide something other than "which does not give the configuration assembly any useful information and instead gives something like" com.company1 ", which can only be found in one place.

 Reflections reflections = new Reflections("com.company1"); 

In this case, ConfigurationBuilder correctly finds the path / tmp / so 8780228.jar to scan, and everything works as expected.

Alternatively, you can interact more with ConfigurationBuilder and tell it to look for each jar in the class path (for example, iterate System.getProperty (java.class.path) and add each), but performance will suffer.

+2
source

Source: https://habr.com/ru/post/1389928/


All Articles