Visualize package dependencies with mermaid and 'bnd xref'

  1. Run the bnd xref command in your comand line (e.g. install via brew on MacOS):

bnd xref */generated/*.jar | sed -r 's/ < / --> /g'

The sed replaces the < in the output with -->. The direction might not be correct, but I just wanted to get something working.

  1. Paste the output or parts of the output to https://mermaid.live/

  2. Get a visual graph or something like this:

Feel free to modify it as needed with filtering and what not. Inspired by this github issue.

1 Like

The bndlib contains a DOT class that makes it trivial to turn this into a dot file. (graphviz).

Note that the bnd resolve command has such an option

Thanks @pkriens . Any hints about the bnd resolve command?
I tried:

cd myworkspace_with_a_cnf_folder
bnd resolve dot my.bundle.with.the.bndruns/myapp.bndrun

But I got “Resolution failed Unable to resolve” … although when I click resolve in Eclipse on the myapp.bndrun, it resolves.

Am I in the wrong folder?

You have to be in the project directory. I guess the resolve command has a -p to direct this to another directory.

bnd resolve dot test.bndrun 
................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................digraph "test.bndrun" {
  "<<INITIAL>>" -> "biz.aQute.websocket.jetty.provider[4]"
  "<<INITIAL>>" -> "org.apache.felix.webconsole[16]"
  "<<INITIAL>>" -> "org.apache.felix.configadmin[8]"
  "<<INITIAL>>" -> "org.apache.felix.gogo.runtime[10]"
  "<<INITIAL>>" -> "org.apache.felix.log[14]"
  "<<INITIAL>>" -> "org.apache.felix.http.jetty[12]"
  "<<INITIAL>>" -> "biz.aQute.graphql.gqljava.provider[3]"
  "biz.aQute.websocket.jetty.provider[4]" -> "org.apache.felix.http.servlet-api[13]"
  "biz.aQute.websocket.jetty.provider[4]" -> "biz.aQute.api.websocket[1]"
  "biz.aQute.websocket.jetty.provider[4]" -> "org.osgi.service.component[17]"
  "biz.aQute.websocket.jetty.provider[4]" -> "org.apache.felix.http.jetty[12]"
  "biz.aQute.websocket.jetty.provider[4]" -> "org.apache.felix.scr[15]"
  "org.apache.felix.gogo.command[9]" -> "org.apache.felix.gogo.runtime[10]"
  "org.osgi.util.promise[19]" -> "org.osgi.util.function[18]"
  "org.apache.commons.fileupload[6]" -> "org.apache.commons.io[7]"
  "org.apache.commons.fileupload[6]" -> "org.apache.felix.http.servlet-api[13]"
  "org.apache.felix.webconsole[16]" -> "org.apache.commons.io[7]"
  "org.apache.felix.webconsole[16]" -> "org.apache.felix.http.servlet-api[13]"
  "org.apache.felix.webconsole[16]" -> "org.apache.commons.fileupload[6]"
  "org.apache.felix.webconsole[16]" -> "org.apache.felix.http.jetty[12]"
  "org.apache.felix.configadmin[8]" -> "org.apache.felix.log[14]"
  "biz.aQute.api.graphql[0]" -> "biz.aQute.graphql.gqljava.provider[3]"
  "biz.aQute.graphql.framework.example[2]" -> "biz.aQute.api.graphql[0]"
  "biz.aQute.graphql.framework.example[2]" -> "reactive-streams[20]"
  "biz.aQute.graphql.framework.example[2]" -> "org.apache.felix.http.jetty[12]"
  "biz.aQute.graphql.framework.example[2]" -> "org.apache.felix.scr[15]"
  "biz.aQute.wrapper.graphql[5]" -> "reactive-streams[20]"
  "biz.aQute.api.websocket[1]" -> "biz.aQute.websocket.jetty.provider[4]"
  "org.osgi.service.component[17]" -> "org.osgi.util.promise[19]"
  "org.apache.felix.gogo.runtime[10]" -> "org.apache.felix.gogo.shell[11]"
  "org.apache.felix.log[14]" -> "org.apache.felix.configadmin[8]"
  "org.apache.felix.http.jetty[12]" -> "org.apache.felix.http.servlet-api[13]"
  "org.apache.felix.http.jetty[12]" -> "org.apache.felix.configadmin[8]"
  "org.apache.felix.http.jetty[12]" -> "org.apache.felix.log[14]"
  "org.apache.felix.scr[15]" -> "org.osgi.util.promise[19]"
  "org.apache.felix.scr[15]" -> "org.apache.felix.configadmin[8]"
  "org.apache.felix.scr[15]" -> "org.osgi.service.component[17]"
  "org.apache.felix.scr[15]" -> "org.apache.felix.gogo.runtime[10]"
  "org.apache.felix.scr[15]" -> "org.apache.felix.log[14]"
  "biz.aQute.graphql.gqljava.provider[3]" -> "org.apache.felix.http.servlet-api[13]"
  "biz.aQute.graphql.gqljava.provider[3]" -> "reactive-streams[20]"
  "biz.aQute.graphql.gqljava.provider[3]" -> "biz.aQute.api.graphql[0]"
  "biz.aQute.graphql.gqljava.provider[3]" -> "biz.aQute.graphql.framework.example[2]"
  "biz.aQute.graphql.gqljava.provider[3]" -> "biz.aQute.wrapper.graphql[5]"
  "biz.aQute.graphql.gqljava.provider[3]" -> "biz.aQute.api.websocket[1]"
  "biz.aQute.graphql.gqljava.provider[3]" -> "org.apache.felix.gogo.runtime[10]"
  "biz.aQute.graphql.gqljava.provider[3]" -> "org.apache.felix.scr[15]"
  "org.apache.felix.gogo.shell[11]" -> "org.apache.felix.gogo.command[9]"
  "org.apache.felix.gogo.shell[11]" -> "org.apache.felix.gogo.runtime[10]"
}