{"id":15069241,"url":"https://github.com/sormuras/jigsaw-quick-start","last_synced_at":"2026-02-21T09:01:56.718Z","repository":{"id":248702656,"uuid":"814111581","full_name":"sormuras/jigsaw-quick-start","owner":"sormuras","description":"https://openjdk.org/projects/jigsaw/quick-start","archived":false,"fork":false,"pushed_at":"2025-07-15T05:40:21.000Z","size":55,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-15T12:18:38.340Z","etag":null,"topics":["java","jdk","modules","tools"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sormuras.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-06-12T11:10:04.000Z","updated_at":"2025-07-15T05:40:24.000Z","dependencies_parsed_at":"2024-08-12T08:27:40.867Z","dependency_job_id":"92ba5bdd-ec61-4381-b072-78d8b9253734","html_url":"https://github.com/sormuras/jigsaw-quick-start","commit_stats":null,"previous_names":["sormuras/jigsaw-quick-start"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sormuras/jigsaw-quick-start","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sormuras%2Fjigsaw-quick-start","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sormuras%2Fjigsaw-quick-start/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sormuras%2Fjigsaw-quick-start/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sormuras%2Fjigsaw-quick-start/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sormuras","download_url":"https://codeload.github.com/sormuras/jigsaw-quick-start/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sormuras%2Fjigsaw-quick-start/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29677881,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T06:23:40.028Z","status":"ssl_error","status_checked_at":"2026-02-21T06:23:39.222Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","jdk","modules","tools"],"created_at":"2024-09-25T01:41:16.791Z","updated_at":"2026-02-21T09:01:56.682Z","avatar_url":"https://github.com/sormuras.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Jigsaw Quick-Start Revisited\n\nThis project uses the example from the [Project Jigsaw Quick-Start] guide to show a 100% Java build\nsetup: the following shell commands are transformed into platform-agnostic Java code.\n\n```text\n$ javac -d mods --module-source-path src $(find src -name \"*.java\")\n$ jar --create --file=mlib/org.astro@1.0.jar --module-version=1.0 -C mods/org.astro .\n$ jar --create --file=mlib/com.greetings.jar --main-class=com.greetings.Main -C mods/com.greetings .\n$ java -p mlib -m com.greetings\n\nGreetings world!\n```\n\n## Back to Basics\n\nUse command-line tools as primitives and express logic in Java programs.\n\nCreate a Java program for each action:\n\n```\nb0/src/\n    Build.java\n    Clean.java\n    Rebuild.java\n    Start.java\n```\n\nFor example, `Start.java` can be implemented like this:\n\n```java\npublic class Start {\n    public static void main(String... args) {\n        var out = Path.of(\"b0\", \"out\");\n        if (!Files.isDirectory(out)) {\n            run(\"java\", Path.of(\"b0\", \"src\", \"Build.java\").toString());\n        }\n        run(\"java\", \"--module-path=\" + out.resolve(\"modules\"), \"--module=com.greetings\");\n    }\n}\n```\n\nRun actions directly from within an IDE or on the shell via the `java` launcher:\n\n```shell\njava b0/src/Start.java\n```\n\nThis is possible due to \"[JEP 330](https://openjdk.org/jeps/330): Launch Single-File Source-Code\nPrograms\" introduced in Java 11.\n\nNote that the `java` launcher is used as a tool to trigger other actions.\n\n## Better Basics\n\nWith the help of \"[JEP 458](https://openjdk.org/jeps/458): Launch Multi-File Source-Code Programs\"\nit is possible to centralize common properties and methods.\n\nIntroduce `Project` record as a central place to organize common properties and all action methods.\n\n```java\nrecord Project(Path out) {\n    void start() {\n        if (!Files.isDirectory(out)) { // Use instance record component `out`\n            build(); // Invoke same-class sibling method `build()`\n        }\n        run(\"java\", \"--module-path=\" + out.resolve(\"modules\"), \"--module=com.greetings\");\n    }\n    // Here be more methods: build(), clean(), rebuild(), ...\n}\n```\n\nModify action programs to create and work on an instance of `Project`.\n\n```java\npublic class Start {\n    public static void main(String... args) {\n        Project.ofCurrentWorkingDirectory().start();\n    }\n}\n```\n\nWith \"[JEP 512](https://openjdk.org/jeps/512): Compact Source Files and Instance Main Methods\" those\nentry-point programs like `Start.java` can be reduced to:\n\n```java\nmain() {\n    Project.ofCurrentWorkingDirectory().start();\n}\n```\n\n## Extract Model and Actions\n\nLet the `Project` record compose desired traits.\n\nMove common project properties into components of a `Model` record — which in turn is composed of\nnested records like `Folders`.\n\nThe `Action` interface defines an accessor to an instance of `Model`.\n\nWrap actions with custom code by overriding default methods.\nWrapping custom code around those action methods is achieved by overriding them,\nrendering explicit and empty `startBefore()` and `startAfter()` methods redundant.\n\n```java\nrecord Project(Model model) implements Builder, Cleaner, Starter {\n    static Project ofCurrentWorkingDirectory() {\n        return new Project(Model.of(\"b2\"));\n    }\n\n    @Override\n    public void start() {\n        // \u003c-- before start\n        if (!Files.isDirectory(model.folders().out())) {\n            build(); // Builder.this.build();\n        }\n        Starter.super.start();\n        // --\u003e after start\n    }\n}\n```\n\n## Define extension points for configuration.\n\n[Extension Points](b3) Introduce command-line abstractions and extension points for configuration.\n\nAction interfaces (`Starter`) define a single method as their main purpose (`start()`).\n\n\nAction interface may also define functions as overridable extension points to let a project\nconfigure the behaviour.\n\nNames of such extension point functions should start with their interface name.\nThis naming convention helps to override right extension point and the prevents name clashes with\nother actions.\n\n```java\npublic interface Starter extends Action, Builder {\n}\n```\n\n## Tool Time\n\n- [Tool Time](b4) Improve tooling support.\n\n## Tool's Trifecta\n\n- [Tool's Trifecta](b5) ToolFinder - ToolRunner - ToolCall\n\n## Externals\n\n- [External Tools](b6) Install external tools.\n- [External Modules](b7) Import external modules.\n\n[Project Jigsaw Quick-Start]: https://openjdk.org/projects/jigsaw/quick-start\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsormuras%2Fjigsaw-quick-start","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsormuras%2Fjigsaw-quick-start","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsormuras%2Fjigsaw-quick-start/lists"}