【问题标题】:Tool to generate graph data for class dependencies [closed]为类依赖项生成图形数据的工具[关闭]
【发布时间】:2013-11-06 08:40:58
【问题描述】:

是否有一些工具能够分析 Java 源文件,从中构建图表并以某种标准/可理解的格式提供图表数据

它绝对不需要 GUI,我更喜欢命令行的东西,这样我就可以通过各种工具(用于分割、可视化等)处理输出。

【问题讨论】:

  • 你说“分析 Java 源文件”是什么意思?
  • 我的意思是“这个类扩展了这个类,实现了这些接口,使用(引用这些类,甚至可能来自什么方法)......”理想情况下考虑继承(也许是访问控制?)。
  • Class Dependency Tools for Java 的可能重复项
  • 该工具是否必须处理源代码,还是可以处理已编译的类?
  • 你试过 FastClasspathScanner 吗? stackoverflow.com/a/43095956/1422630

标签: java dependencies static-analysis


【解决方案1】:

我不确定命令行工具,但我喜欢使用 ObjectAid 对类图进行逆向工程:

http://www.objectaid.com/

您可以轻松地将任何类及其关系添加到 ObjectAid 图表中。它以带有 ucls 扩展名的 XML 格式保存文件。这是一个示例:

<?xml version="1.0" encoding="UTF-8"?>
<class-diagram version="1.1.4" icons="true"
always-add-relationships="true" generalizations="true" realizations="true"
associations="true" dependencies="true" nesting-relationships="true">
<class id="1" language="java"
    name="my.classpath.common.controllers.AuthenticationInterceptor"
    project="MyProject"
    file="/SpecialPath/common/controllers/AuthenticationInterceptor.java"
    binary="false" corner="BOTTOM_RIGHT">
    <position height="205" width="355" x="2222" y="37" />
    <display autosize="true" stereotype="true" package="true"
        initial-value="false" signature="true" accessors="true" visibility="true">
        <attributes public="true" package="true" protected="true"
            private="true" static="true" />
        <operations public="true" package="true" protected="true"
            private="true" static="true" />
    </display>
</class>
<class id="2" language="java"
    name="my.classpath.common.domain.CompanyAssignmentLocation" project="MyProject"
    file="/SpecialPath/common/domain/CompanyAssignmentLocation.java"
    binary="false" corner="BOTTOM_RIGHT">
    <position height="-1" width="-1" x="856" y="399" />
    <display autosize="true" stereotype="true" package="true"
        initial-value="false" signature="true" accessors="true" visibility="true">
        <attributes public="true" package="true" protected="true"
            private="true" static="true" />
        <operations public="true" package="true" protected="true"
            private="true" static="true" />
    </display>
</class>
<class id="3" language="java"
    name="my.classpath.common.domain.LocationsSpreadsheetReader" project="MyProject"
    file="/SpecialPath/common/domain/LocationsSpreadsheetReader.java"
    binary="false" corner="BOTTOM_RIGHT">
    <position height="115" width="348" x="680" y="37" />
    <display autosize="true" stereotype="true" package="true"
        initial-value="false" signature="true" accessors="true" visibility="true">
        <attributes public="true" package="true" protected="true"
            private="true" static="true" />
        <operations public="true" package="true" protected="true"
            private="true" static="true" />
    </display>
</class>
<class id="4" language="java" name="my.classpath.common.domain.Stock"
    project="MyProject" file="/SpecialPath/common/domain/Stock.java"
    binary="false" corner="BOTTOM_RIGHT">
    <position height="439" width="210" x="430" y="37" />
    <display autosize="true" stereotype="true" package="true"
        initial-value="false" signature="true" accessors="true" visibility="true">
        <attributes public="true" package="true" protected="true"
            private="true" static="true" />
        <operations public="true" package="true" protected="true"
            private="true" static="true" />
    </display>
</class>
<class id="5" language="java" name="my.classpath.common.util.FilesUtil"
    project="MyProject" file="/SpecialPath/common/util/FilesUtil.java"
    binary="false" corner="BOTTOM_RIGHT">
    <position height="277" width="218" x="1409" y="37" />
    <display autosize="true" stereotype="true" package="true"
        initial-value="false" signature="true" accessors="true" visibility="true">
        <attributes public="true" package="true" protected="true"
            private="true" static="true" />
        <operations public="true" package="true" protected="true"
            private="true" static="true" />
    </display>
</class>
<class id="6" language="java" name="my.classpath.common.util.MyProjectUtil"
    project="MyProject" file="/SpecialPath/common/util/MyProjectUtil.java"
    binary="false" corner="BOTTOM_RIGHT">
    <position height="439" width="349" x="41" y="37" />
    <display autosize="true" stereotype="true" package="true"
        initial-value="false" signature="true" accessors="true" visibility="true">
        <attributes public="true" package="true" protected="true"
            private="true" static="true" />
        <operations public="true" package="true" protected="true"
            private="true" static="true" />
    </display>
</class>
<class id="7" language="java" name="my.classpath.common.util.SpringUtil"
    project="MyProject" file="/SpecialPath/common/util/SpringUtil.java"
    binary="false" corner="BOTTOM_RIGHT">
    <position height="133" width="246" x="1936" y="37" />
    <display autosize="true" stereotype="true" package="true"
        initial-value="false" signature="true" accessors="true" visibility="true">
        <attributes public="true" package="true" protected="true"
            private="true" static="true" />
        <operations public="true" package="true" protected="true"
            private="true" static="true" />
    </display>
</class>
<class id="8" language="java"
name="my.classpath.common.util.MyProjectUserUtil" project="MyProject"
file="/SpecialPath/common/util/MyProjectUserUtil.java" binary="false"
corner="BOTTOM_RIGHT">
    <position height="133" width="229" x="1667" y="37" />
    <display autosize="true" stereotype="true" package="true"
        initial-value="false" signature="true" accessors="true" visibility="true">
        <attributes public="true" package="true" protected="true"
            private="true" static="true" />
        <operations public="true" package="true" protected="true"
            private="true" static="true" />
    </display>
</class>
<class id="9" language="java" name="my.classpath.common.util.UnitConversion"
    project="MyProject" file="/SpecialPath/common/util/UnitConversion.java"
    binary="false" corner="BOTTOM_RIGHT">
    <position height="151" width="301" x="1068" y="37" />
    <display autosize="true" stereotype="true" package="true"
        initial-value="false" signature="true" accessors="true" visibility="true">
        <attributes public="true" package="true" protected="true"
            private="true" static="true" />
        <operations public="true" package="true" protected="true"
            private="true" static="true" />
    </display>
</class>
<dependency id="10">
    <end type="SOURCE" refId="3" />
    <end type="TARGET" refId="2" />
</dependency>
<classifier-display autosize="true" stereotype="true"
    package="true" initial-value="false" signature="true" accessors="true"
    visibility="true">
    <attributes public="true" package="true" protected="true"
        private="true" static="true" />
    <operations public="true" package="true" protected="true"
        private="true" static="true" />
</classifier-display>
    <association-display labels="true" multiplicity="true" />
</class-diagram>

您也可以使用 PlantUML,但它更适合正向工程而不是逆向工程:

http://plantuml.sourceforge.net/

PlantUML 有自己独特的语法,您也可以从中获取源代码 - 但它不像 ObjectAid 那样容易整合

这两个都作为 eclipse 插件工作,很抱歉我不知道更多关于任何命令行工具可能能够完成你所要求的工作。

【讨论】:

  • 谢谢,但这正是我不想要的——我需要处理人际关系,而不是演示。 UML 图对我的意图来说太粗粒度了。
  • 您有任何可以提供的示例输出或期望的结果吗?就人际关系而言,我对您想要处理的内容有点困惑。
  • 有什么我可以更好地回答以防止被否决的吗?
  • 理想情况下,输出将是 GraphML,但我对任何简单的文本格式都很满意,所以类似以下的内容就可以了:class ClassA extends ClassX / class ClassA uses ClassB / method fixIt() uses ClassX.how() / 方法 fixIt() 使用 ClassX.what /
  • ObjectAID 生成一个 XML 文件 - 我在答案中添加了一个示例。我不知道它会满足您的要求,但看起来它可以帮助您满足您的需求。
【解决方案2】:

至于命令行工具,大家不妨看看jdeps

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jdeps.html

jdeps -cp <your cp> -v <path to your .class file>

【讨论】:

    【解决方案3】:

    这里是Class Dependency Analyzer (CDA)

    此工具的目的是分析 Java™ 类文件,以便 详细了解这些类之间的依赖关系。

    这里是 API:http://www.dependency-analyzer.org/#PluginAPI

    【讨论】:

    • 这看起来不错,可能可以定制以满足一些mi需求。不幸的是,它适用于类文件,而不是源。许可证也非常严格。
    【解决方案4】:

    来自http://blog.schauderhaft.de/degraph/

    您可以使用 Degraph 分析类文件和 jar,并获得一个 graphml 文件作为结果。这可以使用 yed 来呈现。

    【讨论】:

      【解决方案5】:

      您可能对UMLGraph 有用。它像大多数此类图形工具一样利用 GraphViz/dot。不过我没用过,所以无法评价。

      话虽如此,您也可以仅使用 GraphViz 和 dot 推出自己的简约图表工具。

      我使用 GraphViz/dot 生成了许多有用的图表类型,从 Spring 上下文的可视化到 IntelliJ 模块依赖项,再到复杂 XML 文档的可视化。环顾四周,看看你发现了什么。

      【讨论】:

      • 我不需要生成图表,至少目前不需要。而且我需要找到一个工具来收集我能够首先完成的信息。
      • 嘿。你说“图形”我认为图形的渲染:-)。可能是因为我现在正忙于进行点渲染。祝你好运!
      【解决方案6】:

      试试Google CodePro Analytix。该工具提供了有关dependencies 的良好见解。

      但是我还没有尝试从命令行的角度使用它。我希望它支持报告导出,可以在工具链中进一步解析。

      【讨论】:

      • 谢谢。我之前正在查看它 - 无法下载它,并且该页面基于 Eclipse 是面向 GUI 的。我真的不想要 GUI,我需要图形才能在其上使用通用图形工具。
      【解决方案7】:

      我在我的 IDE 中使用了这个功能 - IntelliJ Idea

      查看此页面了解更多信息和截图http://www.jetbrains.com/idea/features/uml_class_diagram.html

      【讨论】:

      • 我知道,对我来说绝对太弱了,虽然我非常喜欢 IDEA。
      【解决方案8】:

      如果问题仍然存在,请尝试使用 Code Iris 插件。它适用于 Intellij Idea http://plugins.jetbrains.com/plugin/7324

      它提供了类、包和模块级别的依赖图的可视化表示。此外,您可以将数据导出为 json 格式。

      它仍然是更新和免费的。

      【讨论】:

        【解决方案9】:

        我刚刚创建了一个最小的工具,它可以分析和显示包之间的依赖关系图,无需太多交互或需要其他程序。

        https://github.com/battlesnake/jorgy

        因为它是一个快速的 hack 项目,所以没有记录,但基本上你运行它并将源目录的路径作为第一个参数传递给它。

        它不关心目录名或文件名,但确实需要:

        • package 在每个文件中声明。

        • 在顶层定义的正是一种类型(零个或多个嵌套在其中的内部类型都可以)。

        您可以更改Application 类中的GraphStyle 接口以满足您的需要。该接口提供了一种方式让您告诉图形构建器哪些依赖项是弱的,哪些不应该显示在图形上等。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-03-05
          • 2010-09-07
          • 1970-01-01
          • 1970-01-01
          • 2021-07-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多