Skip to content

Commit 5e17485

Browse files
author
mrhunsaker
committed
fixes for a Git HEAD corruption
1 parent a02d21d commit 5e17485

9 files changed

Lines changed: 411 additions & 102 deletions

File tree

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pom.xml.versionsBackup
99
pom.xml.next
1010
release.properties
1111
dependency-reduced-pom.xml
12+
GraphDigitizer/
1213

1314
# IDE
1415
.idea/
@@ -50,3 +51,8 @@ bin/
5051
*.zip
5152
*.tar.gz
5253
*.rar
54+
*.exe
55+
*.msi
56+
*.dmp
57+
*.bak
58+
core.20251202.120453.9872.0001.dmp

.scripts/find_missing_javadoc.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import pathlib,re
2+
root=pathlib.Path('src/main/java')
3+
missing=[]
4+
for p in sorted(root.rglob('*.java')):
5+
s=p.read_text(encoding='utf-8')
6+
m=re.search(r'^(?:\s*)public\s+(class|record|enum|interface)\s+\w+', s, flags=re.M)
7+
if m:
8+
start=m.start()
9+
before=s[:start]
10+
# look for a /** that starts a javadoc block in the last 10 lines before
11+
prev_lines=before.rstrip('\n').split('\n')[-10:]
12+
has_javadoc=False
13+
for line in reversed(prev_lines):
14+
if '/**' in line:
15+
has_javadoc=True
16+
break
17+
if line.strip()=='' or line.strip().startswith('*') or line.strip().startswith('/*'):
18+
continue
19+
if not line.strip().startswith('//'):
20+
break
21+
if not has_javadoc:
22+
missing.append(str(p))
23+
print('\n'.join(missing))
24+
print('MISSING_COUNT:', len(missing))

META-INF/MANIFEST.MF

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Manifest-Version: 1.0
2+
Created-By: Maven JAR Plugin 3.3.0
3+
Build-Jdk-Spec: 24
4+
Main-Class: com.digitizer.ui.GraphDigitizerApp
5+

README.md

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,41 @@ A modern Java 21 / JavaFX implementation of the Graph Digitizer tool for extract
4747

4848
- **[jlink / jpackage Guide](docs/JPACKAGE.md)** - How to create runtime images, cross-arch examples (Docker), and use `jpackage` for native installers.
4949

50+
### **Native Packaging (Windows)**
51+
52+
- **Symptom:** Packaged launcher could exit early during GUI startup due to the runtime attempting to load a missing assistive-technology provider (AccessBridge). This manifests as an AWTError about "Assistive Technology not found: com.sun.java.accessibility.AccessBridge" during toolkit initialization.
53+
54+
- **Fix applied:** The Windows `jpackage` launcher is now created with an explicit JVM option that disables assistive-technology lookups on startup:
55+
56+
```
57+
--java-options -Djavax.accessibility.assistive_technologies=
58+
```
59+
60+
- **Where it's configured:** In the project `pom.xml` under the `native` profile's `jpackage-app-image` execution. The produced launcher (`target/jpackage/GraphDigitizer/app/GraphDigitizer.cfg`) will include the `java-options=-Djavax.accessibility.assistive_technologies=` entry so the packaged app does not attempt to load `com.sun.java.accessibility.AccessBridge` at runtime.
61+
62+
- **How to build (PowerShell):** quote properties in PowerShell so Maven parses them correctly, and use the `preserve.appimage` property to keep the `app-image` folder for inspection:
63+
64+
```powershell
65+
mvn -DskipTests verify -Pnative "-Dpreserve.appimage=true"
66+
```
67+
68+
- **How to test quickly (PowerShell):** run the bundled runtime to see verbose JavaFX output (example):
69+
70+
```powershell
71+
# Run the bundled java with the packaged classpath
72+
& .\target\jpackage\GraphDigitizer\runtime\bin\java.exe \
73+
-Djavax.accessibility.assistive_technologies= \
74+
-Dprism.verbose=true -Dprism.order=d3d \
75+
-cp ".\target\jpackage\GraphDigitizer\app\graph-digitizer.jar; .\target\jpackage\GraphDigitizer\app\lib\*" \
76+
com.digitizer.ui.GraphDigitizerApp
77+
```
78+
79+
- **Alternative:** If full assistive-technology support is required, bundle the appropriate Access Bridge classes in the runtime and enable them explicitly. For most users, disabling the lookup is lighter and avoids the ClassNotFoundException.
80+
81+
- **Notes:**
82+
- The `preserve.appimage` Maven property is used during the build to avoid an automated cleanup of `target/jpackage/GraphDigitizer` so you can inspect the `app` and `runtime` folders. In PowerShell, quote the `-Dpreserve.appimage=true` argument as shown above.
83+
- The change is safe for end users — it prevents an unnecessary classloading attempt when the AccessBridge is not present and does not affect normal GUI behavior.
84+
5085
### Packaging Scripts
5186

5287

@@ -59,35 +94,53 @@ A modern Java 21 / JavaFX implementation of the Graph Digitizer tool for extract
5994

6095
- **[Latest API (Javadoc)](https://mrhunsaker.github.io/Graph_Digitizer_Java_Implementation/)** – Generated from the current main branch
6196

97+
- **Local Javadoc:** To regenerate the API docs locally run:
98+
99+
```powershell
100+
mvn javadoc:javadoc
101+
```
102+
103+
The generated docs are written to `target/site/apidocs`.
104+
62105
- **Versioned Archives:** Each release will publish Javadocs under a subdirectory (e.g. `/1.1/`, `/1.2/`). Navigate directly to a version path to view older APIs.
63106

64107
## Quick Start
65108

66-
### Prerequisites
109+
### Java & JavaFX Requirements
67110

111+
This project uses Java 21 and JavaFX 21 (see `<properties>` in `pom.xml`). Packaging and runtime behavior depend on two things matching correctly:
68112

69-
- Java 21 or later
70-
jpackage --type dmg --name GraphDigitizer --main-jar graph_digitizer_1.0.jar \
113+
- Java runtime (JDK/JRE) that is compatible with JavaFX (HotSpot builds are recommended). We recommend using Eclipse Temurin (HotSpot) builds for packaging and runtime (`Java 21` LTS builds are tested). Avoid using OpenJ9 builds for the runtime image used by `jlink`/`jpackage` since some OpenJ9 builds have exhibited native compatibility issues with JavaFX in past tests.
114+
115+
- Matching JavaFX platform artifacts (jmods or platform jars) for the same JavaFX release (example: `javafx-21.0.2`). When creating runtime images with `jlink` you should use JavaFX `jmods` that match your JavaFX dependency version; for `jpackage` windows app-images we copy the platform jars into the app `lib/` directory so the launcher can find native JavaFX libraries at runtime.
116+
117+
Where to get them:
118+
119+
- Java (Temurin): https://adoptium.net/ — download the matching Java 21 (x64/arm64) HotSpot builds. Use the `jmods` or full JDK for `jlink`.
120+
- JavaFX SDK / jmods: https://openjfx.io/ or Gluon (https://gluonhq.com/products/javafx/) — download the JavaFX SDK / jmods that match the JavaFX version in `pom.xml`.
121+
122+
Packaging tips:
123+
124+
- Use a Temurin HotSpot JDK when running `jlink` and `jpackage` to produce the runtime image; specify the `--runtime-image` jlink output when invoking `jpackage`.
125+
- Ensure the JavaFX classifier/platform (e.g., `win`, `linux`, `mac`) matches the target OS when copying platform jars into `target/jpackage-input/lib`.
126+
- If you run into native crashes or rendering issues, try rebuilding the runtime with another HotSpot build (Temurin) and ensure JavaFX versions match exactly.
71127

128+
See the `docs/JPACKAGE.md` for detailed packaging examples and cross-arch instructions.
129+
130+
### Prerequisites
131+
132+
jpackage --type dmg --name GraphDigitizer --main-jar graph_digitizer_1.0.jar \
72133
Note: This project uses JavaFX 21 and therefore either the user's JDK should
73-
contain JavaFX modules (e.g., a Liberica Full JDK) or the build will need
74134
to download platform-specific JavaFX artifacts (handled by Maven profiles in
75-
the `pom.xml`).
76-
77-
### Installation
78135

79136

80137
1. Clone or download the repository
81-
82138
2. Navigate to the project directory
83-
84139
3. Build the project:
85140

86141
````bash
87142
mvn clean package
88-
89143
```
90-
91144
### Running the Application
92145

93146
Using Maven:

docs/JPACKAGE.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ Example for Windows MSI (run on Windows host):
5555

5656
For ARM64 MSI you would pass `--runtime-image C:\path\to\runtime-arm64` (and run jpackage on a Windows host or produce a Windows-compatible runtime image accordingly).
5757

58+
### Recommended JVM & JavaFX builds
59+
60+
- Use a HotSpot JDK (we recommend Eclipse Temurin) for `jlink` and `jpackage` — HotSpot builds are the most commonly tested and are known to work well with JavaFX. Some OpenJ9 builds have shown native compatibility issues with JavaFX rendering or native libraries.
61+
- Download JavaFX SDK/jmods that exactly match the `javafx.version` in `pom.xml` (for example `21.0.2`). Use the platform-specific `jmods` or platform jars for the target OS/arch.
62+
- When creating runtime images, use the JDK that matches the target architecture (x64 vs arm64) and include `java.desktop` and `java.management` modules if your app uses AWT/Swing interop or management APIs.
63+
5864
## CI recommendations
5965

6066

@@ -69,6 +75,24 @@ For ARM64 MSI you would pass `--runtime-image C:\path\to\runtime-arm64` (and run
6975

7076
- If an MSI fails to install on a target arch, verify the runtime image architecture matches the target and that the app's native libraries (JavaFX) were built for that arch.
7177

78+
- **AWT / Accessibility startup error**: On some Windows systems the bundled launcher may attempt to load the Java Accessibility Access Bridge (`com.sun.java.accessibility.AccessBridge`) which is not always present in minimal runtime images. When the AWT Toolkit attempts to load configured assistive technologies and the AccessBridge class is missing, startup can fail with an `AWTError: Assistive Technology not found: com.sun.java.accessibility.AccessBridge`.
79+
80+
- Quick workaround (recommended for most builds): instruct the JVM to skip assistive-technology lookups by adding the JVM option:
81+
82+
```text
83+
-Djavax.accessibility.assistive_technologies=
84+
```
85+
86+
When using `jpackage` this should be included as a `--java-options` argument so generated launchers include the property. Example (snippet from this project's `pom.xml`):
87+
88+
```text
89+
--java-options -Djavax.accessibility.assistive_technologies=
90+
```
91+
92+
- Alternative: if you require full Access Bridge support, bundle the AccessBridge classes and native bits in the runtime image and enable them explicitly. This increases runtime size and complexity and is only needed for systems that rely on the Access Bridge.
93+
94+
- Note: This project's `README.md` and `pom.xml` are updated to include this `--java-options` by default for the Windows `jpackage` steps.
95+
7296
## References
7397
7498
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
Packaging verification — latest run (2025-12-02)
2+
3+
Summary
4+
5+
- Installer MSI produced: `target/jpackage-msi/GraphDigitizer-1.1.msi` — present
6+
- App-image folder: `target/jpackage/GraphDigitizer` — not present in this run (the `jpackage` step removed the folder before MSI creation)
7+
- jlink runtime image used for packaging: `target/jlink-image` — present
8+
- Key diagnostic logs captured during the process:
9+
- `target/jlink-driver/app-run3.log` (detailed JavaFX startup logs)
10+
- `target/jlink-native-debug.log` (native debug flags output)
11+
- `target/jlink-driver/run.log` (launcher driver run log)
12+
13+
Where artifacts live
14+
15+
- jlink runtime image: `target/jlink-image`
16+
- jpackage app-image (if preserved): `target/jpackage/GraphDigitizer`
17+
- installer MSI: `target/jpackage-msi/GraphDigitizer-1.1.msi`
18+
- staged jpackage input (app + libs): `target/jpackage-input/` (contains `graph-digitizer.jar` and `lib/*.jar`)
19+
20+
Next steps you can request
21+
22+
- "Re-run packaging and keep app-image" — re-run `mvn -DskipTests package -Pnative` but skip the cleanup step so the `app-image` folder remains under `target/jpackage/GraphDigitizer` (I can do this and then list its contents).
23+
- "Build and sign MSI" — run the packaging and then apply codesigning (requires access to a signing certificate).
24+
25+
Commands used to reproduce the run
26+
27+
1) Build + prepare jpackage input and run jpackage profile:
28+
29+
```powershell
30+
mvn -DskipTests package -Pnative
31+
```
32+
33+
2) Create the jlink runtime image (example used in this run):
34+
35+
```powershell
36+
& 'C:\Program Files\Eclipse Adoptium\jdk-21.0.9.10-hotspot\bin\jlink.exe' \
37+
--strip-debug --no-man-pages --no-header-files \
38+
--add-modules java.desktop,java.management,java.logging,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,javafx.swing \
39+
--module-path 'C:\Program Files\Eclipse Adoptium\jdk-21.0.9.10-hotspot\jmods;C:\javafx-jmods-21.0.9' \
40+
--output target/jlink-image
41+
```
42+
43+
3) Run the packaged app against the created runtime for verification (expanded classpath):
44+
45+
```powershell
46+
$cp = (Get-ChildItem .\target\jpackage-input\lib -Filter *.jar | ForEach-Object { $_.FullName }) -join ';'
47+
& .\target\jlink-image\bin\java \
48+
"-Djava.library.path=$PWD\target\jlink-image\bin;$PWD\target\jlink-image\bin\javafx" \
49+
"-Dprism.verbose=true" "-Djavafx.verbose=true" \
50+
-cp "$PWD\target\jlink-driver\bin;$PWD\target\jpackage-input\graph-digitizer.jar;$cp" \
51+
com.digitizer.ui.GraphDigitizerApp 2>&1 | Tee-Object .\target\jlink-driver\app-run3.log
52+
```
53+
54+
Notes
55+
56+
- The `pom.xml` in the `native` profile was updated to copy runtime-scoped dependencies into `target/jpackage-input/lib` and to pass `--runtime-image ${project.build.directory}/jlink-image` to `jpackage`.
57+
- If you'd like, I can re-run packaging to preserve the `app-image` folder and then enumerate its contents and sizes.

0 commit comments

Comments
 (0)