2012年6月27日水曜日

アプリケーションの止め方 その2

その1は以前commons-daemon書いたときの方法だけど
文字列入力する方法は分かりにくいので、(どこに入力するか迷う)
Ctrl + zとした。というかreadLine()がnullの場合。


macだとCtrl + dとか。

  1. public static void main(String[] args) throws IOException {  
  2.         // the main routine is only here so I can also run the app from the  
  3.         // command line  
  4.   
  5.         BufferedReader stdReader = new BufferedReader(new InputStreamReader(  
  6.                 System.in));  
  7.         System.out.print("Enter 'Ctrl + z' to halt: ");  
  8.         while (stdReader.readLine() != null) { // ユーザの入力を待つ  
  9.             ;  
  10.         }  
  11.     }  

2012年5月18日金曜日

StringでSOAP通信

wsdlからwsimportを使って自動生成したJavaクラスSayHelloを使って、SOAPメッセージ(xml)をString型で生成し、
そのStringをURLConnectionでHTTP送受信する。
で、レスポンスをStringにして
SOAPMessageに戻す。

SOAPMessageからSOAPEnvelopeの子要素をorg.w3c.dom.Nodeオブジェクトで取得。
最後に、JAXBのUnmarshallでNodeからSayHelloResponse(wsimportで生成されたSOAPの応答のクラス)に変換する。
あとは、いつものSOAPです。


以上! ソースが汚すぎるから、明日整形しましょうかね。

  1. /** 
  2.  *  
  3.  */  
  4. package jp.blogspot.tanakanbb;  
  5.   
  6. import java.io.BufferedReader;  
  7. import java.io.BufferedWriter;  
  8. import java.io.ByteArrayInputStream;  
  9. import java.io.ByteArrayOutputStream;  
  10. import java.io.InputStreamReader;  
  11. import java.io.OutputStreamWriter;  
  12. import java.io.StringWriter;  
  13. import java.net.URL;  
  14. import java.net.URLConnection;  
  15.   
  16. import javax.xml.bind.JAXBContext;  
  17. import javax.xml.bind.Marshaller;  
  18. import javax.xml.bind.Unmarshaller;  
  19. import javax.xml.parsers.DocumentBuilderFactory;  
  20. import javax.xml.soap.MessageFactory;  
  21. import javax.xml.soap.SOAPMessage;  
  22. import javax.xml.soap.SOAPPart;  
  23. import javax.xml.transform.Transformer;  
  24. import javax.xml.transform.TransformerFactory;  
  25. import javax.xml.transform.dom.DOMSource;  
  26. import javax.xml.transform.stream.StreamResult;  
  27. import javax.xml.transform.stream.StreamSource;  
  28.   
  29. import org.w3c.dom.Document;  
  30.   
  31. import com.tanakanbb.sample.soap.SayHello;  
  32. import com.tanakanbb.sample.soap.SayHelloResponse;  
  33.   
  34. public class JaxWSExecutor {  
  35.   
  36.  public static void main(String[] args) throws Exception {  
  37.   
  38.   DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();  
  39.   dbf.setNamespaceAware(true);  
  40.   Document doc = dbf.newDocumentBuilder().newDocument();  
  41.   
  42.   JAXBContext context = JAXBContext.newInstance(SayHello.class);  
  43.   Marshaller marshaller = context.createMarshaller();  
  44.   marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);  
  45.   
  46.   SayHello sayHello = new SayHello();  
  47.   
  48.   sayHello.setName("hoge");  
  49.   
  50.   marshaller.marshal(sayHello, doc);  
  51.   
  52.   // We now have a DOM tree which has been populated by JAX-B  
  53.   MessageFactory factory = MessageFactory.newInstance();  
  54.   SOAPMessage message = factory.createMessage();  
  55.   message.getSOAPBody().addDocument(doc);  
  56.   
  57.   message.saveChanges();  
  58.   
  59.   ByteArrayOutputStream outputStream = new ByteArrayOutputStream();  
  60.   
  61.   message.writeTo(outputStream);  
  62.   
  63.   String xml = outputStream.toString("utf-8");  
  64.   
  65.   // <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><sayHello xmlns="http://soap.sample.tanakanbb.com"><name>hoge</name></sayHello></SOAP-ENV:Body></SOAP-ENV:Envelope>  
  66.   System.out.println(xml);  
  67.   try {  
  68.    URL url = new URL(  
  69.      "http://localhost:8084/soap_sample/services/Hello");  
  70.   
  71.    URLConnection con = url.openConnection();  
  72.   
  73.    // 送信するよ!指定  
  74.    con.setDoOutput(true);  
  75.   
  76.    con.setRequestProperty("Content-Type""application/soap+xml");  
  77.    con.setRequestProperty("SoapAction""");  
  78.   
  79.    // --------------------  
  80.    // 送信する  
  81.    // --------------------  
  82.    OutputStreamWriter ow1 = new OutputStreamWriter(con  
  83.      .getOutputStream());  
  84.    BufferedWriter bw1 = new BufferedWriter(ow1);  
  85.   
  86.    // POSTの内容を書き出す  
  87.    bw1.write(xml);  
  88.   
  89.    // クローズ  
  90.    bw1.close();  
  91.    ow1.close();  
  92.   
  93.    // --------------------  
  94.    // 受信する  
  95.    // --------------------  
  96.    InputStreamReader ir1 = new InputStreamReader(con.getInputStream());  
  97.    BufferedReader br1 = new BufferedReader(ir1);  
  98.   
  99.    ByteArrayOutputStream ba = new ByteArrayOutputStream();  
  100.    // 1行ずつ書き出す  
  101.    int b;  
  102.    while ((b = br1.read()) != -1) {  
  103.     ba.write(b);  
  104.    }  
  105.   
  106.    String response = ba.toString("utf-8");  
  107.   
  108.    // クローズ  
  109.    br1.close();  
  110.    ir1.close();  
  111.    ba.close();  
  112.   
  113.    // <?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><sayHelloResponse xmlns="http://soap.sample.tanakanbb.com"><sayHelloReturn>Hello!, hoge</sayHelloReturn></sayHelloResponse></soapenv:Body></soapenv:Envelope>  
  114.    System.out.println(response);  
  115.   
  116.    // Create SoapMessage  
  117.    MessageFactory msgFactory = MessageFactory.newInstance();  
  118.    SOAPMessage message2 = msgFactory.createMessage();  
  119.    SOAPPart soapPart = message2.getSOAPPart();  
  120.   
  121.    // Load the SOAP text into a stream source  
  122.    byte[] buffer = response.getBytes();  
  123.    ByteArrayInputStream stream = new ByteArrayInputStream(buffer);  
  124.    StreamSource source = new StreamSource(stream);  
  125.   
  126.    // Set contents of message  
  127.    soapPart.setContent(source);  
  128.   
  129.    // -- DONE  
  130.    // <?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><sayHelloResponse xmlns="http://soap.sample.tanakanbb.com"><sayHelloReturn>Hello!, hoge</sayHelloReturn></sayHelloResponse></soapenv:Body></soapenv:Envelope>  
  131.    message2.writeTo(System.out);  
  132.   
  133.    System.out.println("");  
  134.   
  135.    org.w3c.dom.Node srcNode = message2.getSOAPPart().getEnvelope()  
  136.      .getBody().getFirstChild();  
  137.   
  138.    StringWriter writer = new StringWriter();  
  139.   
  140.    Transformer transformer = TransformerFactory.newInstance()  
  141.      .newTransformer();  
  142.    transformer.transform(new DOMSource(srcNode), new StreamResult(  
  143.      writer));  
  144.   
  145.    // <?xml version="1.0" encoding="UTF-8"?><sayHelloResponse xmlns="http://soap.sample.tanakanbb.com"><sayHelloReturn>Hello!, hoge</sayHelloReturn></sayHelloResponse>  
  146.    System.out.println(writer.toString());  
  147.   
  148.    JAXBContext context2 = JAXBContext  
  149.      .newInstance(SayHelloResponse.class);  
  150.   
  151.    Unmarshaller m = context2.createUnmarshaller();  
  152.    Object obj = m.unmarshal(srcNode);  
  153.    SayHelloResponse ret = (SayHelloResponse) obj;  
  154.   
  155.    // Hello!, hoge  
  156.    System.out.println(ret.getSayHelloReturn());  
  157.   
  158.   } catch (Exception e) {  
  159.    e.printStackTrace();  
  160.   }  
  161.   
  162.  }  
  163. }  

2012年4月4日水曜日

commons-daemon 第3回

Windowsでのサービス登録方法 公式ページを参考にしてもどうにも動かないので、ちょっと頑張りが必要でした。  公式ページ → Daemon: Procrun

jarの作成

前回作成したJavaをJarにします。
ここでは面倒なので、Eclipseのエクスポート機能を使います。

成果物:EngineLauncher.jar

場所

とりあず、C:\tmp\test-serviceを作ります。
で、libフォルダにcommons-daemon-1.0.10.jar、commons-logging-1.1.1.jar、log4j-1.2.16.jarを入れ
logsフォルダも作っておきます。
あと、commons-daemon-1.0.10-bin-windows.zipをダウンロードしてあるはずなので、
その中にあるprunsrv.exeもC:\tmp\test-serviceに入れておきます。
C:\tmp\test-service
│  EngineLauncher.jar
│  install.bat
│  prunsrv.exe
│  uninstall.bat
│  
├─lib
│      commons-daemon-1.0.10.jar
│      commons-logging-1.1.1.jar
│      log4j-1.2.16.jar
│      
└─logs
        commons-daemon.2012-04-04.log
        testservice-stderr.2012-04-04.log
        testservice-stdout.2012-04-04.log

サービスへの登録バッチ

--Jvmオプションでjvm.dllの場所を指定するのですが、autoでうまく動かず、直接指定しました。autoのはずだと思うのですが…

  1. set EXEC_DIR=%~dp0  
  2. echo %EXEC_DIR%  
  3. set CLASSPATH_DIR=%EXEC_DIR%lib  
  4. echo %CLASSPATH_DIR%  
  5. set CLASSPATH=%EXEC_DIR%EngineLauncher.jar;%CLASSPATH_DIR%\commons-daemon-1.0.10.jar;%CLASSPATH_DIR%\commons-logging-1.1.1.jar;%CLASSPATH_DIR%\log4j-1.2.16.jar;  
  6. echo %CLASSPATH%  
  7. set JVM_PATH="C:\Program Files\Java\jdk1.6.0_31\jre\bin\server\jvm.dll"  
  8.   
  9. prunsrv //IS//TestService --DisplayName="Test Service" ^  
  10.         --Startup=auto ^ --Jvm=%JVM_PATH% --StartMode=jvm --StopMode=jvm ^  
  11.         --Classpath=%CLASSPATH% ^  
  12.         --StartClass=jp.tanakanbb.blogspot.daemon.service.sample.EngineLauncher --StartParams=start ^  
  13.         --StartMethod=windowsService ^  
  14.         --StopClass=jp.tanakanbb.blogspot.daemon.service.sample.EngineLauncher --StopParams=stop ^  
  15.         --StopMethod=windowsService ^  
  16.         --LogPath=%EXEC_DIR%logs --LogLevel=DEBUG ^  
  17.         --StdOutput=auto --StdError=auto ^  
  18.           
  19.           
  20.   
  21. pause  

サービスへの削除バッチ


  1. prunsrv //DS//TestService  
  2.   
  3. pause  

手順

install.batを実行すると、サービスに登録され、管理ツールからサービスを開いて、"Test Service"を開始すればサービスが始まります。
停止すれば止まります。
アンインストールは、uninstall.batです。

--Startup=autoだけど、install.batを実行しても開始されません...

追加で

commons-logging.properties

  1. org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger  
log4j.xmlはこんなかんじ。/var/log/daemon/application.logにログ出力します。

  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">  
  3.   
  4. <log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>  
  5.   
  6.   <!-- ********************** 標準出力への出力 ********************** -->  
  7.   <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">  
  8.     <param name="threshold" value="info"/>  
  9.   
  10.     <!-- レイアウトの指定 -->  
  11.     <layout class="org.apache.log4j.PatternLayout">  
  12.       <param name="ConversionPattern"  
  13.              value=""%d{yyyy/MM/dd HH:mm:ss.SSS}",%p,%c,%M,%L,%m%n" />  
  14.     </layout>  
  15.   </appender>  
  16.   
  17.   <!-- ********************** ファイルへの出力 ********************** -->  
  18.   <appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">  
  19.     <param name="threshold" value="debug"/>  
  20.   
  21.     <!-- ファイル情報 -->  
  22.     <param name="file" value="/var/log/daemon/application.log" />  
  23.   
  24.     <param name="append" value="false" />  
  25.     <param name="datePattern" value="'.'yyyy-MM-dd" />  
  26.   
  27.     <!-- レイアウトの指定 -->  
  28.     <layout class="org.apache.log4j.PatternLayout">  
  29.       <param name="ConversionPattern"  
  30.              value=""%d{yyyy/MM/dd HH:mm:ss.SSS}",%p,%c,%M,%L,%m%n" />  
  31.     </layout>  
  32.   </appender>  
  33.   
  34.   <!-- ********************** category定義 ************************* -->  
  35.   <category name="jp.tanakanbb.blogspot">  
  36.     <priority value="debug" />  
  37.     <appender-ref ref="FILE" />  
  38.   </category>  
  39.   
  40.   <!-- ********************** root定義 ***************************** -->  
  41.   <root>  
  42.     <priority value="debug" />  
  43.     <appender-ref ref="STDOUT" />  
  44.   </root>  
  45.   
  46. </log4j:configuration>  

commons-daemon 第2回

まずはjavaソースから。 以下のwikiを参考にしてます。

参考 Daemon - Commons Wiki

ただ、肝心な部分がよく分からなかったので、カスタマイズしてます。 まずは、Daemonインターフェースを実装したクラス。
EngineLauncher クラスが本体で、こいつがEngine(インターフェースを実装した)クラスを起動してメイン処理を実行します。
停止するときも、Engine(インターフェースを実装した)クラスを停止します。

EngineLauncher

Windowsのサービスとして動くときは、windowsServiceを使用します。
procrun.exeは、public staticメソッドしか呼ぶことができません。
そして、実行時には引数を渡すことができますので
開始時には、"start"、停止時には"stop"を渡すことで、それぞれstartWindowsServiceとstopWindowsServiceメソッドを呼び出します。

mainメソッドはおまけです。使用しません。

Linuxで使用するjsvcでは、Daemonインターフェースを実装していると、
最初にinitが呼ばれ、続いてstartメソッドが呼ばれます。
停止するときは、"-stop"オプションをつけてjsvcを実行することでstopメソッドが呼び出されます。

  1. package jp.tanakanbb.blogspot.daemon.service.sample;  
  2.   
  3. import java.util.Scanner;  
  4. import java.util.concurrent.ExecutorService;  
  5. import java.util.concurrent.Executors;  
  6.   
  7. import jp.tanakanbb.blogspot.daemon.service.sample.impl.SampleEngineImpl;  
  8.   
  9. import org.apache.commons.daemon.Daemon;  
  10. import org.apache.commons.daemon.DaemonContext;  
  11. import org.apache.commons.logging.Log;  
  12. import org.apache.commons.logging.LogFactory;  
  13.   
  14. public class EngineLauncher implements Daemon {  
  15.   
  16.     /** 
  17.      * ログ 
  18.      */  
  19.     private static Log LOG = LogFactory.getLog(EngineLauncher.class);  
  20.   
  21.     /** 
  22.      * エンジン 
  23.      */  
  24.     private static Engine engine = null;  
  25.   
  26.     /** 
  27.      * エンジン起動 
  28.      */  
  29.     private static EngineLauncher engineLauncherInstance = new EngineLauncher();  
  30.   
  31.     /** 
  32.      * Executor 
  33.      */  
  34.     private ExecutorService executor = null;  
  35.   
  36.     /** 
  37.      * The Java entry point. 
  38.      * 
  39.      * @param args 
  40.      *            Command line arguments, all ignored. 
  41.      */  
  42.     public static void main(String[] args) {  
  43.         // the main routine is only here so I can also run the app from the  
  44.         // command line  
  45.         engineLauncherInstance.initialize();  
  46.   
  47.         engineLauncherInstance.startWindowsService();  
  48.   
  49.         Scanner sc = new Scanner(System.in);  
  50.         // wait until receive stop command from keyboard  
  51.         System.out.printf("Enter 'stop' to halt: ");  
  52.   
  53.         while (!sc.nextLine().toLowerCase().equals("stop")) {  
  54.             ;  
  55.         }  
  56.   
  57.         engineLauncherInstance.stopWindowsService();  
  58.   
  59.     }  
  60.   
  61.     /** 
  62.      * Windowsサービスを起動します。 
  63.  
  64.      * サービス登録するときのパラメータは次のようです。 
  65.      * 
  66.      * <pre> 
  67.      * --StartMode=jvm --StartClass=jp.tanakanbb.blogspot.daemon.service.sample.EngineLauncher --StartMethod=windowsService --StartParams=start --StopMode=jvm --StopClass=jp.tanakanbb.blogspot.daemon.service.sample.EngineLauncher --StopMethod=windowsService --StopParams=stop 
  68.      * </pre> 
  69.      * 
  70.      * Windowsサービス、つまりprocrunで起動する場合、実行するメソッドは"public static void"である必要があります。 
  71.  
  72.      * voidでなくてもいいかもしれませんが、戻り値を解釈しないので、voidがいいと思います。 
  73.      * 
  74.      * @param args 
  75.      *            Arguments from prunsrv command line 
  76.      **/  
  77.     public static void windowsService(String args[]) {  
  78.         String cmd = "start";  
  79.         if (args.length > 0) {  
  80.             cmd = args[0];  
  81.         }  
  82.   
  83.         if ("start".equals(cmd)) {  
  84.             engineLauncherInstance.startWindowsService();  
  85.         } else {  
  86.             engineLauncherInstance.stopWindowsService();  
  87.         }  
  88.     }  
  89.   
  90.     /** 
  91.      * Windowsサービスの場合のスタートメソッド。 
  92.  
  93.      * Engine#execute()を起動します。 
  94.      */  
  95.     public void startWindowsService() {  
  96.         if (LOG.isDebugEnabled()) {  
  97.             LOG.debug("startWindowsService called");  
  98.         }  
  99.   
  100.         initialize();  
  101.         // don't return until stopped  
  102.         executor.execute(engine);  
  103.     }  
  104.   
  105.     /** 
  106.      * Windowsサービスを停止します。 
  107.      */  
  108.     public void stopWindowsService() {  
  109.         if (LOG.isDebugEnabled()) {  
  110.             LOG.debug("stopWindowsService called");  
  111.         }  
  112.   
  113.         terminate();  
  114.   
  115.         executor.shutdown();  
  116.     }  
  117.   
  118.     /** 
  119.      * Implementing the Daemon interface is not required for Windows but is for 
  120.      * Linux 
  121.  
  122.      * jsvcでの起動時に最初に呼ばれます。 
  123.  
  124.      * {@link Daemon#init(DaemonContext)} 
  125.      */  
  126.     @Override  
  127.     public void init(DaemonContext arg0) throws Exception {  
  128.         LOG.debug("Daemon init");  
  129.     }  
  130.   
  131.     /** 
  132.      * jsvcでの起動時に、{@link Daemon#init(DaemonContext)}の次に呼ばれます。 
  133.      */  
  134.     @Override  
  135.     public void start() {  
  136.         if (LOG.isDebugEnabled()) {  
  137.             LOG.debug("Daemon start");  
  138.         }  
  139.         initialize();  
  140.     }  
  141.   
  142.     /** 
  143.      * jsvcでの-stopオプション時に呼ばれます。 
  144.      */  
  145.     @Override  
  146.     public void stop() {  
  147.         if (LOG.isDebugEnabled()) {  
  148.             LOG.debug("Daemon stop");  
  149.         }  
  150.   
  151.         terminate();  
  152.     }  
  153.   
  154.     /** 
  155.      * {@link Daemon#stop()}後に呼ばれます。 
  156.      */  
  157.     @Override  
  158.     public void destroy() {  
  159.         if (LOG.isDebugEnabled()) {  
  160.             LOG.debug("Daemon destroy");  
  161.         }  
  162.     }  
  163.   
  164.     /** 
  165.      * Engineを初期化します。 
  166.  
  167.      * WindowsでもLinuxでも、最初にこれを呼ぶ必要があります。 Do the work of starting the engine 
  168.      */  
  169.     private void initialize() {  
  170.         if (engine == null) {  
  171.             if (LOG.isInfoEnabled()) {  
  172.                 LOG.info("Starting the Engine");  
  173.             }  
  174.             engine = new SampleEngineImpl();  
  175.         }  
  176.   
  177.         executor = Executors.newSingleThreadExecutor();  
  178.     }  
  179.   
  180.     /** 
  181.      * Windowsサービス、デーモンを停止します。 WindowsでもLinuxでも、停止時には、これを呼ぶ必要があります。 Cleanly stop 
  182.      * the engine. 
  183.      */  
  184.     public void terminate() {  
  185.         if (engine != null) {  
  186.             if (LOG.isInfoEnabled()) {  
  187.                 LOG.info("Stopping the Engine");  
  188.             }  
  189.   
  190.             engine.stop();  
  191.   
  192.             if (LOG.isInfoEnabled()) {  
  193.                 LOG.info("Engine stopped");  
  194.             }  
  195.         }  
  196.     }  
  197.   
  198. }  

Engine


  1. package jp.tanakanbb.blogspot.daemon.service.sample;  
  2.   
  3. public interface Engine extends Runnable {  
  4.   
  5.     public void stop();  
  6.   
  7.     public Boolean isStopped();  
  8.   
  9. }  

SampleEngineImpl


  1. package jp.tanakanbb.blogspot.daemon.service.sample.impl;  
  2.   
  3. import jp.tanakanbb.blogspot.daemon.service.sample.Engine;  
  4.   
  5. import org.apache.commons.logging.Log;  
  6. import org.apache.commons.logging.LogFactory;  
  7.   
  8. public class SampleEngineImpl implements Engine {  
  9.   
  10.     /** 
  11.      * ログ 
  12.      */  
  13.     private static Log LOG = LogFactory.getLog(SampleEngineImpl.class);  
  14.   
  15.     /** 
  16.      * 停止フラグ 
  17.      */  
  18.     private Boolean isStopped = Boolean.FALSE;  
  19.   
  20.     /** 
  21.      * スレッドID 
  22.      */  
  23.     private String id = null;  
  24.   
  25.     @Override  
  26.     public void stop() {  
  27.         this.isStopped = Boolean.TRUE;  
  28.     }  
  29.   
  30.     @Override  
  31.     public Boolean isStopped() {  
  32.         return isStopped;  
  33.     }  
  34.   
  35.     @Override  
  36.     public void run() {  
  37.   
  38.         this.id = String.valueOf(Thread.currentThread().getId());  
  39.   
  40.         while (!isStopped()) {  
  41.             if (LOG.isInfoEnabled()) {  
  42.                 LOG.info("[" + id + "]" + "hoge");  
  43.             }  
  44.   
  45.             try {  
  46.                 Thread.sleep(10000);  
  47.             } catch (InterruptedException e) {  
  48.                 isStopped = Boolean.TRUE;  
  49.                 if (LOG.isErrorEnabled()) {  
  50.                     LOG.error(e);  
  51.                 }  
  52.             }  
  53.         }  
  54.     }  
  55.   
  56. }  
さて、第3回では、Windowsサービスへの登録方法とLinuxデーモン化方法を書きたいと思います。

2012年3月28日水曜日

commons-daemon [第1回]

Javaでも常駐プロセスを、つまりデーモンを作りたいときもある。
もしくは、Windowsサービスを作りたいときもある。

そんなとき、やっぱり常駐するだけあって、実績のあるものを使いたい!!(←本音)

ということで選択したのはtomcatでも採用されている「commons-daemon

しかし、情報が少ない。 日本語も少ないし、英語も少ない(全部読んだわけではないけど)。

というわけで、自分で書いてみる。

第1回目は目標を掲げます。

目標

LinuxでもWindowsでも動くデーモンorサービスを作る

準備

次のサイトからダウンロードします。※1.0.10使います。 Commons Daemon Download
  1. [Commons Daemon Binaries] commons-daemon-1.0.10-bin.tar.gz
  2. [Browse native binaries download area...] commons-daemon-1.0.10-bin-windows.zip
  3. [Commons Daemon Source] commons-daemon-1.0.10-native-src.tar.gz


1番目は実装するときに使います。
2番目はWindowsサービス化で使います。
3番目はLinuxデーモン化で使います。
第2回はいきなりソース公開します。

2011年10月2日日曜日

Objective-C @Windows XP

Objective-C @Windows XP

Objective-Cに興味を持ったのでWindows XPで環境構築してみた。

参考にさせていただきました → 参考サイト

ダウンロードサイト

GNUSTEP公式サイト 0.22系だったので、以下の3つをダウンロードしました。
  1. gnustep-system-0.22.0-setup.exe
  2. gnustep-core-0.22.0-setup.exe
  3. SystemPreferences-1.0.2-7-setup.exe
  4. gorm-1.2.4-6-setup.exe (0.20.xのみ必要)
  5. Calculator-1.0.0-2-setup.exe (0.19.xのみ必要)

インストール

上記の番号順にインストールしました。
なんとなくインストールフォルダは「C:\opt\gnustep」としました。
インストール場所は毎回聞かれますが、毎回「C:\opt\gnustep」です。

私は0.22系だったので、1から3番をインストールしました。

環境変数の設定

環境変数に
  • GNUSTEP_HOME=C:\opt\gnustep
  • PATHに「%GNUSTEP_HOME%\bin」を追記

サンプルソース

では、ためしにやってみよう!ということで、以下のサイトにあったサンプルソースで実行してみました。 勝手にすみません。 ほんまの走り書き技術メモ
  1. #import <stdio.h>  
  2. #import <objc/Object.h>  
  3.   
  4. @interface TestClass : Object  
  5. - (void) getMessage;  
  6. @end  
  7.   
  8. @implementation TestClass  
  9. - (void) getMessage {  
  10.     printf("Hello Objective-C World\n");  
  11. }  
  12. @end  
  13.   
  14. int main(int argc, char *argv[]) {  
  15.     id obj = [ TestClass alloc ];  
  16.     [ obj getMessage ];  
  17.   
  18.     return 0;  
  19. }  

サンプルコンパイル

上記のソースをコンパイル。オプション多すぎて面倒、、、
C:\Documents and Settings\xxxxxx\デスクトップ>gcc -o hello hello.m -I C:\opt\g
nustep\GNUstep/System/Library/Headers -L C:\opt\gnustep\GNUstep/System/Library/L
ibraries -lobjc -lgnustep-base -fconstant-string-class=NSConstantString -enable-
auto-import
hello.exeができたので実行しました。
Hello Objective-C World
よかった、よかった

2011年9月19日月曜日

原発のしくみと放射能

Newton別冊 原発のしくみと放射能
そろそろ話題も絞られてきた気がするので
ちゃんと勉強しておこうと思って読んでみた。

結構難しいなーさすがNewton