【Spark Framework】Spark Framework + args4j を使ってコマンドライン引数から設定値を変更

■ はじめに

 コマンドライン引数のパーサー である args4j を使って、
ポートなどのSpark Frameworkの設定値を変更する。

 なお、 args4j については、以下の関連記事を参照のこと。
https://blogs.yahoo.co.jp/dk521123/37206429.html

■ 前提条件

https://blogs.yahoo.co.jp/dk521123/37204914.html
のように設定されていること

■ 環境設定

 * 以下の「build.gradle」を参考に、args4jを追加し、
   Eclipseの対象プロジェクトを右クリックし、[Gradle]-[Refresh Gradle Project]を選択
build.gradle
dependencies {
    # 途中略

    compile 'com.sparkjava:spark-core:2.7.0'
    compile 'org.slf4j:slf4j-simple:1.7.25'
    compile 'com.google.code.gson:gson:2.8.2'
    compile 'args4j:args4j:2.33' # args4j の追加

    // Use JUnit test framework
    testImplementation 'junit:junit:4.12'
}

■ サンプル

DemoService.java

package com.sample.spark;

import com.google.gson.Gson;
import com.sample.spark.controllers.HelloWorldController;

import spark.Service;

public class DemoService {
  public static void main(String[] args) {
    ServiceConfig config = ServiceConfig.create(args);
    DemoService sparkService = new DemoService(config);
    sparkService.initialize();
  }

  private Service service;

  private DemoService(ServiceConfig config) {
    this.service = Service.ignite().port(config.getPort()).threadPool(config.getMaxThreads());
  }

  public void initialize() {
    Gson gson = new Gson();
    HelloWorldController controller = new HelloWorldController();

    this.service.get("/", controller::getPeople, gson::toJson);
  }
}

ServiceConfig.java

package com.sample.spark;

import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;

public class ServiceConfig {
  private static final int DEFAULT_PORT = 4567;
  private static final int DEFAULT_MAX_THREADS = 6;
  private static final boolean DEFAULT_IS_DEBUG = false;
  
  @Option(name = "-p", aliases="--port", required=false, usage="Port this server listens on")
  private int port;
  
  @Option(name = "-t", aliases="--threads", required=false, usage="Max Threads")
  private int maxThreads;
  
  @Option(name="-d", aliases="--debug", required=false, usage="debug option")
  private boolean isDebug;
  
  private ServiceConfig() {
    this.port = DEFAULT_PORT;
    this.maxThreads = DEFAULT_MAX_THREADS;
    this.isDebug = DEFAULT_IS_DEBUG;
  }
  
  public int getPort() {
    return this.port;
  }
  public void setPort(int port) {
    this.port = port;
  }
  
  public int getMaxThreads() {
    return this.maxThreads;
  }
  public void setMaxThreads(int maxThreads) {
    this.maxThreads = maxThreads;
  }
  
  public boolean isDebug() {
    return this.isDebug;
  }
  public void setDebug(boolean isDebug) {
    this.isDebug = isDebug;
  }
  
  public static ServiceConfig create(String[] args) {
    if (args == null || args.length == 0) {
      return new ServiceConfig();
    }
    
    try {
      ServiceConfig serviceConfig = new ServiceConfig();
      CmdLineParser parser = new CmdLineParser(serviceConfig);
      parser.parseArgument(args);
      return serviceConfig;
    } catch (CmdLineException ex) {
      return new ServiceConfig();
    }
  }
}

HelloWorldController.java

package com.sample.spark.controllers;

import java.util.ArrayList;
import java.util.List;

import com.sample.spark.models.Person;

import spark.Request;
import spark.Response;

public class HelloWorldController {
  public List<Person> getPeople(Request request, Response response) {
    List<Person> people = new ArrayList<>();
    people.add(new Person(1L, "Mike"));
    people.add(new Person(2L, "Tom"));
    people.add(new Person(3L, "Kevin"));
    return people;
  }
}

Person.java

package com.sample.spark.models;

public class Person {
  private long id;
  private String name;
  
  public Person(long id, String name) {
    this.id = id;
    this.name = name;
  }
  
  public long getId() {
    return id;
  }
  public void setId(long id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
}

動作確認

[1] 引数として、例えば、
-p 18080 -t 10 --debug
を指定する

[2] ブラウザを立ち上げて、以下のURLにアクセスする
[[http://localhost:18080]]

注意:「-t 5」を指定した場合、例外「IllegalStateException」発生

「threads: max=5 < needed」で、5より超えた数字である必要がある
[Thread-0] ERROR spark.Spark - ignite failed
java.lang.IllegalStateException: Insufficient threads: max=5 < needed(acceptors=1 + selectors=4 + request=1)
	at org.eclipse.jetty.server.Server.doStart(Server.java:414)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at spark.embeddedserver.jetty.EmbeddedJettyServer.ignite(EmbeddedJettyServer.java:130)
	at spark.Service.lambda$init$2(Service.java:504)
	at java.lang.Thread.run(Unknown Source)

関連記事

【Spark Framework】初期設定 ~ 環境構築(Gradle Project)からHello Worldまで / 新版 ~

https://blogs.yahoo.co.jp/dk521123/37204914.html

Spark Framework + GSONを使って REST API を作成する

https://blogs.yahoo.co.jp/dk521123/37203509.html

Javaコマンドライン引数のパーサー

https://blogs.yahoo.co.jp/dk521123/37206429.html