2019年3月21日木曜日

Android Studio Kotlinで"Room cannot verify the data integrity."エラー発生

Android でRoomを使って開発中に以下のエラーが発生した場合の対処法。
Room cannot verify the data integrity. Looks like you've changed schema 
but forgot to update the version number.
You can simply fix this by increasing the version number.
デプロイ先のAVDやデバッグ実機上のDB定義と
新しいDB定義が食い違ってますよ、というエラー。

開発中はしょっちゅうDB定義を変えながら開発するので、
このエラーが出た場合は、デバッグ先のDBを初期化すれば良い。
※あくまでもDBの内容を消去しても良いと判断した場合。
 開発中といえども消したくない場合は、ちゃんと
 DBマイグレーションしましょう。

以下は、DB初期化方法。
AVDや実機でアプリ情報を開き、
ストレージ → ストレージを消去
すれば解消する。

または、実機で開発している場合は、Android Studioの
Device File Explorerからも削除可能。
/data/data/開発中のアプリケーション/database/配下

2016年5月28日土曜日

Eclipse + Gradle でGradleがうまく動かなくなったら

Eclise + Gradle を使用していたが、ある時から
Could not fetch model of type 'EclipseProject' using Gradle distribution
'https://services.gradle.org/distributions/gradle-2.2.1-bin.zip'
というエラーが出てGradleがうまく動かなくなった。

【環境】
Windows 7
Eclipse 4.4 Luna
Gradle (STS) Integration for Eclipse
(使用されてるGradle versionは2.2.1)
プロキシ使用環境

【解決策】
Gradleが動作するJVMにプロキシー設定をする。
Eclipseメニュー→ウィンドウ→設定
Gradle(STS)→引数 の
JVM引数で「使用」を選択し、以下を設定
-DproxySet=TRUE
-DproxyHost=xxx.your.proxy.server ←以下ご自身の環境のプロキシを設定してください
-DproxyPort=xxx
-Dhttp.proxyUser=xxx
-Dhttp.proxyPassword=xxx
※proxyUser, proxyPassword はプロキシ認証する場合だけ設定

【考察】
プロジェクトはTomcatで動かしているが、そういえば
デバッグしててTomcatが変な落ちかたをしたので、
タスクマネージャーからTomcatのJVMを強制停止したが、
実はTomcatではなくGradleDaemonだったかも知れない。
それでプロキシ設定がふっとんだ?

(※そもそもGradleDaemonがEclipse側のプロキシ設定を使ってて、
Eclipseを行儀よく落とせばGradleDaemon側の設定も飛ばなくて、
GradleDaemonを強制終了した場合だけプロキシ設定の連携が
吹っ飛んでしまうのか、そこらへんの内部の細かい動作は不明。
というか、GradleDaemonが裏で別プロセスとして動いていることさえ、
普通に使ってる分には知らない人の方が多いのではないだろうか?)

ちゃんとjpsコマンドでプロセスを確認してから落としましょう。
しかもWindowsだとTomcatはタスクマネージャー上だと
「 javax」だが、GradleDaemonはただの「java」だった。
javaxはいなかったと思うのでTomcatは既に落ちてたな。これは。
(つまりGradleDaemonを自分で強制終了してた!
 主犯は自分自身だった。。)

※吹っ飛んだGradleとEclipseの連携を戻せればベスト。
 'EclipseProject'あたりを設定し直せば良いのだろうか?

※ちなみにWindowsのタスクマネージャーでもjava/javaxで
 何が動いているか確認できなくもない。

タスクマネージャーを開いて、
詳細タブ → ヘッダーを右クリック → 「列の選択」
→ 「コマンドライン」にチェックを入れてOK

コマンドライン列が表示されるが、java引数は長いので、
プロセスを選択して Ctrl + c で選択行の情報がコピーできる
ので、それをテキストエディタなどに貼り付けて確認する。。。
素直にjpsを使いましょう。


2015年12月27日日曜日

Windows 10 Edge Developer Tools: Debug Tab (Javascript) is Hidden

OS: Windows 10
Browser: Edge

While you are debugging your web page by Edge's developer's tools,
Sometimes this will be occurred that only variables and breakpoints are shown in your
developer's tools window, there is no Javascript debug area.

if this was happened, then even you try to close and reopen the developer's window,
nothing will be changed, there aren't any javascript window yet.

so these below are the solutions.

1. (WISH) MS will solve this problem soon, hopefully,  so you will wait for that.
   (and I think the cause is around  dynamic tabs these are shown on loading a page, Edge wisely remember the status or something about the page.)

2. Rewind the source code area by hand
 if you can luckily find out that the edge of Edge's developer's tools window is BOLD,  like double-lined, then you can just rewind that by dragging the edge of the window.
 sometimes, it's effective to minimise and maximise the developer's tool.

2015年11月21日土曜日

HBase リージョン分割した後にクライアントが最新行キーを持つリージョンからしかデータが取れなくなった時の対処法

HBase リージョン分割した後にクライアントが最新行キーを
持つリージョンからしかデータが取れなくなった時の対処法

HBaseからとにかく全件を取得したいクライアントで起こる事象。
例えばHBaseをキューのように溜まってるデータを取ったら
消すようにして使用している場合。

具体的には org.apache.hadoop.hbase.client.Scan を何も設定せず
そのまま使用していて、HBaseサーバ側でリージョン分割が
発生した場合に現象が発生する。

これはリージョンサーバの情報をクライアントが覚えておき、
無駄な通信をしないようにする仕様から来ていると思われる。
分散システム前提のシステムをキューとして使用しようとすること
自体が設計に反しているが、それを敢えてやる場合の話である。
(上司が勘違いされている場合は、部下が必死で「HBaseを
 キュートして使うのはちょっと違いますよ。」と説得しましょう。
 HBaseはビッグデータの最終的な入れ物。前段でキューが必要なら
 RDBを使った方がよほど良い。)

1番いいのはリージョン分割しないようにHBaseの分割サイズを
調整しHBaseに入るデータ量を上回るように、HBaseのパラメータおよび
取得クライアント側の性能を設計することだ。

HBaseリージョンサーバの分割設計は、MemStoreのフラッシュサイズと
リージョンサーバの最大サイズの設計からなる。

フラッシュサイズは
1. 固定値(hbase.hregion.memstore.flush.size)と
2. 計算値(hbase-env.shの HBASE_REGIONSERVER_OPTSで設定するヒープサイズ ×
 hbase.regionserver.global.memstore.upperLimit and lowerLimit)
で調整できる。
(フラッシュとは、メモリからディスクへのフラッシュのこと)
また、リージョン分割のサイズは hbase.hregion.max.filesize で調整できる。


とは言ってもHBaseの仕組み上、リージョン分割は念頭に置かなければならない。
リージョン分割ありきで考えるならば、クライアントはいつ分割が発生しても
いいように備えなければならない。

単純な順かつリソース消費量の順に案を挙げていくと、
1. 毎回HTableから作り直す。
2. 毎回リージョン情報をクリアする。(HTable#clearRegionCache())
3. 開始行キーを先頭にリセットする。(Scan#setStartRow())

となるだろうか。(実際の検証はしてないのであくまで推測。)

ということで3. の開始行キーを設定する方法を紹介する。
// HTable htable = ... 
Scan scan = new Scan();

// use addFamily() when you want to set row family only, 
// but it's better to specify a column, because you're going to get 
// all of data. this column would be like a second key.
// take care of your machine's memory.
scan.addColumn(Bytes.toBytes(FAMILY_XXX), Bytes.toBytes(COL_XXX)); 

// set 0x00(null) so that HBase will scan from the first region server.
scan.setStartRow(new byte[]{ (byte)0x00} ); 

HashMap dataMap = new HashMap<>();
try(ResultScanner result = htable.getScanner(scan);) {
    for(Result item : result){
        // Row ID
        byte[] rowId = result.getRow();
         // Column data example.
        byte[] data = result.getValue(Bytes.toBytes(FAMILY_XXX), Bytes.toBytes(COL_XXX));
        // for example, get small sortable value like date_and_time value.
        dataMap.put(rowId, data);
    }
}

// then sort the sortable value using Entry<>, sort of value.
ArrayList> dataEntries = new ArrayList<>(dataMap.entrySet());
Collections.sort(dataEntries, (o1, o2) -> {
    // define how to sort between byte[].
    // for example parse byte[] to Long when the data is UNIX epoch time. (8bytes)
    Long t1 = ...   // convert with ByteBuffer or something.
    return t1.compareTo(t2);
});

// loop with sorted key list.
for( Entry  dataEntry : dataEntries){
     // then get all of columns with row id.
     // this is safer way because you can manage when you should stop the function or not.
     // you can choose resource or spec or ..
    Get get = new Get(dataEntry.getKey());
    Result result = htable.get(get);
    byte[] content = result.getValue(xxx);
    ....
}

2015年8月24日月曜日

JUnitでHBaseクライアント側を通す - How to test HBase in Unit Test process (client side)

jUnitでHBaseの擬似HTableをつくってUnit Testを通すやり方。

HBaseにつなぐソースのユニットテストを、実際のHBaseに
繋がずに通したいときに、擬似HTable(モック)を作成して
通す方法。

簡単に言うと
①HConnectionを偽装
②偽装HConnectionを使用してHTableを偽装
となる。
また、おまけで
③Scan時に擬似データを返すように擬似データを登録
することも可能。

※①②ともHBaseの内部の処理を通るため作成には
数十秒かかる。そこで通るタイムアウト絡みの
パラメータを乗っ取れば(リフレクション)高速化できる
のであろうが、そこまでは追わなかった。

いろいろ試した結果、この方法に辿り着いた。

一応試行の遍歴を記すと、
・実際にHBaseに接続した時のHTableオブジェクトを
 シリアライズ化して保存し、それを復元する試行。
→引数なしのHTableコンストラクタが定義されてないので
 エラー。

※そもそもシリアライザを継承してないのでシリアライズしても
 表面上のパラメタだけしか取得できない。
 そこでJSON化を試し、それなりの情報が取得でき、それの
 復元化(復元マッパの登録)まで出来たが、やはり最後は
 コンストラクタ呼び出しがされるので、引数なしコンストラクタ
 未定義でエラー。

ダメかと思ったが、HTableはHConnectionを引数にするコンストラクタが
あるのでHConnectionの偽装、それを使用してしかも -ROOT- を指定する
ことでHTableのコンストラクタを通すことができた。

HBase、Hadoopを内部から理解されてる方ならHBaseクライアントの
Unit Test方法は一般的なのかもしれないが、取っ掛かもなくいきなり
HBaseクライアントのUnit Testをする必要が生じた方々はこれを
参考にしていただければ。一助になれば。

以下、テストクラスのコードサンプル。
// Prepare the configuration
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "127.0.0.1");

// 1.Create HConnection - HConnectionの作成
HConnection con = ... 
// make HTable with table name "-ROOT-" and set isClosed to false.
// prepare class loader
// get inner HTable's implemented class
// get "isClosed" member
Field fld = cls.getDeclaredField("isClosed");
fld.setAccessible(true);
fld.set( ... 

// 2.make HTable mock with -ROOT- table , so that it will work.
// 「-ROOT-」テーブルのHTableモックの作成。 
HTable tbl = new HTable("-ROOT-", con);

// 3. you can put the data of htable with reflection.

2015年3月2日月曜日

Oracle 目的のサイズのアーカイブログ作成方法

目的のサイズのアーカイブログ作成方法

方法1:REDOログファイルのサイズを目的のサイズで作成して自然にログスイッチさせる。
方法2:オンラインREDOログのサイズを確認して、目的のサイズになったら手動でログスイッチする。

方法1の場合、環境作成後だとREDOログファイルを作り直さなければならず面倒。
また、試験は本番環境と同じ条件で実施したいだろうから、REDOログファイルの
作り直しとかはあまりやりたくない。

よって以下では方法2のやり方を記載する。

1. ログスイッチしてサイズを0リセット
alter system switch logfile;

2. 開始時点の【生成済みREDOログサイズ】を確認
select value from V$SYSSTAT where name = 'redo size';

3. 任意のSQLを大量投入

4. 【生成済みREDOログサイズ】を確認して、開始時点との差分から
 現在のオンラインREDOログサイズを算出。
select value from V$SYSSTAT where name = 'redo size';

5. 目的のサイズになったらログスイッチ
alter system switch logfile;