歩行訓練

おいっちにー!

Windows10 で pip install

 これの環境を作っていたら、cmdでpip installしろという解説があった。

東京大学のデータサイエンティスト育成講座 ~Pythonで手を動かして学ぶデ―タ分析~

東京大学のデータサイエンティスト育成講座 ~Pythonで手を動かして学ぶデ―タ分析~

 

 でも実際やってみると、「pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.」とか出るので、インストールできない。

stackoverflow.com

Anaconda Promptを使うか、3つのロケーションをPathに入れろという事だった。

Anaconda Promptを使ったら1発成功した。

ついでに、本に書いていないPath「\Anaconda3\Library\bin」を追加してみると、cmdで出てくるコンソールでpip出来るようになった感じがする。

出来なかったらごめんなさい。

バイクで風が強い日のアクアラインの渡り方

強風のアクアラインをバイク通勤している者がここに記す。カモメが空中に止まって見えたらそろそろ危ない。アクアラインの攻略方法をここに纏める。

まとめ

  1. 情報を集める
  2. ガソリンを満タンにする
  3. 風を読む

1. 情報を集める

まずは情報を集める。何時間後にどれぐらいの風速であるか。現状どうなっているか。今渡れるかどうかなどを調べる。その際に利用するWEBサイトは3つ。

GPV気象情報

まずはここで、アクアラインを通る時間帯の風速予報を確認する。

エリアを「関東」にして、「気圧・風速」をクリック。アクアラインを通る予定の時間にまでスライダーを合わせる。

この時にアクアラインのある辺りがピンク色や赤色の風速予報になっている場合は、アクアラインを通るのはあきらめた方が良い。本当に怖い思いをすることになる。1時間後に風が止んでいたら1時間待つことをお勧めする。

weather-gpv.info

海の安全情報

現在のアクアライン周辺の風速が確認できる。ここで風速が18Mとか書かれている場合、恐怖体験をしながら渡れる状態であるが、下手するとそのうち閉鎖される可能性がある。

海の安全情報(沿岸域情報提供システム)

 

アクアライン交通ナウ

ここは、風速だけでなく高速の情報も取得できる。渋滞をしているかどうかや、閉鎖されているかどうかが確認できる。週末のアクアラインは14時を超えると確実に渋滞する。バイクだけじゃなくて、高速バスがちゃんと流れているか、風速が強すぎてアクアラインが閉鎖されているかどうか確認できる。渋滞していると羽田空港から乗れるアクアラインを渡るバスも遅れているという事になる。

アクアライン交通情報ナウ

 

2. ガソリンを満タンにする

風が強くてどうしようもないけど、渡らなくてはいけない時がある。その時はまず、ガソリンを満タンにすることをお勧めする。

バイクの重さが重いほうが突風に飛ばされづらくなる。私の通勤バイクはマジェスティーの250CC。ガソリンが半分の状態で強風を吹かれるとかなり影響を受けてふらふらするが、ガソリンが満タンの場合は安定感が違う。風速12Mぐらいでガソリン満タン状態なら特に吹っ飛ばされるような怖いことは無い。

 

3. 風を読む

吹き流しを信じてはいけない。風は逆に吹くこと部分がある。これを知らないとかなり怖い体験をすることになるだろう。

アクアラインの高い場所は吹き流しとは逆の向きの風が吹く。たまにかなりの突風が吹き流しの方向へ吹く。これが怖い。非常に怖い。

吹き流しとは逆の方向に耐えながら、強風は耐えている方向に吹く。これを食らうとかなり吹っ飛ばされる。この強風を読む必要がある。

読み方は簡単、軽い車の後ろにつくか、バスなどのデカい車の後ろについて、前の車が流されるかどうかを確認しながら進めばよい。

強風が吹いている場所は同じなので、バスや軽車両が流された地点では強風が直撃する。分かっていれば怖くない。

 

4. その他

スピードを落とす。落とせば怖い思いをする時間も長くなる。そう。逆にスピードを出してしまうのも一つの手である。特にアクアラインの高い部分は非常に怖いので、吹き飛ばされないならば勇気を出して通り過ぎてしまった方が良い。

 

千葉に住んで2年が経とうとしている。年中バイク乗れるし、家賃は安くて部屋も広い。アクアラインは晴れていればとても見晴らしが良いので楽しい。千葉も凍結しないし2月でもバイクで走れる素晴らしい所だと思う。でも週末になるとアクアラインは渋滞するので、東京へ通勤する場合は緊急時に移動できるようにバイクが必要になる。強風を攻略してみんな千葉に住もう!

Tomcat の Session relipcation で ReplicationValve が悪さをしてセッション共有できなかった

Tomcat 公式のドキュメントにある ReplicationValve

Apache Tomcat 8 (8.5.6) - Clustering/Session Replication HOW-TO

 

サンプルの一番簡単な場合では

<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                 filter=""/>

 とあるが、次のサンプルでは

<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/>

となっている。

よく見ると「.htm」と「.html」もフィルターに含まれているので、htmlファイルがフィルターされて「hoge.html」などのファイルだとセッションが共有できない。
さらにこの状態だと、「index.html」を指定しないで「/hoge.com/hogehoge/」などにアクセスする場合はセッションが共有できる状態になる。
そのため、あるパターンでは全くセッションが共有できなくなり、あるページではセッションが共有できている状態になる。

この状態だと、どの状態で共有が失敗しているのかわからなくなって、「なんかTomcatのセッションが不安定でわけわからん」という状態になって途方に暮れてしまう。

というか途方に暮れた。

<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.css|.*\.txt"/>

 こんな感じに削れば良い

Spring boot で application.properties の spring.messages.basename を使わずに国際対応をした感出したい

やりたいことは、application.properties の spring.messages.basename を使わずに国際対応をしたい。前々回辺りに書いた ValidationMessages.properties を流用したい。つまり、デフォルトの機能を使わずになんとか楽したい。

 

ResourceBundleMessageSource を使う場合。

ReloadableResourceBundleMessageSource (Spring Framework 4.2.2.RELEASE API)

 

問題はこのResourceBundleMessageSource がUTF-8ではなく、ISO-8859-1で文字列を持ってくる点だけど、よく考えたら変換すればいいだけだった。

import java.util.Locale;

import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.stereotype.Service;

@Service
public class I18nMessageService
{
    private final String VALID_MSG_FILE = "i18n/ValidationMessages";
    private ResourceBundleMessageSource validRb;
    public I18nMessageService()
    {
        validRb = new ResourceBundleMessageSource();
        validRb.setBasename( VALID_MSG_FILE );
    }
    
    public String getValidationMsg( String propStr, Locale locale )
    {
        String msg = validRb.getMessage( propStr, null, locale);
        return toUtf8( msg );
    }
   
    private String toUtf8( String str8859 )
    {
        String strUtf8 = str8859;
        try {
            strUtf8 = new String( str8859.getBytes( "ISO-8859-1" ), "UTF-8" );
        }catch ( Exception e ){
        }
        return strUtf8;
    }
}

ここでファイルへのパスに前回同様「classpath:」で指定するのかな、と思って入れてみたら動かなかった。なんでなんだ・・・?

 

じゃあ、前回と同様に ReloadableResourceBundleMassageSource使えばいいんじゃね。

import java.util.Locale;

import org.springframework.context.MessageSource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Service;

@Service
public class I18nMessageService
{
    private final String VALID_MSG_FILE = "classpath:i18n/ValidationMessages";
    private MessageSource validMs;

    public I18nMessageService()
    {
        validMs = getMessageSource( VALID_MSG_FILE );
    }
    
    public String getValidationMsg( String propStr, Locale locale )
    {
        return validMs.getMessage( propStr, null, "", locale );
    }
    
    private MessageSource getMessageSource( String filePath )
    {
        ReloadableResourceBundleMessageSource validRb = new ReloadableResourceBundleMessageSource();
        validRb.setBasename( filePath );
        validRb.setDefaultEncoding( "UTF-8" );
        return validRb;
    }
}

 こちらも動いた。こちらは「classpath」付き。うーん。

Spring boot で AbstractHttpSessionApplicationInitializer とか使うと tomcat で死ぬ

リファレンスを斜め読みすると死ぬ。

 

リファレンスはここ。

Spring Session

 

ここを斜め読みすると、2つファイルを作れば良い、という空気を感じてしまう。

  1. Config.java
  2. Initializer.java

で、実際作ってみると、Spring Application で起動する場合は何も起こらない。がTomcatで起動しようとすると

重大: One or more listeners failed to start. Full details will be found in the appropriate container log file
10 18, 2015 6:37:49 午後 org.apache.catalina.core.StandardContext startInternal
重大: 以前のエラーのためにコンテキストの起動が失敗しました [/hoge]

localhostの方は

重大: クラス org.springframework.web.context.ContextLoaderListener のリスナインスタンスにコンテキスト初期化イベントを送信中の例外です
java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple
ContextLoader* definitions in your web.xml!

 とか言われ路頭に迷ってしまう。

 

リファレンスをよく見ると、Spring Bootは別のリンクがあって

Spring Session - Spring Boot

こっちはもうほんと書く量がなくて

github.com

このリンクの量だけで済む。1ファイルだけ。

この少なさは悩んだ時間に対して、かなりダメージが大きい。書き換えたらTomcat上で動いた。今度からはきちんとリファレンスを読もう・・・

JDK8にバージョンアップするときに -Xss128k とか書いてあると死ぬ

The stack size specified is too small, Specify at least 228k
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

 とかエラーが出て起動しない。

 

オプションを消せば動いた。

どうも本番環境だけパラメータを前任者が触っていたのに気付かず、危うく障害になるところだった。JDK1.6から1.8へのバージョンアップ。

なぜスタックのサイズを下げたのか。とりあえず、テスト環境と本番環境に差を作るのは本当にやめてほしい。

Spring boot でValidationMessagesが文字化けするのをなんとかする。

Validationのエラーメッセージを国際化する方法を探していると、こういう記事があった

stackoverflow.com

ここで書いてあることは

  1. ValidationMessages.propertiesってのをresourcesのルートに置く
  2. @Digits(fraction = 0, integer = 3, message="{message.key}")って感じに書く

とのこと。実際やってみると、出来たことはできたのだが文字化けを起こした。

この文字化けどうやって直すのだろうと思って探すと

 

tono-n-chi.com

@Configurationなクラスに以下を貼っとけばOK。

と書いてあるが、そんなわけもなく、これでは動作しなかった。

他を探してみると

www.silverbaytech.com

という記事が見つかる。

ここでは

@Override
public Validator getValidator()
{
    return validator();
}

 って書いてあるので、これが足りない模様。でもどのクラスがこれを持っているのか。

WebMvcConfigurerAdapter (Spring Framework 4.2.1.RELEASE API)

の一番下にあった。

ということは、みんなやっているであろうPOSTメッセージのUTF-8化とかで持っているクラスに追記すればよいことになる。

他にも、「classpath:」と書いてあるので、resourcesのルートに置く意味もなくなる。同様にValidationPropertiesというファイル名にこだわる必要もなくなる。

実際にちゃんとそのパスが読めているのか不明なので、resouces配下にi18nというパッケージを作り「unko.properties」「unko_ja.properties」というファイルを用意して、jaの方に日本語のエラーメッセージを用意する。

procedure.hogehoge.check=unko / english

↑unko.properties

procedure.hogehoge.check=日本語おおお。japanese

↑unko_ja.properties

 

@Configuration
public class WebMvcConfig
extends WebMvcConfigurerAdapter
{

    @Bean
    public FilterRegistrationBean
    getFilterRegistrationBean()
    {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter( new CharacterEncodingFilter() );
        return filterRegistrationBean;
    }

    
    private static class CharacterEncodingFilter
    implements Filter
    {
        protected String encoding;

        public void init( FilterConfig filterConfig )
        throws ServletException
        {
            encoding = StandardCharsets.UTF_8.name();
        }
        
        public void doFilter( ServletRequest servletRequest
                            , ServletResponse servletResponse
                            , FilterChain filterChain )
        throws IOException, ServletException
        {
            HttpServletRequest request = ( HttpServletRequest )servletRequest;
            request.setCharacterEncoding( encoding );
            filterChain.doFilter( servletRequest, servletResponse );
        }
                
        
        public void destroy()
        {
            encoding = null;
        }
    }
    
    @Override
    public Validator getValidator()
    {
        return localValidatorFactoryBean();
    }

    @Bean
    public LocalValidatorFactoryBean localValidatorFactoryBean()
    {
        LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
        bean.setValidationMessageSource( messageSource() );
        return bean;
    }
 
    @Bean
    public MessageSource messageSource()
    {
        ReloadableResourceBundleMessageSource bean = new ReloadableResourceBundleMessageSource();
        //bean.setBasename("classpath:/i18n/ValidationMessages");
        bean.setBasename("classpath:/i18n/unko");
       bean.setDefaultEncoding("UTF-8");
        return bean;
    }
}

これの下3つのクラスが今回の話で追加したメソッド

@Data
public class HogeFormData
{
    @Min( value=1, message="{procedure.hogehoge.check}" )
    int hogyaaa;

 こんな感じで呼び出すと日本語の表示に成功した。