Javaをスクリプト言語っぽくするJBangその3です。今回はSpringBootを起動してみようと思います。その1
、その2
の内容は説明しませんので、下記からみてください。
想定シナリオ
ちょっとSpringBootとかで試したいことがあるときやAPIサーバの挙動とかを軽くテストしたいときに使う感じです。モノリスなどで大きい場合はちょっとした検証をするにもDBやRedisなどが必要になったり、ユニットテストを書かないといけなかったりちょっと面倒です。それをJBangが解決してくれます。
成果物
成果物は下記になります。一つずつ説明します。(追加説明を希望の場合はコメントにお願いします。)
Gistにもあげておきます。
https://gist.github.com/ko-sasaki/f38dfe9fc7146268520cf72f333565e5
///usr/bin/env jbang "$0" "$@" ; exit $? package api; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; //JAVA 21+ //DEPS org.springframework.boot:spring-boot-starter-web:3.5.0 //FILES application.yml //REPOS central,jitpack,google @SpringBootApplication @RestController public class SpringBootSample { @Value("${sample.message}") private String message; public static void main(String[] args) { SpringApplication.run(SpringBootSample.class, args); } /** * 固定メッセージを返却する. */ @GetMapping("/hello") public String hello() { return "Hello, World!"; } /** * URLパスで指定された文字列でメッセージを置換して返却する. */ @GetMapping("/hello/{name}") public String hello(@PathVariable String name) { return "Hello, {name}!".replace("{name}", name); } /** * application.ymlのメッセージを表示する */ @GetMapping("/hello/message") public String message() { return message; } }
application.yml
の中身は下記
server: port: 8081 sample: message: Hello, Application Yaml!
ファイル作成
jbang init
を使用して新規にファイルを作成します。
jbang init api/SpringBootSample.java
上記でファイルが作成されます。
パッケージ設定
SpringBootはルートパッケージですとDB設定などが動きだしてしまうので、テスト用のパッケージを指定します。
package api;
Javaバージョン
Java21以上で動作するように設定します。
//JAVA 21+
Javaがインストールされていない場合は下記のコマンドを入力してみてください。
// JBangを使用する場合 jbang jdk install 21 or // SDKMANを使用する場合 sdk install java 21.0.7-tem
依存関係
SpringBootをAPIサーバとして動かすのはこの1行だけで十分になります。
//DEPS org.springframework.boot:spring-boot-starter-web:3.5.0
なんかすごいですよね。この1行だけでSpringBootが起動できるなんて。
ファイル
//FILES
で起動時に読み込むファイルを指定する。
//FILES application.yml
Javaコード
Javaコードの部分は、SpringBootのRestController
のときに書くものを1ファイルにまとめたものです。いくつかのパターンで書いてあります。
@SpringBootApplication @RestController public class SpringBootSample { @Value("${sample.message}") private String message; public static void main(String[] args) { SpringApplication.run(SpringBootSample.class, args); } @GetMapping("/hello") public String hello() { return "Hello, World!"; } @GetMapping("/hello/{name}") public String hello(@PathVariable String name) { return "Hello, {name}!".replace("{name}", name); } @GetMapping("/hello/message") public String message() { return message; } }
実行
Webアプリケーションでも実行方法は変わりません。下記のコマンドで実行します。
$jbang api/SpringBootSample.java [jbang] Building jar for SpringBootSample.java... . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.5.0) 2025-06-14T10:11:49.229+09:00 INFO 60388 --- [ main] api.SpringBootSample : Starting SpringBootSample using Java 21.0.7 with PID 60388 (/Users/kohei.sasaki/.jbang/cache/jars/SpringBootSample.java.be468baacb1ab8033bb744d7e1c4d7073e1736db3075b9bb1af7e20d0c22a440/SpringBootSample.jar started by kohei.sasaki in /Users/kohei.sasaki/git/jbang-sample) 2025-06-14T10:11:49.230+09:00 INFO 60388 --- [ main] api.SpringBootSample : No active profile set, falling back to 1 default profile: "default" 2025-06-14T10:11:49.664+09:00 INFO 60388 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8081 (http) 2025-06-14T10:11:49.674+09:00 INFO 60388 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2025-06-14T10:11:49.674+09:00 INFO 60388 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.41] 2025-06-14T10:11:49.706+09:00 INFO 60388 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2025-06-14T10:11:49.706+09:00 INFO 60388 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 449 ms 2025-06-14T10:11:49.911+09:00 INFO 60388 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8081 (http) with context path '/' 2025-06-14T10:11:49.917+09:00 INFO 60388 --- [ main] api.SpringBootSample : Started SpringBootSample in 0.938 seconds (process running for 1.114) 2025-06-14T10:12:09.050+09:00 INFO 60388 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2025-06-14T10:12:09.050+09:00 INFO 60388 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2025-06-14T10:12:09.050+09:00 INFO 60388 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms
これで起動完了です。
curlコマンドでテストしてみます。
$ curl localhost:8081/hello Hello, World! $ curl localhost:8081/hello/hogehoge Hello, hogehoge! $ curl localhost:8081/hello/message Hello, Application Yaml!
ちゃんと期待したものが応答されました。
Gistを経由してのコード共有
上記のコードをGistにあげておきます。jbangコマンドにGistのURLを指定すると自動でダウンロードして、依存解決をして実行してくれます。とても便利です。
$ jbang https://gist.github.com/ko-sasaki/f38dfe9fc7146268520cf72f333565e5 . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.5.0) 2025-06-14T14:50:06.953+09:00 INFO 6158 --- [ main] api.SpringBootSample : Starting SpringBootSample using Java 21.0.7 with PID 6158 (/Users/kohei.sasaki/.jbang/cache/jars/SpringBootSample.java.6ed9516f48ab6c188d73ce5f1a848c811e4640775b1e8eea6cc1305d8c9a6c69/SpringBootSample.jar started by kohei.sasaki in /Users/kohei.sasaki/git/jbang-sample) 2025-06-14T14:50:06.954+09:00 INFO 6158 --- [ main] api.SpringBootSample : No active profile set, falling back to 1 default profile: "default" 2025-06-14T14:50:07.358+09:00 INFO 6158 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8081 (http) 2025-06-14T14:50:07.368+09:00 INFO 6158 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2025-06-14T14:50:07.368+09:00 INFO 6158 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.41] 2025-06-14T14:50:07.395+09:00 INFO 6158 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2025-06-14T14:50:07.395+09:00 INFO 6158 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 415 ms 2025-06-14T14:50:07.574+09:00 INFO 6158 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8081 (http) with context path '/' 2025-06-14T14:50:07.579+09:00 INFO 6158 --- [ main] api.SpringBootSample : Started SpringBootSample in 0.846 seconds (process running for 1.019)
とても簡単ですね。
プロジェクトに変換する
ここまでプロジェクトができたら、jbangではなく通常のプロジェクトに変換したくなってきます。JBangではexport
コマンドがあり、それを実現できます。exportのコマンドはExecutableJar形式、Gradle形式、Maven形式など色々な形式で出力できます。今回はGradle形式で出力してみます。
$ jbang export gradle --output export_dir api/SpringBootSample.java
export_dir
のディレクトリの中身をみてみます。
$ tree export_dir export_dir/ ├── build.gradle └── src └── main ├── java │ └── api │ └── SpringBootSample.java └── resources └── application.yml
jbangで書いた構成がそのまま出力されています。build.gradleも生成されており、実際にビルドや実行などができます。
まとめ
JBangでSpringBootのWebアプリケーションサーバの起動がすぐできました。Gist経由でコードの共有や実行まで確認できたり、exportコマンドでスムーズにプロジェクトに昇格できるようになっています。プロダクトエンジニアのことがよくわかっている、かなり気が利いているツールになっています。エコシステムとしても既存のものを最大限フル活用しており、独自仕様のようなものがコンパクトにまとまっています。チーム内でも広めたいですし、Javaエンジニアのみならず、Java初学者の方がもっと使ってくれたらと思います。
次回はAI系またはデバッグについて書こうと思います。