2013年10月21日月曜日

Windows Defenderの自動定義更新

Windows Defenderの定義更新はWindows Updateに統合されていて
自動更新させようとするとWindows Updateの自動更新も起動してしまいます。
そうすると勝手に再起動されて困ります。


そんなときに試したいのが
Windows Defenderの定義のみを更新するコマンドです

これ、

"C:\Program Files\Windows Defender\MpCmdRun.exe" -SignatureUpdate


私は、プロンプトの表示を避けたいので
下のようなvbsファイルを作成してTaskスケジューラに登録しています


WindowsDefenderUpdate.vbs :

Set ws = CreateObject("Wscript.Shell")

ws.run "cmd /c ""C:\Program Files\Windows Defender\MpCmdRun.exe"" -SignatureUpdate", vbhide


2013年10月5日土曜日

JAXB アノテーションを利用したJSON マッピング

Jerseyを使っているとレスポンス用のJSONの定義クラスに
アノテーションの@XmlTransitで省略したり
@XmlElement(name="element")で名前変更したりして
ObjectをJAXB経由でJSONに自動でパースさせてたりしますが
その定義を他でも使いまわして各々の処理でJSON文字列にパースする場合には

JacksonJAXBAnnotations

を利用すればいいです。

これは利用すればJAXBアノテーションを利用したマッピングが可能です。


mavenでpom.xmlに追加

        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-xc</artifactId>
            <version>1.9.13</version>
        </dependency>



Javaでは次のようにするればobjをJSONにパース可能
例ではやってないけどObjectMapperはthread safeなので使いまわしましょう

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;
import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;


…
        JaxbAnnotationIntrospector introspector  = new JaxbAnnotationIntrospector();
        ObjectWriter ow = new ObjectMapper().setAnnotationIntrospector(introspector).writer()
                .withDefaultPrettyPrinter();
       
        String json = ow.writeValueAsString(obj);

       


最初は、jerseyの内部ロジックを利用しようとしましたが
ひとつのオブジェクトしかないリストがオブジェクトでパースされる問題が発生したり
いちいちクラスタイプ指定しないといけないので面倒でやめました


ちなみに 最初はこんなかんじにしてました

        private Class[] types = {
            MyClass.class,  

            ArrayList.class,
        };


        String result = null;
        JSONConfiguration config = JSONConfiguration.natural().build();
        JSONJAXBContext ctx = new JSONJAXBContext(config, types);
       
        JSONMarshaller m = ctx.createJSONMarshaller();
        StringWriter sw = new StringWriter();
        m.marshallToJSON(xmlObj, sw);
        result = sw.toString();

        return result;



JAXBContextResolverと似たような感じですね
POJOMappingFeatureで問題はどうにかなるかと思ったんですが
JacksonJAXBAnnotationsを使ったほうが楽だし早い

2013年9月21日土曜日

J2EE (jetty) アプリケーション初期化処理

J2EE のリスナーの話です

基本のリスナーの使い方は覚えないといけないなー
と思いながら全然すすまない

まずは初期化処理から
初期化時にはDBからマスタの読み込みとかします


package com.gauuud.StartUp;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;


public class InitDB implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //初期化処理       
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        //終了時処理

    }

}


web.xml :

<listener>     
        <listener-class>com.gauuud.StartUp.InitDB</listener-class>
</listener>


余談になりますが
マスタは起動時にメモリ上に全部読み込むようにするべきですよね
最近のサーバはメモリ多いし(マスタとか10Mもいかないだろうし
クラスタ構成が多いので更新時に再起動でサービスが止まることもないし

2013年9月20日金曜日

Java Tripletクラス 3つの組みあわせ

2つの値を一つの組にまとめて比較やMapのキーにしたり
することがある場合は、

commons-langのTupleを使えばいいのですが
3つ必要 だという場合には自分で定義する必要があります。たぶん



Triplet.java:


import java.io.Serializable;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.builder.CompareToBuilder;

public class Triplet<X, Y, Z> implements Comparable<Triplet<X, Y, Z>>,Serializable {

    private static final long serialVersionUID = -7986546850125833527L;

    public X x;

    public Y y;

    public Z z;

    public static <X, Y, Z> Triplet<X, Y, Z> of(X x, Y y, Z z) {
        return new Triplet<X, Y, Z>(x, y, z);
    }

    public Triplet(X x, Y y, Z z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public X getX() {
        return x;
    }

    public void setX(X x) {
        this.x = x;
    }

    public Y getY() {
        return y;
    }

    public void setY(Y y) {
        this.y = y;
    }

    public Z getZ() {
        return z;
    }

    public void setZ(Z z) {
        this.z = z;
    }

    public int compareTo(Triplet<X, Y, Z> other) {
        return new CompareToBuilder().append(getX(), other.getX())
                .append(getY(), other.getY()).append(getZ(), other.getZ())
                .toComparison();
    }

    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj instanceof Triplet<?, ?, ?>) {
            Triplet<?, ?, ?> other = (Triplet<?, ?, ?>) obj;
            return ObjectUtils.equals(getX(), other.getX())
                    && ObjectUtils.equals(getY(), other.getY())
                    && ObjectUtils.equals(getZ(), other.getZ());
        }
        return false;
    }
   
    public int hashCode() {
        // see Map.Entry API specification
        return (getX() == null ? 0 : getX().hashCode())
                ^ (getY() == null ? 0 : getY().hashCode())
                ^ (getZ() == null ? 0 : getZ().hashCode());
    }

    @Override
    public String toString() {
        return new StringBuilder().append('(').append(getX()).append(',')
                .append(getY()).append(',').append(getZ()).append(')').toString();
    }
}




commons-lang3が必要です。
Tupleを真似してみただけですが割りと使います^^;

3つのPKをもつデータをMapに登録するとか

JavaでTimeSpanクラス

TimeSpanクラスとはなんぞやというと
Date と Dateを比較した差分を保持するという単純なクラスです#

Calendarクラス使えばいいと思われますが
static final な fieldの定義とか結構めんどくさい



TimeSpanクラスで7日の差分を定義すると

public static final TimeSpan TIMESPAN = TimeSpan.Days(7);


で現在と差分を足したDateを求めるには、

Date date = TIMESPAN.getDate(new Date());

とすればいい。


何に利用するかというと主に
Memcachedに渡すExpireの 定義とかです。


Memcached.get(key, new Memgetable<String>() {
    public String get() {
        return value;
    }
}, TIMESPAN.getDate(new Date()));



こんな風に記述ができます。




TimeSpan.java : stackoverflowを参照したような…参照元は失念


import java.util.Date;

import org.apache.commons.lang3.time.DateUtils;

public class TimeSpan {
    private int millis;

    public TimeSpan(int millis) {
        this.millis = millis;
    }

    public TimeSpan(Date source, Date dest){
        millis = (int)(dest.getTime() - source.getTime());
    }
   
    private TimeSpan() {
    }

    public int getDays() {
        return this.getTotalHours() / 24;
    }

    public int getTotalHours() {
        return this.getTotalMinutes() / 60;
    }

    public int getTotalMinutes() {
        return this.getTotalSeconds() / 60;
    }

    public int getTotalSeconds() {
        return (int) (this.millis / 1000);
    }

    public long getTotalMillis() {
        return this.millis;
    }

    public TimeSpan addDays(int days) {
        return addHours(days * 24);
    }

    public TimeSpan addHours(int hours) {
        return addMinutes(hours * 60);
    }

    public TimeSpan addMinutes(int minutes) {
        return addSeconds(minutes * 60);
    }

    public TimeSpan addSeconds(int seconds) {
        return addMillis(seconds * 1000);
    }

    public TimeSpan addMillis(int millis) {
        this.millis += millis;
        return this;
    }
   
    public Date getDate() {
        return new Date(this.millis);
    }
   
    public Date getDate(Date currentDate) {
        return DateUtils.addMilliseconds(currentDate, millis);
    }

    public static TimeSpan Days(int days) {
        return new TimeSpan().addDays(days);
    }

    public static TimeSpan Hours(int hours) {
        return new TimeSpan().addHours(hours);
    }

    public static TimeSpan Minutes(int minutes) {
        return new TimeSpan().addMinutes(minutes);
    }

    public static TimeSpan Seconds(int seconds) {
        return new TimeSpan().addSeconds(seconds);
    }   
   
    public static TimeSpan Millis(int millis){
        return new TimeSpan(millis);
    }

    public static TimeSpan Span(Date source, Date dest){
        return new TimeSpan((int)(dest.getTime() - source.getTime()));
    }
}



TODO:TimeSpan同士の比較

追記
2014/01/23 Java 8でのDurationによる代替方法→ここ
 

jquery cdn 止まった時には

https://ajax.aspnetcdn.com/ajax/最近たまに止まりますね
jquery.tmpl.jsがあるから使ってるのに…

そういう時の対策として
jquery.tmpl.js読み込めてない場合に自前のjsを読み込むようにする


jqueryの場合は、htmlに下記を追加

<script>
window.jQuery || document.write(unescape("%3Cscript src='js/jquery-1.6.2.min.js'%3E%3C/script%3E"));
</script>




jquery.tmplの場合は、htmlに下記を追加

<script>
$.tmpl || document.write(unescape("%3Cscript src='js/jquery.tmpl.min.js'%3E%3C/script%3E"));
</script>


環境によってpathとかversionは変わります
読み込み順序には気をつけましょう

2013年9月16日月曜日

JNDIのカスタムPropertyクラス2

jetty 8.1以降では

JNDI に Array を指定することが可能になっています
次のように指定可能です


web.xml



    <resource-ref>
        <description>Maintenance Property</description>
        <res-ref-name>maintenance</res-ref-name>
        <res-type>java.lang.reflect.Array</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>



jetty-env.xml



    <New id="maintenance" class="org.eclipse.jetty.plus.jndi.Resource">
        <Arg></Arg>
        <Arg>maintenance</Arg>
        <Arg>
              <Array type="com.gauuud.Property.MaintenanceProp">
                <item><New class="com.gauuud.Property.MaintenanceProp">
                    <Set name="start">2012/9/11 1:25</Set>
                    <Set name="end">2012/9/11 1:30</Set>
                    <Set name="type">10</Set>
                    <Set name="desc">test</Set>
                </New></item>
                <item><New class="com.gauuud.Property.MaintenanceProp">
                    <Set name="start">2012/9/12 1:25</Set>
                    <Set name="end">2012/9/13 1:30</Set>
                    <Set name="type">10</Set>
                    <Set name="desc">test2</Set>
                </New></item>
            </Array>
        </Arg>
    </New>




MaintenanceProp.java :



package com.gauuud.Property;

import java.util.Date;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;




public class MaintenanceProp {

    private int type;

    public int getType() {
        return this.type;
    }

    public void setType(int type) {
        this.type = type;
    }

    private Date start;

    public Date getStart() {
        return this.start;
    }

    public void setStart(Date start) {
        this.start = start;
    }

    private Date end;

    public Date getEnd() {
        return this.end;
    }

    public void setEnd(Date end) {
        this.end = end;
    }

    private String desc;

    public String getDesc() {
        return this.desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public MaintenanceProp() {}

}



MaintenancePropArray.java:



package com.gauuud.Property;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;



public class MaintenancePropArray {
    private static final MaintenanceProp[] array;
   
    public static MaintenanceProp[] get(){
        return array;
    }
   
    static {
        MaintenanceProp[] props = null;
        try {
            InitialContext ic = new InitialContext();
            Context envCtx = (Context) ic.lookup("java:comp/env");
            props = (MaintenanceProp[]) envCtx.lookup("maintenance");
        } catch (NamingException e) {
            e.printStackTrace();
        }
        array = props;
    }
}