mike-neckのブログ

Java or Groovy or Swift or Golang

OpenShiftでTwitter4jアプリ作った時に出たNoSuchAlgorithmExceptionの解決法 #openshift #twitter4j

定期的にツイートさせるbotを作ろうとして、herokuで定期的に叩き起こして定期的にツイートさせるようにしようと検討していたんだけど、どうやらweb dynoが12時間/dayしか動けなくなったっぽいので、OpenShiftで実現することにした。

で、初回のスケジュールタスク起動時に次のエラーが発生しました(´・ω・`)

TwitterException{exceptionCode=[2fc5b7cb-11613e17 2fc5b7cb-11613ded], statusCode=-1, message=null, code=-1, retryAfter=-1, rateLimitStatus=null, version=4.0.3} 
        at twitter4j.HttpClientImpl.handleRequest(HttpClientImpl.java:179) 
...

これの原因が、これ

java.security.NoSuchAlgorithmException: EC AlgorithmParameters not available

で、これをそのままググったら、もろそのままのタイトルでOpenJDK on OpenShift: “NoSuchAlgorithmException: EC AlgorithmParameters not available”があったので、それの解決策をコピペ。

  1. rhc ssh app-namesshでOpenShiftへログイン
  2. cd $OPENSHIFT_DATA_DIRでなんか.bash_profileとかがあるディレクトリーに移動
  3. vim override_security.propertiesで、新規ファイルを作成して、中身にjdk.tls.disabledAlgorithms=EC,ECDHE,ECDHを記述
  4. pwdして、現在のパスを取得して、上記のoverride_security.propertiesを加えてメモっておく
  5. exitしてOpenShiftからログアウト
  6. rhc env set JAVA_OPTS_EXT=-Djava.security.properties=file:さっきのメモのパス -a app-nameを実行
  7. rhc app restart -a app-nameを実行して、アプリを再起動

これで、動きました。

ちなみに、上記のツイートするコードはこんな感じ。

@Stateless
@Startup
public class LetsSleep {

    @Inject
    private ZoneId zone;

    @Inject
    private Twitter twitter;

    @Inject
    @OnlyHour
    private DateTimeFormatter formatter;

    @Schedule(minute = "00", hour = "23", dayOfWeek = "Sun-Thu", timezone = "Asia/Tokyo", persistent = false)
    public void say() throws TwitterException {
        twitter.updateStatus(sentence(EndSentence.random()));
    }

    String sentence(EndSentence sentence) {
        LocalDateTime now = LocalDateTime.now(zone);
        String f = formatter.format(now);
        return String.format("@mike_neck [bot] %sだよ%s。" +
                sentence.getMessage(), f, f);
    }

    enum EndSentence {
        Tomorrow("そろそろ寝ないと、明日の朝起きられないよ!"),
        ToBed("わたし、先に寝るよ"),
        Regret("明日おきれなくても、わたし知らないよ!"),
        Concentration("こんな時間に頑張ったって、たかが知れてるんだから、明日がんばろ?");

        private final String message;

        EndSentence(String message) {
            this.message = message;
        }

        String getMessage() {
            return message;
        }

        static EndSentence random() {
            EndSentence[] values = values();
            return values[new Random().nextInt(values.length)];
        }
    }

    public void setZone(ZoneId zone) {
        this.zone = zone;
    }

    public void setTwitter(Twitter twitter) {
        this.twitter = twitter;
    }
}

結論

Javaプログラマーはherokuでいろいろハックするより、Java EEちゃんと身につけてOpenShift使うのもありかもしれんよ。(ただし、日本語情報が多いとは言っていない)


【追記】

OpenShiftのログイン画面chromeからつながらない問題

があって、issue登録したんだけど、どうやらduplicateだったらしく、closedにされた上、duplicate先のissue見れなくて、大丈夫なんかなと思ってたら、案の定

RedHatさん頑張って!