There's a bug in the Guice grapher utility that causes most or all graphs to render corrupted. Is there a workaround or fix for this?
Using GuiceIn each of your constructors that need to have something injected in them, you just add an @Inject annotation and that tells Guice to do it's thing. Guice figures out how to give you an Emailer based on the type. If it's a simple object, it'll instantiate it and pass it in.
Guice (pronounced 'juice') is a lightweight dependency injection framework for Java 8 and above, brought to you by Google.
Beyond Dependency Injection, the benefits of using Google Guice is: Guice has a very clean implementation of constructor Injection. As you can see from the example you just add @Inject annotation constructor. Guice also has setter Injection using the same annotation.
I modified @wuppi's answer slightly to also hide class paths and long random name annotations to make the graph much more compact and readable. His answer with edited code follows:
I find this utility method pretty useful and it never pritned incorrect graphs for me.
Regarding the style=invis
bug: The Guice grapher plugin generates a dot file, which styles some of the clases as invisible. The replaceAll()
in the below posted method works around that. The rest of the code is nearly the same from the Guice example.
I've incorporated Scot's fix for Guice 4.x, which included Tim's answer as well:
public class Grapher {
public static void main(String[] args) throws Exception {
Grapher.graph4("filename.dot", Guice.createInjector(new MyModule()));
}
public static void graph4(String filename, Injector inj) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter out = new PrintWriter(baos);
Injector injector = Guice.createInjector(new GraphvizModule());
GraphvizGrapher renderer = injector.getInstance(GraphvizGrapher.class);
renderer.setOut(out);
renderer.setRankdir("TB");
renderer.graph(inj);
out = new PrintWriter(new File(filename), "UTF-8");
String s = baos.toString("UTF-8");
s = fixGrapherBug(s);
s = hideClassPaths(s);
out.write(s);
out.close();
}
public static String hideClassPaths(String s) {
s = s.replaceAll("\\w[a-z\\d_\\.]+\\.([A-Z][A-Za-z\\d_\\$]*)", "$1");
s = s.replaceAll("value=[\\w-]+", "random");
return s;
}
public static String fixGrapherBug(String s) {
s = s.replaceAll("style=invis", "style=solid");
s = s.replaceAll("margin=(\\S+), ", " margin=\"$1\", ");
return s;
}
}
Of course you are free to generate any other Filename :)
Guice 4.x example incorporating Jeff and Tim's solutions:
public class Grapher {
public static void main(String[] args) throws Exception {
Grapher.graph4("filename.dot", Guice.createInjector(new MyModule()));
}
public static void graph4(String filename, Injector inj) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter out = new PrintWriter(baos);
Injector injector = Guice.createInjector(new GraphvizModule());
GraphvizGrapher renderer = injector.getInstance(GraphvizGrapher.class);
renderer.setOut(out);
renderer.setRankdir("TB");
renderer.graph(inj);
out = new PrintWriter(new File(filename), "UTF-8");
String s = baos.toString("UTF-8");
s = fixGrapherBug(s);
s = hideClassPaths(s);
out.write(s);
out.close();
}
public static String hideClassPaths(String s) {
s = s.replaceAll("\\w[a-z\\d_\\.]+\\.([A-Z][A-Za-z\\d_]*)", "");
s = s.replaceAll("value=[\\w-]+", "random");
return s;
}
public static String fixGrapherBug(String s) {
s = s.replaceAll("style=invis", "style=solid");
s = s.replaceAll("margin=(\\S+), ", " margin=\"$1\", ");
return s;
}
}
When using the most recent version of GraphViz, I find that the following substitution also helps (otherwise GraphViz refuses to open the file):
s.replaceAll(" margin=(\\S+), ", " margin=\"$1\", ")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With