ActiveMQを停止する

bin\activemq.bat stopで止まらない

  • 以下のようなエラーが出ます。
Connecting to JMX URL: service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi
ERROR: java.lang.RuntimeException: Failed to execute stop task.
  Reason: java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.ServiceUnavailableException
  [Root exception is java.rmi.ConnectException: Connection refused to host: localhost; nested exception is:
        java.net.ConnectException: Connection refused: connect]
java.lang.RuntimeException: Failed to execute stop task.
  Reason: java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.ServiceUnavailableException
  [Root exception is java.rmi.ConnectException: Connection refused to host: localhost; nested exception is:
        java.net.ConnectException: Connection refused: connect]
        at org.apache.activemq.console.command.ShutdownCommand.runTask(ShutdownCommand.java:116)
        at org.apache.activemq.console.command.AbstractCommand.execute(AbstractCommand.java:62)
        at org.apache.activemq.console.command.AbstractJmxCommand.execute(AbstractJmxCommand.java:387)
        at org.apache.activemq.console.command.ShellCommand.runTask(ShellCommand.java:154)
        at org.apache.activemq.console.command.AbstractCommand.execute(AbstractCommand.java:62)
        at org.apache.activemq.console.command.ShellCommand.main(ShellCommand.java:104)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.apache.activemq.console.Main.runTaskClass(Main.java:262)
        at org.apache.activemq.console.Main.main(Main.java:115)
(以下略)
  • 1099ポートで制御用のRMIがいるはずなのがいないということかな。

解決方法

  • conf\activemq.xmlmanagementContextを設定すればいいらしい。
<managementContext>
    <managementContext createConnector="false"/>
</managementContext><managementContext>
    <managementContext createConnector="true"/>
</managementContext>
  • これで止まるようになりましたよ。
> bin\activemq.bat stop
Connecting to JMX URL: service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi
Stopping broker: hogehoge

自動実装するプロパティを使ってみる

C#でプロパティを書くときに特別な処理が要らなければgetter, setterを省略できるらしい

  • getter, setter書いてると冗長だし、コードが長くなって見づらくなるので書きたくない。ということで使ってみる。

よくあるprivateのフィールドとpublicのプロパティ

/// <summary>
///ルートディレクトリ
/// </summary>
private string rootPath;

/// <summary>
///ルートディレクトリ
/// </summary>
public string RootPath
{
    get { return rootPath; }
}
  • うーん、長すぎるというかこんなのがずっとつづいてると見づらいですね。

自動実装プロパティに書き換える

public static string RootPath { get; }
  • と思ったらエラーです。

    'Foo.Bar.RootPath.get' は abstract または extern に指定されていないため、本体を宣言する必要があります。自動的に実装されたプロパティは、get および set アクセサーの両方を定義する必要があります。

  • get および set アクセサーの両方を定義する必要があります。」だからですね。
  • 以下のように書きなおしたらうまくいきました。
    • もともとsetterは公開していなかったのでprivateにしています。
public static string RootPath { get; private set; }
  • getのみの自動実装プロパティがC# 6.0から使えるというのも見ましたが、自分の環境はまだVisual Studio 2012なので試してません。

Groovyからexecute()したプロセスで環境変数がうまく取れない

  • C#で書いたexeがあって、内部でEnvironment.GetEnvironmentVariable("ComSpec");してcmd.exeのフルパスを取っているのですが、何故かGroovyからexecute()した時だけ値が空白になります。

検証コード

groovy> println "cmd /c set".execute([], new File(".")).text 
 
COMSPEC=C:\Windows\system32\cmd.exe
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC
PROMPT=$P$G
SystemRoot=C:\Windows
  • あれ?もしかしてComSpecCOMSPECって全部大文字に変わってるからかな?
C:\>set
ALLUSERSPROFILE=C:\ProgramData
ChocolateyInstall=C:\ProgramData\chocolatey
CommonProgramFiles=C:\Program Files\Common Files
ComSpec=C:\Windows\system32\cmd.exe
以下略
  • うーんそうかも。

execute()環境変数を渡せそうなので渡してみる

  • ここを参考にやってみる。

[http://npnl.hatenablog.jp/entry/20110325/1301006575#Process_execute_String_ary_envp_File_dir:embed:cite]

groovy> def env = System.getenv() 
groovy> def envList = env.collect { "$it.key=$it.value" } 
groovy> println "cmd /c set".execute(envList, new File(".")).text 
 
ALLUSERSPROFILE=C:\ProgramData
ChocolateyInstall=C:\ProgramData\chocolatey
CLASS=groovy.ui.Console
COMMAND_COM="C:\Windows\system32\cmd.exe"
CommonProgramFiles=C:\Program Files\Common Files
ComSpec=C:\Windows\system32\cmd.exe
以下略
  • このやり方でC#側を呼んだらComSpecの値がちゃんが取れました。
  • この件と関係ないけど、Groovyのcollect便利だなぁ。

GroovyでScript実行時に複数のクラスがあるとエラー発生

ソース

import static spark.Spark.*
import groovy.json.JsonBuilder

class A {
    def a = "test"
    def b = ['a':1, 'b': [111, 222, 333]]
}

class B {
    public static void main(String[] args) {

        Object.metaClass.asJson = {
            def builder = new JsonBuilder(delegate);
            builder.toString()
        }

        def obj = new A()
        get('/obj', { req, res -> obj.asJson() })
    }
}
  • Script実行すると、以下のようなエラーが出ます。
C:\hogehoge>groovy -classpath "%CLASSPATH%" src\main\groovy\foo.groovy
Caught: groovy.lang.GroovyRuntimeException: This script or class could not be run.
It should either:
- have a main method,
- be a JUnit test or extend GroovyTestCase,
- implement the Runnable interface,
- or be compatible with a registered script runner. Known runners:
  * <none>
groovy.lang.GroovyRuntimeException: This script or class could not be run.
It should either:
- have a main method,
- be a JUnit test or extend GroovyTestCase,
- implement the Runnable interface,
- or be compatible with a registered script runner. Known runners:
  * <none>

修正

  • どうやら最初のクラスにmainが無いといけないようです。

The Groovy programming language - Mailing-lists

  • ソース修正
import static spark.Spark.*
import groovy.json.JsonBuilder

class B {
    public static void main(String[] args) {

        Object.metaClass.asJson = {
            def builder = new JsonBuilder(delegate);
            builder.toString()
        }

        def obj = new A()
        get('/obj', { req, res -> obj.asJson() })
    }
}

class A {
    def a = "test"
    def b = ['a':1, 'b': [111, 222, 333]]
}

これで動いた!

Groovyで外部プロセス起動して結果を読もうとすると処理が返ってこない事がある

  • execute().textを読み出そうとすると一部のコマンドで返ってこないことがある。
    • どうやらWindowsではストリーム詰まる問題が出ることがあるらしい

www7164up.sakura.ne.jp

元ソース

def runCommand(String command, String param) {
    def msg = []
    def cmd = "C:/foo/bar/hogehoge.exe ${command} ${param}"
    
    def msg = cmd.execute([], new File("C:/foo/bar")).text.split()
    return msg
}
  • textを読み出そうとすると詰まる。
    • textを読まなければ詰まらないのでコマンド自体は実行されている・・・

改善後

def runCommand(String command, String param) {
    def msg = []
    def cmd = "C:/foo/bar/hogehoge.exe ${command} ${param}"
    
    def p = cmd.execute([], new File("C:/foo/bar"))
    // 一部のコマンドでStreamが詰まる問題のためThreadにしている
    Thread.start {
        p.in.eachLine {msg << it}
    }
    p.waitFor()
    return msg
}
  • p.err.eachLine {}が必要ならこちらもThreadにしたほうが良いかも。

うーん、出来たけどなんかすっきりしない。

Gradleで依存するライブラリをコピーする

  • オンプレミスのシステムを作っていると依存するライブラリはあらかじめインストーラに含めておく必要があるので、簡単に固めたいです。
  • gradle buildすると.gradleの下に入ったり、Groovyでgrape使ったりすると.groovyの下に入ったりするのですが、それを手動で集めるなんてしたくないし。

依存ライブラリをコピーするGradleタスク

  • build.gradleにコピーするタスクを書きます。
task copyDependencies(type:Copy) {
    new File('lib').mkdirs()
    copy {
        from configurations.runtime
        into 'lib'
    }
}
  • 実行
$ gradle copyDependencies
  • これでプロジェクトフォルダの下にlibディレクトリが出来てその中にjarがコピーされます。

別解

apply plugin: 'application'

mainClassName = 'class_name'
  • 実行
$ gradle installApp

SparkでAPIサーバを起動しようとしたらエラー

  • この記事を参考にSparkを使ってGroovyでWebAPIサーバ書こうと思ってる。

qiita.com

sparkjava.com

エラー発生!

:compileGroovy FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileGroovy'.
> spark/Spark : Unsupported major.minor version 52.0

原因

  • Javaのバージョンが1.7だったかららしい。1.8にしたら直った。
    • もう1.7だめかなー。うーんどうしよう。。。

Sparkとってもシンプルで書きやすいし、いい感じなので使いたいなー。1.8と1.7混在でもいいかな・・・。