kazurayam / vba-callgraph

Generating a Call Graph for Excel VBA workbooks
https://kazurayam.github.io/VBACallGraph/
Apache License 2.0
0 stars 0 forks source link

自作のJavaプログラムからPlantUMLを起動する方法を解明しよう #27

Closed kazurayam closed 2 months ago

kazurayam commented 3 months ago

https://gist.github.com/GAM3RG33K/cc59290e8fe68d61c7ab2540f8471fd3 を参考に。

kazurayam commented 3 months ago

HomebrewでPlantUMLの実行可能なバイナリファイルをmacにインストールした。

$ brew install plantuml
==> Downloading https://formulae.brew.sh/api/formula.jws.json
######################################################################### 100.0%
==> Downloading https://formulae.brew.sh/api/cask.jws.json
######################################################################### 100.0%
plantuml 1.2024.5 is already installed but outdated (so it will be upgraded).
==> Downloading https://ghcr.io/v2/homebrew/core/plantuml/manifests/1.2024.6
Already downloaded: /Users/kazuakiurayama/Library/Caches/Homebrew/downloads/f06333faffc96c360b27ab1a050d4a4b80c39855b2f6c69bceaa1f34512a8279--plantuml-1.2024.6.bottle_manifest.json
==> Fetching plantuml
==> Downloading https://ghcr.io/v2/homebrew/core/plantuml/blobs/sha256:0492d42c3
######################################################################### 100.0%
==> Upgrading plantuml
  1.2024.5 -> 1.2024.6 
==> Pouring plantuml--1.2024.6.sonoma.bottle.tar.gz
🍺  /usr/local/Cellar/plantuml/1.2024.6: 5 files, 21MB
==> Running `brew cleanup plantuml`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
Removing: /usr/local/Cellar/plantuml/1.2024.5... (5 files, 11.4MB)
Removing: /Users/kazuakiurayama/Library/Caches/Homebrew/plantuml_bottle_manifest--1.2024.5... (53.7KB)
:~

どこにインストールされたかというと

$ which plantuml
/usr/local/bin/plantuml

ちゃんと動くか?

$ plantuml -version
PlantUML version 1.2024.6 (Sat Jul 06 18:14:38 JST 2024)
(GPL source distribution)
Java Runtime: OpenJDK Runtime Environment
JVM: OpenJDK 64-Bit Server VM
Default Encoding: UTF-8
Language: ja
Country: JP

PLANTUML_LIMIT_SIZE: 4096

Dot version: dot - graphviz version 12.0.0 (20240704.0754)
Installation seems OK. File generation OK
:~

PlantUMLの実行可能ファイルをmacにインストールできた。

kazurayam commented 3 months ago

GraphVizも必要だ。

$ brew install graphviz
graphviz 12.0.0 is already installed but outdated (so it will be upgraded).
==> Downloading https://ghcr.io/v2/homebrew/core/graphviz/manifests/12.1.0
######################################################################### 100.0%
==> Fetching dependencies for graphviz: libx11
==> Downloading https://ghcr.io/v2/homebrew/core/libx11/manifests/1.8.10
######################################################################### 100.0%
==> Fetching libx11
==> Downloading https://ghcr.io/v2/homebrew/core/libx11/blobs/sha256:ae4c27d7553
######################################################################### 100.0%
==> Fetching graphviz
==> Downloading https://ghcr.io/v2/homebrew/core/graphviz/blobs/sha256:d26fe0fd8
######################################################################### 100.0%
==> Upgrading graphviz
  12.0.0 -> 12.1.0 
==> Installing dependencies for graphviz: libx11
==> Installing graphviz dependency: libx11
==> Downloading https://ghcr.io/v2/homebrew/core/libx11/manifests/1.8.10
Already downloaded: /Users/kazuakiurayama/Library/Caches/Homebrew/downloads/2e75e14e6bb3157688933738ae64e0dc86954ca8ef075737dda6b890d605d566--libx11-1.8.10.bottle_manifest.json
==> Pouring libx11--1.8.10.sonoma.bottle.tar.gz
🍺  /usr/local/Cellar/libx11/1.8.10: 1,043 files, 6.8MB
==> Installing graphviz
==> Pouring graphviz--12.1.0.sonoma.bottle.tar.gz
🍺  /usr/local/Cellar/graphviz/12.1.0: 281 files, 6.2MB
==> Running `brew cleanup graphviz`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
Removing: /usr/local/Cellar/graphviz/12.0.0... (283 files, 5.6MB)
Removing: /Users/kazuakiurayama/Library/Caches/Homebrew/graphviz_bottle_manifest--12.0.0... (55.0KB)
==> Upgrading 1 dependent of upgraded formulae:
Disable this behaviour by setting HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
bazel 7.1.2 -> 7.3.0
==> Downloading https://ghcr.io/v2/homebrew/core/bazel/manifests/7.3.0
######################################################################### 100.0%
==> Fetching dependencies for bazel: python@3.12 and openjdk@21
==> Downloading https://ghcr.io/v2/homebrew/core/python/3.12/manifests/3.12.5
######################################################################### 100.0%
==> Fetching python@3.12
==> Downloading https://ghcr.io/v2/homebrew/core/python/3.12/blobs/sha256:9f9356
######################################################################### 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/openjdk/21/manifests/21.0.4
######################################################################### 100.0%
==> Fetching openjdk@21
==> Downloading https://ghcr.io/v2/homebrew/core/openjdk/21/blobs/sha256:be8c445
######################################################################### 100.0%
==> Fetching bazel
==> Downloading https://ghcr.io/v2/homebrew/core/bazel/blobs/sha256:3989cc53a05a
######################################################################### 100.0%
==> Upgrading bazel
  7.1.2 -> 7.3.0 
==> Installing dependencies for bazel: python@3.12 and openjdk@21
==> Installing bazel dependency: python@3.12
==> Downloading https://ghcr.io/v2/homebrew/core/python/3.12/manifests/3.12.5
Already downloaded: /Users/kazuakiurayama/Library/Caches/Homebrew/downloads/2cc40b4b76a48e24e9d83ccbaa744d74a15494224fdcd425d2fefeb9100357b8--python@3.12-3.12.5.bottle_manifest.json
==> Pouring python@3.12--3.12.5.sonoma.bottle.tar.gz
==> Downloading https://formulae.brew.sh/api/formula.jws.json
#=#=-#  #                                                                       
==> /usr/local/Cellar/python@3.12/3.12.5/bin/python3.12 -Im ensurepip
==> /usr/local/Cellar/python@3.12/3.12.5/bin/python3.12 -Im pip install -v --no-
🍺  /usr/local/Cellar/python@3.12/3.12.5: 3,260 files, 61MB
==> Installing bazel dependency: openjdk@21
==> Downloading https://ghcr.io/v2/homebrew/core/openjdk/21/manifests/21.0.4
Already downloaded: /Users/kazuakiurayama/Library/Caches/Homebrew/downloads/ee6e81d8c4a10c27b80286cfc12aa30f0464eda579d2ec21054219d222189626--openjdk@21-21.0.4.bottle_manifest.json
==> Pouring openjdk@21--21.0.4.sonoma.bottle.tar.gz
🍺  /usr/local/Cellar/openjdk@21/21.0.4: 602 files, 330.5MB
==> Installing bazel
==> Pouring bazel--7.3.0.sonoma.bottle.tar.gz
==> Caveats
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d
==> Summary
🍺  /usr/local/Cellar/bazel/7.3.0: 11 files, 49.3MB
==> Running `brew cleanup bazel`...
Removing: /usr/local/Cellar/bazel/7.1.2... (11 files, 47MB)
Removing: /Users/kazuakiurayama/Library/Caches/Homebrew/bazel_bottle_manifest--7.1.2... (29.7KB)
==> Checking for dependents of upgraded formulae...
==> No broken dependents found!
==> Caveats
==> bazel
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d
:~

GraphViz v12.0.0から12.1.0へアップグレードされた。ちなみにopenJDK@21が同梱されていて、それがサイズが大きくて、ダウンロードするのに数分かかった。

dotコマンドがどこにインストールされたかというと

$ which dot
/usr/local/bin/dot

ちゃんと動くか?

$ dot -version
dot - graphviz version 12.1.0 (20240811.2233)
libdir = "/usr/local/Cellar/graphviz/12.1.0/lib/graphviz"
Activated plugin library: libgvplugin_dot_layout.6.dylib
Using layout: dot:dot_layout
Activated plugin library: libgvplugin_core.6.dylib
Using render: dot:core
Using device: dot:dot:core
The plugin configuration file:
    /usr/local/Cellar/graphviz/12.1.0/lib/graphviz/config6
        was successfully loaded.
    render  :  cairo dot dot_json fig gd json json0 map pic pov ps quartz svg svg_inline tk vrml xdot xdot_json
    layout  :  circo dot fdp neato nop nop1 nop2 osage patchwork sfdp twopi
    textlayout  :  textlayout
    device  :  bmp canon cgimage cmap cmapx cmapx_np dot dot_json eps exr fig gd gd2 gif gv icns ico imap imap_np ismap jp2 jpe jpeg jpg json json0 kitty kittyz pct pdf pic pict plain plain-ext png pov ps ps2 psd sgi svg svg_inline svgz tga tif tiff tk vrml vt vt-24bit vt-4up vt-6up vt-8up wbmp webp xdot xdot1.2 xdot1.4 xdot_json
    loadimage   :  (lib) bmp eps gd gd2 gif jpe jpeg jpg pdf png ps svg webp xbm

dotコマンドが正常に動いた

kazurayam commented 3 months ago

macならばHomebrewを使う。Windowsではどうする?

https://github.com/plantuml/plantuml/issues/1029

maybe try chocolatey: https://www.youtube.com/watch?v=7Cp2LS9eE3c then: https://community.chocolatey.org/packages/plantuml

だって。

kazurayam commented 3 months ago

PlantUMLもDotコマンドも、コマンドラインでexeファイルを実行するというやり方をしなければならない。自作したJavaコードがコマンドライン経由でexeを実行したい。どうするか?

今こそわたしの Subprocessj の出番だ。

kazurayam commented 3 months ago

issue27ブランチを追加した。

com.kazurayam.vba.diagram.PlantUMLRunnerクラスを実装した。

com.kazurayam.vba.diagram.PlantUMLRunnerTestを実行したらエラーが発生した。

> Task :lib:testClasses UP-TO-DATE
2024-08-14T06:09:25.042744Z Test worker ERROR Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
[                              ] 0/1java.lang.ClassNotFoundException: org.apache.batik.apps.rasterizer.SVGConverter
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:413)
    at java.base/java.lang.Class.forName(Class.java:404)
    at net.sourceforge.plantuml.pdf.PdfConverter.convert(PdfConverter.java:61)
    at net.sourceforge.plantuml.UmlDiagram.exportDiagramInternalPdf(UmlDiagram.java:266)
    at net.sourceforge.plantuml.UmlDiagram.exportDiagramNow(UmlDiagram.java:134)
    at net.sourceforge.plantuml.AbstractPSystem.exportDiagram(AbstractPSystem.java:207)
    at net.sourceforge.plantuml.PSystemUtils.exportDiagramsDefault(PSystemUtils.java:207)
    at net.sourceforge.plantuml.PSystemUtils.exportDiagrams(PSystemUtils.java:96)
    at net.sourceforge.plantuml.SourceFileReaderAbstract.getGeneratedImages(SourceFileReaderAbstract.java:190)
    at net.sourceforge.plantuml.Run.manageFileInternal(Run.java:510)
    at net.sourceforge.plantuml.Run.processArgs(Run.java:404)
    at net.sourceforge.plantuml.Run.manageAllFiles(Run.java:371)
    at net.sourceforge.plantuml.Run.main(Run.java:206)
Exception in thread "main" java.lang.UnsupportedOperationException
    at net.sourceforge.plantuml.pdf.PdfConverter.convert(PdfConverter.java:80)
    at net.sourceforge.plantuml.UmlDiagram.exportDiagramInternalPdf(UmlDiagram.java:266)
    at net.sourceforge.plantuml.UmlDiagram.exportDiagramNow(UmlDiagram.java:134)
    at net.sourceforge.plantuml.AbstractPSystem.exportDiagram(AbstractPSystem.java:207)
    at net.sourceforge.plantuml.PSystemUtils.exportDiagramsDefault(PSystemUtils.java:207)
    at net.sourceforge.plantuml.PSystemUtils.exportDiagrams(PSystemUtils.java:96)
    at net.sourceforge.plantuml.SourceFileReaderAbstract.getGeneratedImages(SourceFileReaderAbstract.java:190)
    at net.sourceforge.plantuml.Run.manageFileInternal(Run.java:510)
    at net.sourceforge.plantuml.Run.processArgs(Run.java:404)
    at net.sourceforge.plantuml.Run.manageAllFiles(Run.java:371)
    at net.sourceforge.plantuml.Run.main(Run.java:206)

Subprocess returns 1
java.lang.IllegalStateException: Subprocess returns 1
    at com.kazurayam.vba.diagram.PlantUMLRunner.run(PlantUMLRunner.java:76)
    at com.kazurayam.vba.diagram.PlantUMLRunnerTest.test_smoke(PlantUMLRunnerTest.java:58)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:141)
    at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:686)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:230)
    at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:63)
    at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:992)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:203)
    at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:154)
    at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:134)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.testng.TestRunner.privateRun(TestRunner.java:739)
    at org.testng.TestRunner.run(TestRunner.java:614)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:421)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:413)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:373)
    at org.testng.SuiteRunner.run(SuiteRunner.java:312)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1274)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1208)
    at org.testng.TestNG.runSuites(TestNG.java:1112)
    at org.testng.TestNG.run(TestNG.java:1079)
    at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.runTests(TestNGTestClassProcessor.java:148)
    at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.stop(TestNGTestClassProcessor.java:95)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
    at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)

> Task :lib:test
Gradle suite > Gradle test > com.kazurayam.vba.diagram.PlantUMLRunnerTest > test_smoke FAILED
    java.lang.IllegalStateException at PlantUMLRunnerTest.java:58
1 test completed, 1 failed

まずい感じだ。

kazurayam commented 3 months ago

GitHub上の PlantUMLプロジェクトの Releaseページを見たら

https://github.com/plantuml/plantuml/pkgs/container/plantuml

こうやれと書いてある。

$ docker pull ghcr.io/plantuml/plantuml:sha-36e07ea

jar単体ではインストールできない。dockerコンテナを使えということだ。

わたしはmacにdocker for Macをインストール済みだった。まづdocker for Macを起動せよ。

docker for Macが立ち上がるのを待って、上記のように docker pullせよ。

そしてplantumlマンドをdockerコンテナ上で実行するには

$ docker run ghcr.io/plantuml puファイル -o 出力先 -tpdf

というふうにdocker runコマンドを使うべきなのだろう。やってみよう。

kazurayam commented 3 months ago

Diagramファイル(.puとか.pumlとかいう名前のテキストファイル)をPlantUMLに食わせてPNGやPDFを生成させようと試みた。しかしできなかった。

テスト を実行したらこんなエラーが出力された。

> Task :lib:testClasses UP-TO-DATE
2024-08-14T08:59:40.399550Z Test worker ERROR Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
17:59:43.617 [Test worker] INFO com.kazurayam.vba.diagram.PlantUMLRunner -- commandline: docker run ghcr.io/plantuml/plantuml /Users/kazuakiurayama/github/VBAProcedureUsageAnalyzer/lib/build/tmp/testOutput/com.kazurayam.vba.diagram.PlantUMLRunnerTest/test_smoke.pu -progress -tpdf --verbose
(0.001 - 128 Mo) 122 Mo - SecurityProfile LEGACY
(0.007 - 128 Mo) 122 Mo - PlantUML Version 1.2024.6
(0.007 - 128 Mo) 122 Mo - GraphicsEnvironment.isHeadless() true
(0.008 - 128 Mo) 122 Mo - Forcing -Djava.awt.headless=true
(0.008 - 128 Mo) 122 Mo - java.awt.headless set as true
(0.009 - 128 Mo) 122 Mo - Forcing resource load on OpenJdk
(0.382 - 128 Mo) 120 Mo - Found 0 files
No diagram found

Expecting path:
  /Users/kazuakiurayama/github/VBAProcedureUsageAnalyzer/lib/build/tmp/testOutput/com.kazurayam.vba.diagram.PlantUMLRunnerTest/out.pdf
to exist (symbolic links were followed).
java.lang.AssertionError: 
Expecting path:
  /Users/kazuakiurayama/github/VBAProcedureUsageAnalyzer/lib/build/tmp/testOutput/com.kazurayam.vba.diagram.PlantUMLRunnerTest/out.pdf
to exist (symbolic links were followed).
    at com.kazurayam.vba.diagram.PlantUMLRunnerTest.test_smoke(PlantUMLRunnerTest.java:56)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:141)
    at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:686)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:230)
    at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:63)
    at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:992)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:203)
    at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:154)
    at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:134)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.testng.TestRunner.privateRun(TestRunner.java:739)
    at org.testng.TestRunner.run(TestRunner.java:614)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:421)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:413)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:373)
    at org.testng.SuiteRunner.run(SuiteRunner.java:312)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1274)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1208)
    at org.testng.TestNG.runSuites(TestNG.java:1112)
    at org.testng.TestNG.run(TestNG.java:1079)
    at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.runTests(TestNGTestClassProcessor.java:148)
    at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.stop(TestNGTestClassProcessor.java:95)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
    at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)

つまりこういうコマンドを実行してエラ〜になっている。

$ docker run ghcr.io/plantuml/plantuml /Users/kazuakiurayama/github/VBAProcedureUsageAnalyzer/lib/build/tmp/testOutput/com.kazurayam.vba.diagram.PlantUMLRunnerTest/test_smoke.pu -progress -tpdf --verbose

dockerコンテナ上で動いたplantumlが.../test_smoke.puという名前のdiagramファイルを見つけられなくて「やるべき仕事がない」とばかりに終了している。このコマンドラインの書き方ではだめなのだろう。では、どう書くのが正解なのだろうか?

PlantUML の公式ドキュメントを読んだが、このdockerコンテナの使い方を説明する箇所が見つからなかった。別のdocker image すなわち plantuml-server:jetty の使い方が書いてあったが、plantuml:latestの使い方の説明はない。

plantuml-server:jettyを使って何ができるかといえば、Webブラウザでdiagramファイルを開くとplant-uml-server:jettyが画像に変換するのでそれをwebブラウザの中で見ることができる、ということ。うーん、それってIntelliJ IDEAやVSCodeの中でdiagramファイルを開いてプレビューするのに比べて何もメリットがない。つまらない。

kazurayam commented 3 months ago

自作のJavaプログラムからPlantUMLを駆動してdiagramファイルからPDFファイルを生成しようと試みたが、この課題は棚上げにする。

kazurayam commented 3 months ago

IntelliJ IDEAやVSCodeでdiagramファイルをプレビューできるし、プレビューの画像をローカルのPNGファイルに保存することは簡単にできる。

さて、PNG画像が得られたところで要求が止まるか?

実は止まらない。PNG画像を紙に印刷したくなったらどうすればいい?PlantUMLによって生成されるPNG画像は大きい。それだけでなくてタテxヨコのサイズが変化する。クラスの矩形を1個追加したり削除したりしただけで大きさが変化することもよくある。このPNG画像を紙に印刷しようとすると途方に暮れる。ここに解決すべき問題がある。

別にissueを立ててそっちでこの課題に取り組もう。 → #29

kazurayam commented 2 months ago

自作のJavaプログラムからPlantUMLを駆動してdiagramファイルからPDFファイルを生成しようと試みたが、この課題は棚上げにする。

いやいや、そうは問屋が下さない。

dockerコンテナの使い方を復習すれば多分解決できる。やれ。

kazurayam commented 2 months ago

ローカルにインストールしたplantumlを使ってpumlファイルを変換しようとしてエラーになったのだが、その理由がわかった。

Exception in thread "main" java.lang.UnsupportedOperationException
    at net.sourceforge.plantuml.pdf.PdfConverter.convert(PdfConverter.java:80)
    at net.sourceforge.plantuml.UmlDiagram.exportDiagramInternalPdf(UmlDiagram.java:266)
    at net.sourceforge.plantuml.UmlDiagram.exportDiagramNow(UmlDiagram.java:134)
    at net.sourceforge.plantuml.AbstractPSystem.exportDiagram(AbstractPSystem.java:207)
    at net.sourceforge.plantuml.PSystemUtils.exportDiagramsDefault(PSystemUtils.java:207)
    at net.sourceforge.plantuml.PSystemUtils.exportDiagrams(PSystemUtils.java:96)
    at net.sourceforge.plantuml.SourceFileReaderAbstract.getGeneratedImages(SourceFileReaderAbstract.java:190)
    at net.sourceforge.plantuml.Run.manageFileInternal(Run.java:510)
    at net.sourceforge.plantuml.Run.processArgs(Run.java:404)
    at net.sourceforge.plantuml.Run.manageAllFiles(Run.java:371)
    at net.sourceforge.plantuml.Run.main(Run.java:206)

plantumlコマンドに対して -tpdf を指定した。だからplantumlはpdfを出力しようとしたのだが、なんということでしょう、バグがあった。

plantumlコマンドに-tpdfを指定したのが敗因だ。-tpngを指定してPNG画像ファイルを出力させレバいい。バグを回避できる。

kazurayam commented 2 months ago

done at v0.1.15