Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to get Guice Grapher to work?

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?

like image 571
Jeff Axelrod Avatar asked Feb 15 '12 20:02

Jeff Axelrod


People also ask

How does Guice @inject work?

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.

What is Guice dependency?

Guice (pronounced 'juice') is a lightweight dependency injection framework for Java 8 and above, brought to you by Google.

Why we use Google Guice?

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.


3 Answers

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 :)

like image 155
Jeff Axelrod Avatar answered Oct 21 '22 12:10

Jeff Axelrod


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;
    }
}
like image 31
Scot Avatar answered Oct 21 '22 12:10

Scot


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\", ")
like image 30
Tim Avatar answered Oct 21 '22 14:10

Tim