Skip to content

Instantly share code, notes, and snippets.

View takawitter's full-sized avatar

Takao Nakaguchi takawitter

View GitHub Profile
@takawitter
takawitter / TestService.groovy
Last active February 12, 2016 08:45
The script which serve the service via JSON-RPC using Service Grid Service Container and Jetty.
@Grab('org.eclipse.jetty:jetty-webapp:9.3.0.M1')
@Grab('net.servicegrid:jp.go.nict.langrid.servicecontainer:1.0.6')
import jp.go.nict.langrid.servicecontainer.handler.annotation.Service;
import jp.go.nict.langrid.servicecontainer.handler.jsonrpc.servlet.JsonRpcServlet;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;
public interface TestService{
int f(int n);
}
import net.arnx.jsonic.JSON;
import org.jsonman.Node;
import org.jsonman.NodeFactory;
import org.jsonman.NodeFinder;
import org.jsonman.node.MapNode;
import org.junit.Assert;
import org.junit.Test;
public class NodeFinderTest{
@Test
import org.fluentd.logger.FluentLogger;
public class FluentLoggerTest {
public static class Log{
public Log(String name, String msg){
this.name = name;
this.msg = msg;
}
public String getName() {
return name;
@takawitter
takawitter / MethodInvoker.java
Created July 15, 2013 16:43
https://gist.github.com/takawitter/5993155 の続き。パラメータの型のマッチングにも対応してみた。 パラメータの型が一致するメソッドが見つかった場合はそれを、見つからない場合はパラメータの型の祖先を持つもの(f(Integer v)に対するf(Number v)とか)を検索して実行する。どちらの場合もIllegalAccessExceptionが発生した場合はインタフェースから同じメソッドを探して実行する。 但し、パラメータの型の祖先も対象にする場合は、複数のメソッドがマッチする可能性があり、その場合は例外を投げるべきかもしれないが、それを検出するにはメソッド全部調べる必要がありコストが高い。
public class MethodInvoker{
public static Object invoke(
Object instance, String methodName, Object... args)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException{
Class<?> clazz = instance.getClass();
Class<?>[] argTypes = new Class<?>[args.length];
for(int i = 0; i < args.length; i++){
argTypes[i] = args[i].getClass();
}
try{
@takawitter
takawitter / InvokeSafely.java
Last active December 19, 2015 17:39
https://gist.github.com/takawitter/5993052 の続き。こんな感じでメソッドを検索して、安全に実行できるものを見つけてやる。実際のケースではパラメータのマッチングが加わるから、より複雑なコードになるけど。あと、最初に見つかった(呼ぶとIllegalAccessExceptionになる)メソッドでも、setAccessible(true)してやるとたいてい呼べる。但し呼べるかどうかはSecurityManager次第なので、この方法の方が安全。
import java.lang.reflect.Method;
public class InvokeSafely{
public static Object invokeSafely(Object obj, String method) throws Throwable{
Class<?> c = obj.getClass();
Method m = c.getMethod(method);
try{
return m.invoke(obj);
} catch(IllegalAccessException e){
}
@takawitter
takawitter / Invoker.java
Created July 14, 2013 03:13
https://gist.github.com/takawitter/5985742 の件、IllegalAccessExceptionが起こる原因は別にScheme(kawa)に限らないので、Javaのみで再現させてみた。MainクラスとInvokerクラスは別パッケージ。これはスクリプト言語だけでなく、msgpack-rpcとかのRPCライブラリ系にもよくある話。
package pkg2;
public class Invoker{
public static void invoke(Runnable instance) throws Exception{
instance.run(); // ok
instance.getClass().getMethod("run").invoke(instance); // ng, IllegalAccessException
}
}
@takawitter
takawitter / InvokeJavaFromScheme.java
Last active December 19, 2015 16:39
kawaでJavaオブジェクトのメソッドを呼び出す方法は複数あるけど、匿名クラス(やpublicではないクラス)の場合挙動が変わってくる。そのまとめ。kawaはのバージョンは1.13。
import kawa.standard.Scheme;
public class InvokeJavaFromScheme {
public static void main(String[] args) throws Throwable{
Scheme s = Scheme.getInstance();
// objにRunnableを実装した匿名クラスのインスタンスを設定。
// runメソッドはRunnableインタフェースのメソッドだから、問題なく呼べるはず。
s.define("obj", new Runnable(){
public void run() {
System.out.println("hello");
@takawitter
takawitter / gist:5895868
Last active December 19, 2015 04:18
ThreadPoolExecutorに値を返すlambda(or closure)をsubmitしたい。submit(Callable<T> task)が呼ばれればOKなんだけど、ThreadPoolExecutorにはsubmit(Runnable task)も存在するので、普通にlambdaを渡すと曖昧性が解消できない。そのためCallable<T>を明示する必要があるが、その方法が言語によって違うって話。 ScalaとJythonとJRubyは直接やる方法が無さそうなので、ラッパークラスをかましてる。
/*
* tp は Executors.newCachedThreadPool 等を使って生成
*/
// Rhino(JavaScript)
tp.submit(new Callable({call: function(){ return 1;}}));
// Groovy
tp.submit({1} as Callable)
@takawitter
takawitter / ScalaInvoke.java
Created June 13, 2013 23:51
JavaからScalaを呼び出すコード。カレントディレクトリ直下のlibディレクトリに関連ライブラリ(Scala本体含む)が入っている前提。 Settingsのclasspathに利用するライブラリのjar(Scala自体のもの含む)を追加して、setByUserをtrueに。それをIMainに渡すことでクラスパスが通る。 変数bind時の出力を押さえるためにquietBindを使ってる。
package scalatest;
import java.io.File;
import scala.tools.nsc.Settings;
import scala.tools.nsc.interpreter.IMain;
import scala.tools.nsc.interpreter.NamedParamClass;
public class ScalaInvoke {
public static void main(String[] args) throws Exception{
@takawitter
takawitter / LZEnd.java
Created May 25, 2013 06:18
とりあえずLZ77.javaを改造してLZEndを実装。まだ完備辞書使ってないのでちゃんとしたLZEndではないし、圧縮率もめちゃ悪い(というかたいてい増える)。あと構築方法もLZEndのものとは異なる。でもLZEndの特徴であるランダムアクセスは実現できてるし、そのおかげで展開時に展開済み文字列にアクセスしなくても良いようになってる。
public class LZEnd {
static class Phrase{
public Phrase() {
}
public Phrase(int phraseNum, int ref, int len, char nonMatchedChar) {
this.phraseNum = phraseNum;
this.ref = ref;
this.len = len;
this.nonMatchedChar = nonMatchedChar;
}