ページ

ラベル Java の投稿を表示しています。 すべての投稿を表示
ラベル Java の投稿を表示しています。 すべての投稿を表示

2018年2月3日土曜日

NetBeansでMavenプロジェクトを使ってみる

これまでNetBeansでほんのちょっとだけ遊んでいてもMavenって使ったことなかったんですよね。やっぱりいろいろするのに便利そうなので軽く使ってみようかと。

さて、そもそもNetBeansでMavenプロジェクトを作ると実行できないjarファイルが出来上がるみたい。
このあたりを参考にさせていただきました。
あと依存するライブラリをすべて同梱したいですね。maven-assembly-pluginとやらを使うと実現できるみたい。
上記参考にさせていただきました。
本当はsoファイルとかも入れてみたいですが、それはそのうちということで。

あと作ったライブラリはMavenのローカルリポジトリに登録されるみたいですが、別環境で作ったものなど未登録のものは別途登録しておきましょう。
こちら参考にさせていただきました。
ひとまずこれでおおよそは事足りるかな。(自分の場合は)

最後に、余談ですがプロキシサーバ経由でインターネットに出てるような環境ではNetBeansの設定が必要です。
さてこのあたりが分かってきたので、今度はいよいよJetty使ってプログラム書いてみよーっと。そのうち。

2017年11月14日火曜日

Bash on Ubuntu on Windowsでglassfishが動くのか?

素朴な疑問からスタートしてみました。とりあえず試してみますかね。
まずはGlassFishをダウンロード、今回はglassfish-4.1.2.zipを試してみます。

/opt/にコピーして解凍・・・と思ったらunzipって入ってないんですね。まずは入れてと。

xxx@yyy-pc:~$ sudo apt-get install zip unzip

今回はBash on Ubuntu on Windowsってのもあるのでユーザは新規に作らずに既存ユーザで試してみます。ということでパーミッションを変更してと。

xxx@yyy-pc:/opt$ sudo chown -R xxx: /opt/glassfish4/

さっそく起動してみよう。

xxx@yyy-pc:/opt$ cd /opt/glassfish4/
xxx@yyy-pc:/opt/glassfish4$ bin/asadmin start-domain
Waiting for domain1 to start ..............................
Successfully started the domain : domain1
domain  Location: /opt/glassfish4/glassfish/domains/domain1
Log File: /opt/glassfish4/glassfish/domains/domain1/logs/server.log
Admin Port: 4848
Command start-domain executed successfully.

お、なんか起動したっぽい。
さて管理画面にアクセスできるのかな?Windows上のChromeで「http://localhost:4848」にアクセスしてみましょう。


お、アクセスできた。「http://localhost:8080」にもアクセスできるかな?


こちらもOK。さて停止も試してみましょう。

xxx@yyy-pc:/opt/glassfish4$ bin/asadmin stop-domain
Waiting for the domain to stop .
Command stop-domain executed successfully.

上記サイトにアクセスできなくなったのできちんと終了してるっぽいですね。
次回は簡単なアプリケーションをのせてみようかな。

2016年8月26日金曜日

やっぱりJNI

一時期JNAに凝ってましたが、やっぱり何だかんだでJNIのほうが取り回しやすいなと感じている今日この頃。
なもんで、超簡単なサンプルを載せておきます。(転用は自己責任でお願いします。)


<C++>

#include "jnisample_JniSample.h"
#include <iostream>

class Sample {
public:
  Sample() {
    std::cout << "constructor" << std::endl;
  }
  ~Sample() {
    std::cout << "destructor" << std::endl;
  }
};

#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     jnisample_JniSample
 * Method:    open
 * Signature: (Ljava/lang/String;)J
 */
JNIEXPORT jlong JNICALL Java_jnisample_JniSample_open
  (JNIEnv *env, jobject obj, jstring jconf)
{
  const char *conf = env->GetStringUTFChars(jconf, 0);
  Sample *obj = new Sample();
  env->ReleaseStringUTFChars(jconf, conf);
  return (jlong)obj;
}

/*
 * Class:     jnisample_JniSample
 * Method:    close
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_jnisample_JniSample_close
  (JNIEnv *env, jobject obj, jlong jhandle)
{
  delete (Sample *)jhandle;
}

#ifdef __cplusplus
}
#endif


<Java>

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package jnisample;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 */
public class JniSample {
    
    private long handle;
    
    static {
        System.loadLibrary("native_sample");
    }
    
    public JniSample(String conf) {
        handle = open(conf);
    }
    
    public void close() {
        close(handle);
    }
    
    private native long open(String conf);
    private native void close(long handle);

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        JniSample obj = new JniSample("hoge");
        System.out.println("object created.");
        obj.close();
        System.out.println("program end.");
    }
    
}



Java側のコード書いたあとで、

>javah -classpath classes jnisample.JniSample

こんなするとネイティブライブラリのヘッダができますので、あとは中身の実装をするだけです。

2015年11月8日日曜日

WebSocketでファイルアップロード

前回WebSocketを少しいじったので、今回は少し拡張してファイルアップロードを実現してみました。

まずサーバ側はファイル名を受け取るようにしてみました。ちと面倒だったのでテキストメッセージでファイル名を受けたときにファイルをオープンして、ファイルのクローズは切断時に行ってます。(ちなみにGlassFish上で動作させてます。)

--------------------------------------------------
package sample; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.logging.Level; import java.util.logging.Logger; import javax.websocket.OnOpen; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/endpoint") public class NewWSEndpoint { private static FileChannel channel = null; @OnOpen public void onOpen(Session session){ System.out.println("OnOpen"); } @OnClose public void onClose(Session session){ try { System.out.println("OnClose"); channel.close(); } catch (IOException ex) { Logger.getLogger(NewWSEndpoint.class.getName()).log(Level.SEVERE, null, ex); } } @OnMessage public String onMessage(Session session, String message) { try { System.out.println("OnMessage String = " + message); channel = new FileOutputStream(new File("../logs/" + message)).getChannel(); } catch (FileNotFoundException ex) { Logger.getLogger(NewWSEndpoint.class.getName()).log(Level.SEVERE, null, ex); } return null; } @OnMessage public void onMessage(Session session, ByteBuffer byteBuffer) { try { System.out.println("OnMessage binary = " + byteBuffer.toString()); channel.write(byteBuffer); } catch (IOException ex) { Logger.getLogger(NewWSEndpoint.class.getName()).log(Level.SEVERE, null, ex); } } @OnError public void onError(Throwable t) { System.out.println("OnError"); } } --------------------------------------------------

HTMLはシンプルにこんな感じ。
ファイルをドラッグ&ドロップして指定する形を取りました。

--------------------------------------------------
<html> <head> <title>JavaEE7 WebSocket Test</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script type="text/javascript" src="app.js"></script> </head> <body> <section id="main"> <div id="drop" style="width:500px; height:150px; padding:10px; border:3px solid" ondragover="onDragOver(event)" ondrop="onDrop(event)">ここにファイルをドロップして下さい</div> <div id="disp" ></div> </section> </body> </html> --------------------------------------------------

JavaScriptはこんな感じ。
指定されたファイルを読み込みバイナリとして送信します。

--------------------------------------------------
if (!window.File) { window.alert("このブラウザではFile APIが使えません"); } function onDrop(event) { var files = event.dataTransfer.files; var disp = document.getElementById("disp"); for (var i = 0; i < files.length; i++) { var f = files[i]; var socket = new WebSocket("ws://localhost:8080/TestWebSocket/endpoint"); socket.onopen = function() { var reader = new FileReader(); reader.onload = function(){ var binary = new Uint8Array(reader.result); socket.send(f.name); socket.send(binary.buffer); socket.close(); disp.innerHTML = f.name + "[" + f.size + "byte]" + "アップロード完了"; }; reader.readAsArrayBuffer(f); }; } event.preventDefault(); } function onDragOver(event) { event.preventDefault(); } --------------------------------------------------

あとは大きなファイルでも経過を表示したりできるように分割送信とかするといいでしょうね。

2015年10月17日土曜日

JavaEE7でWebSocket

ここのところお仕事が忙しくてなかなかプログラムで遊ぶことがなかったのですが、今日は雨で子供たちの予定がなくなったのでお勉強がてらいじってみました。

お題は「JavaEE7でWebSocket」です。
バイナリデータをWebSocketサーバで受けたいなというのがそもそもの思いです。

サーバ側はこんなです。

--------------------------------------------------
package sample; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.websocket.OnOpen; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/endpoint") public class NewWSEndpoint { private static FileChannel channel = null; @OnOpen public void onOpen(Session session){ try { channel = new FileOutputStream(new File("output.dat")).getChannel(); System.out.println("OnOpen"); } catch (FileNotFoundException ex) { Logger.getLogger(NewWSEndpoint.class.getName()).log(Level.SEVERE, null, ex); } } @OnClose public void onClose(Session session){ try { channel.close(); System.out.println("OnClose"); } catch (IOException ex) { Logger.getLogger(NewWSEndpoint.class.getName()).log(Level.SEVERE, null, ex); } } @OnMessage public String onMessage(Session session, String message) { System.out.println("OnMessage String = " + message); return null; } @OnMessage public void onMessage(Session session, ByteBuffer byteBuffer) { try { channel.write(byteBuffer); System.out.println("OnMessage binary = " + byteBuffer.toString()); } catch (IOException ex) { Logger.getLogger(NewWSEndpoint.class.getName()).log(Level.SEVERE, null, ex); } } @OnError public void onError(Throwable t) { System.out.println("OnError"); } } --------------------------------------------------

接続を受けたときにファイルを生成し、バイナリデータを受けたときに書きだし、切断を検出したときにファイルをクローズするというシンプルなものです。ちなみにテキストデータを受けたときはprintlnしてるだけです。

これを試すクライアント側です。とりあえず簡単に試したいのでJavaScriptにしてみました。

--------------------------------------------------
<html> <head> <title>JavaEE7 WebSocket Test</title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script type="text/javascript"> var socket; $(document).ready(function(){ socket = new WebSocket("ws://localhost:8080/TestWebSocket/endpoint"); $('#send').click(function(){ // テキストボックスから文字列取得 var text = $('#message').val(); // テキスト送信 socket.send(text); // 文字列のアスキーコードを代入 var length = text.length; var binary = new Uint8Array(length); for (var i = 0; i < length; i++) { binary[i] = text[i]; } // バイナリ送信 socket.send(binary.buffer); }); }); </script> </head> <body> <input id="message" type="text" /> <button id="send">Send</button> <div id="messages"> </div> </body> </html> --------------------------------------------------

それにしても非常に少ないソースコードでサーバが実現できますね。すばらしい。

2014年12月29日月曜日

JNAは楽チン♪

Javaのプログラムで部分的にC/C++で実装したいということはよくあるかと思います。でもJNIって何か面倒なイメージが・・・。
(慣れてしまえば、って感じなのかもしれませんが。)

そこで便利なのがJNA。JNIで実装しなければいけない面倒なコードをだいぶ省略できるようです。
ただ、超簡単なサンプルはよく見かけるのですが、ほんのちょっとインタフェースを複雑にしたりすると意外とサンプルって見かけないものですよね。(検索の仕方が下手なのかもしれませんが・・・
なものでちょこっとC/C++側とJava側のサンプルを作ってみました。

コメント等はそのうち気が向いたら補足するとして、とりあえずコードだけ載せておきます。
構造体やコールバック関数が使えればだいたいのことはできるんじゃないかな?というレベルのものです。日本語扱うときだと環境によっては注意が必要でしょうね。

ちなみに私が使ったJNAのバージョンは4.1.0です。コードを見ていただくと分かりますがWindows上で試してました。

なお、あくまでサンプルコードなので当方では一切の責任を持ちません。皆様の責任の範囲でご参照ください。

--------------------------------------------------
<C/C++側>

#include
#include

struct SampleContext {
  int member;
};
typedef SampleContext* SampleHandle;

struct SampleStruct {
  char member[1024];
};

extern "C" {

__declspec(dllexport) SampleHandle function_open(SampleStruct *arg)
{
  SampleContext *context = (SampleHandle)new SampleContext;
  context->member = atoi(arg->member);
  return (SampleHandle)context;
}

__declspec(dllexport) void function_run(SampleHandle arg, void(*callback)(SampleHandle))
{
  SampleContext *context = (SampleContext *)arg;
  std::cout << "   start: " << context->member << std::endl;
  (*callback)(arg);
  std::cout << "     end: " << context->member << std::endl;
}

__declspec(dllexport) int function_get(SampleHandle arg)
{
  SampleContext *context = (SampleContext *)arg;
  return context->member;
}

__declspec(dllexport) void function_close(SampleHandle arg)
{
  SampleContext *context = (SampleContext *)arg;
  delete context;
}

}
--------------------------------------------------
<Java側>

package sample_jna;

import java.util.Arrays;
import java.util.List;

import com.sun.jna.Callback;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.PointerType;
import com.sun.jna.Structure;

public class SampleJna {
  public static class SampleStruct extends Structure {
    public byte [] member = "12345".getBytes();
      @Override
      protected List getFieldOrder() {
          return Arrays.asList ("member");
      }
      public SampleStruct() {
        super();
      }
  }

  public static class SampleHandle extends PointerType {
    public SampleHandle() {
      super();
    }
    public SampleHandle(Pointer address) {
      super(address);
    }
  }

  public interface SampleCallback extends Callback {
    public void invoke(SampleHandle arg);
  }

  public interface SampleLibrary extends Library {
    SampleLibrary INSTANCE = (SampleLibrary)Native.loadLibrary("sample_library", SampleLibrary.class);
    SampleHandle function_open(SampleStruct arg);
    void function_run(SampleHandle arg, SampleCallback callback);
    int function_get(SampleHandle arg);
    void function_close(SampleHandle arg);
  }

  public static class UserCallback implements SampleCallback {
    public void invoke(SampleHandle arg) {
      String message = "callback: " + SampleLibrary.INSTANCE.function_get(arg);
      System.out.println(message);
    }
  }

  public static void main(String[] args) {
    SampleStruct struct = new SampleStruct();
    UserCallback callback = new UserCallback();

    SampleHandle handle = SampleLibrary.INSTANCE.function_open(struct);
    SampleLibrary.INSTANCE.function_run(handle, callback);
    SampleLibrary.INSTANCE.function_close(handle);
  }
}
--------------------------------------------------

実行結果はこんな感じ。

   start: 12345
callback: 12345
     end: 12345

ちゃんとコールバック関数内でもコンテキスト内部の情報が取れてますね。