Shammer's Philosophy

My private adversaria

Accessing tomcat8 application but received Unsupported major.minor version 52.0

I build war application first time in age, but response is not expected the one, but UnsupportedClassVersionError.

$ curl http://10.255.230.2:8080/myapp/defaultServlet
<!DOCTYPE html><html><head><title>Apache Tomcat/8.0.14 (Debian) - Error report</title><style type="text/css">H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}.line {height: 1px; background-color: #525D76; border: none;}</style> </head><body><h1>HTTP Status 500 - jp/me/MyServlet : Unsupported major.minor version 52.0 (unable to load class jp.me.MyServlet)</h1><div class="line"></div><p><b>type</b> Exception report</p><p><b>message</b> <u>jp/me/MyServlet : Unsupported major.minor version 52.0 (unable to load class jp.me.MyServlet)</u></p><p><b>description</b> <u>The server encountered an internal error that prevented it from fulfilling this request.</u></p><p><b>exception</b></p><pre>java.lang.UnsupportedClassVersionError: jp/me/MyServlet : Unsupported major.minor version 52.0 (unable to load class jp.me.MyServlet)
	org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2476)
	org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:853)
	org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1263)
	org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1146)
	org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:494)
	org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
	org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
	org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537)
	org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1081)
	org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
	org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
	org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1580)
	org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1537)
	java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
	java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:622)
	org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	java.lang.Thread.run(Thread.java:748)
</pre><p><b>note</b> <u>The full stack trace of the root cause is available in the Apache Tomcat/8.0.14 (Debian) logs.</u></p><hr class="line"><h3>Apache Tomcat/8.0.14 (Debian)</h3></body></html>

This is caused by java version difference, the version of JavaVM running as tomcat8 on my DebianVM is 1.7.0_151, but the version of JavaVM on my Mac that is build environment is 1.8.0_144.

This can be resolved using --target and --source option of javac. I change my ant task like below.

  <target name="compile" depends="cleanup">
    <javac srcdir="${dir.src}" destdir="${dir.classes}" executable="${compiler}" includeantruntime="false" target="7" source="7">
      <classpath refid="classpath.tomcat" />
    </javac>
  </target>

Added target attribute and source attribute.

git pull automation on High Sierra

This is required 2 files at least, one is the script to run git pull, and the other is the plist file to invoke the script. Procedure is below.

  1. Generate the script
  2. Generate the plist file in $HOME/Library/LaunchAgent

script sample

#!/bin/bash
while true;
do
    GW_CHECK=`netstat -rn -f inet | grep default | wc -l`;
    if [ 1 -eq $GW_CHECK ];then
	break;
    else
	sleep 1;
    fi
done

ping -c 1 bitbucket.org > /dev/null
if [ $? -eq 0 ];then
    ST="$HOME/Sites";
    WK="$HOME/Workspace";
    array=("$ST/repo1" "$ST/repo2" "$ST/repo3" "$WK/repo1" "$WK/repo2" "$WK/repo3" "$WK/repo4" "$WK/repo5" "$WK/repo6");
    for repository in ${array[@]};
    do
	cd $repository;
	echo "git pull in $repository...";
	git pull;
    done
    exit 0;
else
    echo "ping to bitbucket.org failed."
    exit 1;
fi

There is a possibility that Wifi setup wouldn't be completed at the time above script invoked from Launch Agent, so I add an operation to check network reachability.

plist sample

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE plist PUBLIC "-//Apple//DTDPLIST1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 
<plist version="1.0"> 
  <dict> 
    <key>Label</key> 
    <string>pull.from.bitbucket</string> 
    <key>UserName</key> 
    <string>aaa</string> 
    <key>GroupName</key> 
    <string>staff</string> 
    <key>ProgramArguments</key> 
    <array> 
      <string>/Users/aaa/bin/pull-from-bitbucket.sh</string> 
    </array> 
    <key>StandardOutPath</key> 
    <string>/Users/aaa/pull-from-bitbucket.stdout</string> 
    <key>StandardErrorPath</key> 
    <string>/Users/aaa/pull-from-bitbucket.stderr</string> 
    <key>RunAtLoad</key> 
    <true/> 
  </dict> 
</plist>

ANAダイナースカード改悪

ANAダイナースのみでなく、ダイナースカード全体のことと思うが。数日前からオンラインサービスサイトで、システムの移行が予定されていると掲載されていたが、この移行のタイミングでポイントの換算方法についても変更があるということが本日到着の書類で判明した。具体的には、

  • これまでは月間の累計利用金額全体に対して、100円で1ポイント換算
  • 今後は、カード利用のたびに100円で1ポイント換算

に変更される。他にも変更はあるが、個人的に改悪と感じるのはこの点だけ。他は「はい、そうですか」で終了するレベル。カードの利用頻度が多い人ほどこの影響は大きいと思う。極端な話、199円の買い物を決済した場合はポイント付与率は約50%になってしまう。そもそも、去年の夏にVISAからダイナースにしよう、という一番の動機が、月間の利用金額/100というポイントシステムだったのに、入会数ヶ月にしてこのシステムが変わるとは・・・もうこれは再度カード選定をしなければならないくらいの気持ちになっている。
もう月間の合計利用金額に対して、100円で1ポイントというポイント体系のANAカードは存在しない認識。利用ごとに100円1ポイント(AMEX/DINERS)か、1000円ごとに1ポイント(VISA、ソラチカ等)のいずれか。自分はマイルをスカイコインにして飛行機代に使用するという使い方なので、スカイコインに変換する際の倍率も重要。1.6倍で換算できるゴールド以上は必須。そうすると、JCB/VISA/Master/AMEX/DINERSのいずれかだが、AMEX/DINERSは利用金額100円で1ポイントなので除外(たまにしか使わないカードならこれでも十分だが、月に60回くらい利用するカードがこれだともったいない)なので、JCB/VISA/Masterだ。でも、、、VISAは解約したばかりでなんとなく申し込みにくい。こんなことならもう数日待っていればよかった。Masterも三井住友みたいだから第一候補はJCBか。ソラチカにゴールドがあればそれで決定なのだが。
と、いろいろ思うところを書いているが、今回の変更で失われるであろうポイントも全体で見れば大したポイントにはならないんだよなあ。。。月に60回の利用として、その利用金額が全てXX99円とかとしたら、99X60=5940円、ポイントにして59ポイント分、年間12X59=708ポイント。スカイコインにしたとして70X1.6=1132.8。年間1132円分の旅行代金のためにこんな損した気分になる自分って一体・・・。いや、銀行預金でも年間の金利が1000円越えることの方がない昨今、この差は大きいだろう。人間、悪くなると感じることについては敏感なものなのだ。そういうことにしておこう。

やっぱりKarabinerは必要かも

AquaSKK with Karabiner 環境でスラッシュがShift扱いに? - Shammerismで、AquaSKKキーバインドは/Library/Input Methods/AquaSKK.app/Contents/Resources/keymap.confで編集できることがわかった。書式はAquaSKK Wiki - AquaSKK - OSDNの「keymap.confの文法」を参考にして

EnterAbbrev		group::f,j

EnterAbbrev		group::fj

など、いろいろ試してみたがFとJを同時にタイプすることで変換モードにするようにはできなかった。やはり、これはKarabinerなどの別アプリでSticky Shiftを有効にしておかないとできなそうだ。

AquaSKK with Karabiner 環境でスラッシュがShift扱いに?

AquaSKKで日本語入力モードの際に、FとJの同時タイプで漢字変換扱い(Shiftモード)にするようにKarabinarのオプション - Shammerismで設定したが、意識していなかったがスラッシュを入力したときにも変換扱いになってしまっていた。そのため、スラッシュを入力したいときはいつも日本語入力モードをオフにしていたが、ふと、なぜこんな動作なのかが気になって調べてみた(ちなみに、英語キーボード環境)。
最初は、Karabinerのどこかでそういう設定をしているのでは?と確認してみたが、スラッシュの挙動を変更するような設定は何もない。どうやらKarabinerは関係なく、AquaSKKが怪しいということで確認してみた。
実際、AquaSKKで定義されていた。AquaSKKのキー割り当ては、

/Library/Input Methods/AquaSKK.app/Contents/Resources

というディレクトリのkeymap.confに定義されているらしい。この中でスラッシュについてのものがあった。

EnterAbbrev		/

という行をコメントアウトして再起動することで問題は解消された。スラッシュの入力が格段に楽になった。でも、どういう意味なんだろうか。Abbrevは辞書によればabbreviatedの略で、短縮や省略とかいう意味があるらしいが。ひらがなを短縮(?)して漢字にする、ということだろうか。
それはさておき、Karabinerを使用してShiftと同様のキーをFとJの同時押しに割り当てたが、このファイルをうまく編集することでも実現できたのかもしれないが、、、便利なソフトなのでこのままにしておこう。

VPS Cloud 申し込み停止中・・・

独自ドメイン運用のため、DNSサーバーとして動作させるVPSサービスを検索していて、NTTコミュニケーションズのものが月額360円で利用できるようでいいと思っていたが、、、在庫を確保できないらしく申し込み停止となっていた。
トップページのリンクはここだが、「申し込みはこちら」などのリンクをクリックしても受付停止のページに転送されてしまう。この金額でできるのは魅力なのだがしばらく待つことになりそうだ。

Numbers SUMIFS doesn't calc if the range is other sheet

I use SUMIFS function on my Mac Numbers. I wrote about this function in How to calculate summary with a condition on Numbers of Mac? - Shammerism, but I faced with the case SUMIFS doesn't calc if the range is not in the same sheet.
SUMIFS requires the calc range as below, quoted from How to calculate summary with a condition on Numbers of Mac? - Shammerism.

=SUMIFS(SheetB :: C,SheetB :: D,"=20171210")

I understood that SUMIFS requires Sheet Name if range is in other sheet. So I define the SUMIFS with using Sheet Name. But, it is not correct.
I always create sheet if I want to add a new table, so my Numbers file has sheets which has only 1 table. I am used to this style, like Microsoft Excel.
But, Numbers is different from Excel, sheet name and table name are different. SUMIFS requires Table Name instead of Sheet Name. The syntax of it should be below.

=SUMIFS(TableB :: C,TableB :: D,"=20171210")