MarkdownエディタHaroopadを使ってみた


最近、Markdownが流行っているらしいので、メモをとる時などに使っていこうとエディタを探していました。
MacだとQiitaの開発チームが作成している「kobito」が定番らしいですが、私はWindowsなのでボツ。
Windowsだと「MarkDown#Editor」がいいらしいですが、私の環境だと何故かリストが正しくプレビューされなかったのでボツ。
次に候補となった「Haroopad」がいい感じなので紹介します。

Haroopadとは

インストール方法(Windows

現在の最新版「0.12.2」を想定しています。

  1. 公式サイトにアクセス
  2. 「Download」の「Windows7,8」をクリック
  3. インストーラを実行

設定

  • 設定を説明しているサイトをみると日本語にならないなどという記載もありますが、0.12.2では初期起動から日本語で起動しました。
  • 日本語のフォントがあまりにも酷いので変更する。

ファイル > 設定 > エディタ > defaultをEdit
editor {
font-family: 'Bitstream Vera Sans Mono', 'Courier New', Courier, 'MS Gothic', 'Osaka-Mono', 'TakaoGothic', 'Hiragino Kaku Gothic ProN', 'メイリオ', monospace !important;
}

Windows, Mac, Linuxで使えるMarkdownエディタ、HarooPadを使う - Qiita
  • ビューア側のフォントを変更する

ファイル > 設定 > ビューワ > defaultをEdit
>* {
font-family:'Helvetica Neue', Helvetica, 'Hiragino Kaku Gothic ProN', Meiryo, sans-serif;
}

code {
font-family: 'Bitstream Vera Sans Mono', Courier, monospace;
font-weight: normal;
}

Windows, Mac, Linuxで使えるMarkdownエディタ、HarooPadを使う - Qiita
  • ↑にも書いてありますが、エディタとビューアは設定箇所が異なるので注意。
  • 設定変更後はこんな感じ。

  • 後、デフォルトのテーマだと文字列を選択した際の色が背景色とわかりにくいので変更したほうが良いかと思います。
    • 黒系のテーマはどれもわかりにくいので、私はdefaultを使用しています。

便利機能

  • 日付挿入
    • 「Shift + Ctrl + d」
    • フォーマットは「設定 → 一般」で選択可能。
  • Quick Markdown
    • 「Ctrl + Shift + h」か画面左下のアイコンをクリックすることで使用可能なMarkDownの記法の一覧が表示される。
    • クリックすることで挿入もされるので結構便利。
  • コードハイライトもされると記載がありますが、私の環境では確認できず。。。

JJUG ナイト・セミナー「Javaパラレル処理の最前線」に参加してきた。 #jjug

9月17日にJJUG ナイト・セミナー「Javaパラレル処理の最前線」に参加してきました。

申し込み開始の次の日?に申し込んだのですがキャンセル待ち43人目という人気っぷり。
とは言え、大体キャンセルが多く出るので余裕かと思っていたのですが、
開始2時間前になんとかいうギリギリでの参加になりました。

  • タイムスケジュール
19:00- 櫻庭祐一さん (@skrb): Legend of Java Concurrency/Parallelism
19:25- 槙俊明さん (@making): そんなリザルトキャッシュで大丈夫か?
19:50- 休憩
20:00- 久保智さん: Java EEでの話(仮)
20:25- きょんさん (@kyon_mm): Groovyで学ぶプロセス代数
20:50- 谷本心さん (@cero_t): LT: Parallel Streamを真面目に勉強してみた話

櫻庭祐一さん (@skrb): Legend of Java Concurrency/Parallelism

Javaの歴史
  • Java 1.0
    • Thread/Runnnable
    • synchronized
    • volatile
    • Object#wait など。
    • この時期は処理を切り替えて走らせていたのでコアが遊んでしまう。
  • 1.1
    • 匿名クラスが書けるようになった。

new Thread()なんて使ってる人いないですよね!

  • 1.4
    • Mostly Concurrent
    • Mark & Sweep GC
  • 5
    • Async Execution
      • Concurrency Utilities
      • Executor / ExecutorService
      • Runnnable / Callable
      • Future
    • Synchronizer
      • ReentrantLock
      • Semaphore
      • CountDownLatch
    • Threadsafe Collection
      • BlockingQueue
      • ConcurrentHashMap
      • CopyOnWriteArrayList
    • Atomic Operation
      • AtomicInteger
      • AtomicReference
  • 7
    • Multi Coreの時代になって、細かいタスクを色んなコアにばらまいて実行する。細かいから同期のコストも小さい。
    • ただ、forl/joinは書くのが面倒くさい!
  • 8
    • Project Lambda
    • ParallelStream
    • Spliterator
まとめ
  • 設計的にはThreadは独立。
  • タスクは細かくすることで同期のコストも少なくなる。

槙俊明さん (@making): そんなリザルトキャッシュで大丈夫か?

  • ここでいうリザルトキャッシュ。
  • 重い処理の結果を格納するメモリ

  • Java並行処理プログラミング」という本の内容を話す。
    • Twitterではいい本なんだけど5時代なので、最新版が欲しいとの声多数。。。
たまに見る実装の話
  • キャッシュをHashMapに突っ込む。(HashMapはスレッドセーフじゃないので×)
    • ConcurrentHashMapに変更する。
    • 実はキャッシュをうまく使えてない
    • getしてる段階ではまだputされていないので、キャッシュがうまく使えていない
  • FutureTaskを使って遅延評価
    • とりあえず最初にput。
    • 新しいFutureTaskで上書きされた。
    • FutureTaskをputする方法は本ではほとんど正解に近いと書かれているが、実際にやってみると全然ダメw
  • putではなくputIfAbsentメソッドを使う。
    • キーが存在しない場合はnullを、そうでない場合は入っているモノを返す。
    • 処理は1回しか行われず、正しくキャッシュされている。

  • Java8から
    • ConcurrentHashMapのcomputeIfAbsentメソッドが追加。
    • Mapに値が入っていなかったらラムダ式を実行する。

まとめ
  • ConcurrentHashMap#putIfAbsent + FutureTaskを使う。
  • 8からは
    • ConcurrentHashMapのcomputeIfAbsentメソッドを使う。
  • GoogleのguavaのMapMakerが色々便利らしい。
  • JavaEE8のJCash?とかいうのがいいらしい。

20:00- 久保智さん: Java EEでの話(仮)

元はLTで発表した内容と言うことで早かったので内容を適当にまとめ。

  • レガシー枠との事。
  • Java EEの昔話
  • 並行処理でハマった内容
JavaEEの昔の話。
  • 並行処理は難しい。
    • SingleThreadModel → スレッドセーフになっていない。
    • 現在は非推奨
  • JavaEEの仕様を決める人でも間違えることがあるので、どんどん失敗しましょう
SimpleDateFormat
  • 昔はJavaDocにスレッドセーフでないと記載されていなかった!(今は記載されている)
  • JavaDocにスレッドセーフと書いてないものはスレッドセーフではない!!

System.out
  • 複数スレッドから同時に書き込むとブロックする
    • ログ出力ライブラリを使いましょう

Servletのスコープ
  • HttpSessionスコープにはハマる。
  • ブラウザ単位で同時にアクセスされる可能性がある。
  • アクセス時には安全のためロックしましょう
  • ロックできない箇所がある。
    • HttoSession#invalidate()
    • セッションを破棄するメソッド。
    • Tomcatだと実装を直接扱えば破棄されているかを判定するメソッドがある。
JSF/CDIの場合
  • 複数スレッドからの同一オブジェクトへのアクセスはブロックされている。
  • 何でもかんでもSingletonにすると逆に性能劣化が。
  • スコープは適切に扱いましょう。
Ejb
  • Stateless SessionBean
    • 状態を持たないSeessionBean
  • コンテナのプールにもつ事で同じインスタンスに複数スレッドから同時にアクセスされることはない
  • コンテナのプールはデフォルトでは無効化されていることが多いので開発環境では毎回インスタンスが生成されている
  • 本番に乗せた途端複数のスレッドで使いまわされてハマる。
  • Stateless SessionBeanに状態を持たせるのはやめましょう。
JPAのキャッシュ
  • PKの比較を比較することでキャッシュされているか判別する。
  • その比較に時間がかかると、キャッシュすることで遅くなることがある。
  • JPAの楽観ロック
  • @versionアノテーションを付けるだけで楽観ロックができる。
  • 複数スレッドからの同時更新を防ぐ
  • JPQLからのupdateでは楽観ロックが有効にならない
  • L2キャッシュは性能が問題にならない限り切っておきましょう
CDIの非同期処理
  • @Asynchronousを付けるだけで非同期処理になる。
  • 簡単だけど障害時を考えるとそれでよいのか。
  • 簡単に使えるからといってすぐ何でもかんでも使うのではなく、よく考えて使いましょう。

20:25- きょんさん (@kyon_mm): Groovyで学ぶプロセス代数

  • CSPというと怖いように思うが、こうやって触っていけばいいんだよね。というようにしたい。
  • CSPとは、並行処理のモデルとして利用されているプロセス代数の一例。
    • 並行処理関連で「チャネル」が云々とか言われたらCSPかな?って思って聞くといいかも。
  • 研究者と実績がたくさん
  • Java、Groovyで使用可能。
  • 逐次実行と平行実行の比較
    • 逐次実行だったらあまり間違わないところでも、平行実行にするだけで難しくなることがよくある。
  • FDRというツールで、CSPとほぼ同等の記法のスクリプトを書くと検証してくれる。
    • 最初に逐次実行で書いて、並列で書くとどの程度同一か判定してくれる。
  • CSPをJava実装したものがJCSPというライブラリとして公開されていて、GParsはJCSPをラップしている。
  • Groovyの2.0からGParsは標準で入っている。

  • groovyx.gpars.云々パッケージにいい感じにクラスが定義されているのでこれらを使っていく。
    • JCSPはもっと色々あるけど、gparsがラップしてるのはこれくらい。
  • チャネルを通してでしかプロセス間でやりとりできない。

  • 正直、この後の内容は前提知識が足りなくて理解できず。
    • コードをたくさん載せてくれているので、動かせばわかるか?(探したけどスライドは公開されていない??TT)

  • チャネルは同期的に動作し、プロセスは非同期で動作する。電話みたいなもの(電話かけても相手が受け取らないと始まらない)

まとめ
  • CSPを使ってみるとかいうとハードルが高いけど、Gparsを使うと結構簡単に試せる。
  • モデルとコードが近くなりやすいCSPで書いておくとツールでの検証がはかどるし、
  • 検証してからコードに書くのも困らない。
  • 非同期処理のプロジェクトで失敗したのをキッカケに取り組み始めた。
    • 今はCSPベースの何かを開発している!
  • CIサーバ、テスティングフレームワーク、ビルドツールとかを作っている!

20:50- 谷本心さん (@cero_t): LT: Parallel Streamを真面目に勉強してみた話

  • Java8といえばStream。
    • Parallel Streamは面白い!
  • StreamAPIをパラレルで行えるのがParallel Stream
  • Parallel Streamにしても性能が出ない
    • 素数が少ないと性能がでない
    • 10万要素ぐらいを捌かないと効果がないと感じている。
    • 落とし穴はいっぱいある
    • Parallel Streamは例外時の挙動が予想できない。
    • 例外が発生しても、例外が発生したスレッド以外は実行する。
    • 例外が発生した時点で割り当てられている処理は行われるが、割り当てられていない処理は実行されない。
    • 一回の処理の中では例外が発生しないようにするか、例外をtrycatchして処理するようにしないと、色々ハマる。
    • ストリーム内でDBにアクセスするとかありえない。
    • それ以前にストリームの外にある変数にアクセスしたらダメ。

gitでGlobalに設定したConfigの実態

結論

「~/.gitconfig」に記述されている。

経緯

「git config」でglobalに設定の際に以下のメッセージが出た。

$ git config --global user.name yamap_55
warning: user.name has multiple values
error: cannot overwrite multiple values with a single value
       Use a regexp, --add or --replace-all to change user.name.

コマンドをウル覚えで、「=」付けたり、どこかのblogのコマンドそのまま(値の所に記号あり)実行していたため、同Keyで複数の値が設定されてしまった様子。

通常の場合、「git config --global --unset-all user.name」 「git config --global --unset user.name」などで直接ファイルをいじることなく設定を解除できるらしいですが、何故か解除できませんでした。
localのconfigは「リポジトリ/.git/config」にあるのは知っていたので、「~/.git/config」とかと思ったらそうではなく、↑の通り「~/.gitconfig」にありました。
基本過ぎるからか、全然みつからなくてかなり困ったのでメモ。

#jjug ナイト・セミナー「ビール片手にLT&納涼会」に参加してきました。

概要

2014/08/22(金)に開催された「JJUG ナイト・セミナー 「ビール片手にLT&納涼会」」に参加してきました。

名前の通り、酒飲みながらのんびりLTを見るという感じのイベントです。
毎年この時期に行っていますが、今年もお酒とピザでリラックスしながら楽しめました。
っというか飲み過ぎました。。。orz

内容は↓のLT内容を見てもらえばわかると思いますが、
最初からJVMのコードの説明があったり、perlの人がいたり、フレームワークScala、Groovy、Gradle、AWTっと、ほんと様々でした。
個人的に一番印象に残ったのは「喋るJava!」です。
Javaから音声合成ソフトウェアの「VoiceText」のAPIを呼び出して、しゃべります。
実用としてはJenkinsのビルドがコケた時に実行する位かもですが、実に楽しめました。
いつものようなまっとうな(?)勉強会もいいですが、こういうのもいいですね!

発表者のblog
youtube

外部の勉強会というとハードルが高いイメージがありますが、このようなイベントもあったりしますし未体験の方は行ってみるといいと思います!一緒に行きましょー!

LT内容(下記Youtubeのページより)

  1. くぼたゆうじ (楽して) JVM を学びたい
  2. Benchmark.javaベンチマークをささっとやる話
  3. Quasar: Javaのアクター/軽量スレッド 宮川 拓 @miyakawa_taku
  4. レガシー脳なJavaシステム担当者が改めてStream APIに挑戦してみた。
  5. Stream脳の作り方 もちださん - @mike_neck
  6. 共変戻り値型について
  7. みんな大好き(?) EJB @kikutaro_
  8. Ninja Framework使ってみた @eiryu
  9. 岡野忍 PlayFrameworkとの出会い
  10. Skinny Frameworkをつかってみました @fukai_yasu
  11. 文書自動チェックツール作ってみた(Javaで) 伊藤 敬彦
  12. Botを使った業務効率化 / Java8を使ったBot実装効率化 @yusuke
  13. ある男がJavaエンジニアからフロントエンジニアになった話
  14. GradleではじめるGroovy @grimrose
  15. 喋るJava!
  16. たにもとしん みんなセミナー出ましょう
  17. 牧野 隆志 心は(Java)ソフトウェアエンジニア、仕事は経営者のすゝめ
  18. JavaエンジニアからPPT職人になってJavaエンジニアに戻って苦労する人の話
  19. いまさら触るAWT

GroovyのStringを引数に取るDateのコンストラクタは「1582/01/01」-「1582/10/14」の期間に予想外の値を返す

そもそもコンストラクタだけなのかどうかも調べてないですが。。。

結論

Groovyで「1582/01/01」〜「1582/10/14」は正しく日付がとれなかった。

  • 少なくてもStringを引数に取るコンストラクタを使用した場合。(他は調べてない。)
assert new Date("1582/10/15") as String == "Fri Oct 15 00:00:00 JST 1582" // 1582/10/15以降は正常
assert new Date("1582/10/14") as String == "Thu Oct 04 00:00:00 JST 1582"
assert new Date("1582/10/05") as String == "Tue Sep 25 00:00:00 JST 1582"
assert new Date("1582/10/04") as String == "Mon Sep 24 00:00:00 JST 1582"
assert new Date("1582/01/01") as String == "Fri Dec 22 00:00:00 JST 1581"
assert new Date("1581/12/31") as String == "Sun Dec 31 00:00:00 JST 1581" // 1581/12/31以前は正常
assert new Date("1581/01/01") as String == "Sun Jan 01 00:00:00 JST 1581"
assert new Date("1000/01/01") as String == "Mon Jan 01 00:00:00 JST 1000"
  • 多分、Groovyで追加しているこのコンストラクタの実装がそんな感じになっている。
  • っというか、多分そこで使っているJavaのクラスの仕様だと思われる。

環境

[c:\]
$ java -version
java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) Client VM (build 25.20-b23, mixed mode, sharing)
[c:\]
$ groovy -version
Groovy Version: 2.3.4 JVM: 1.7.0_51 Vendor: Oracle Corporation OS: Windows 7

蛇足というかなんでこんな事に気づいたとか。

  • ↓を読んで、Groovyで試してみたら予想外な値を返してビックリする。

いろんなプログラミング言語で1582年10月5日を扱ってみる| mwSoft

  • 下記のコードは正しく動かないのは何故?
def d = "1582/10/05"
Date dt1 = new java.text.SimpleDateFormat("yyyy/MM/dd").parse(d);
assert dt1 == new Date(d) // Assertion failed
  • Javaは「1582/10/05」を渡すと「1982/10/15」として処理されるけど、GroovyのStringを引数にとるコンストラクタに「1582/10/05」を渡すと「1582/09/25」となる。っという事に気づく。
def d1 = "1582/10/05"
def javaDate1 = new java.text.SimpleDateFormat("yyyy/MM/dd").parse(d1)
assert javaDate1 as String == "Fri Oct 15 00:00:00 JST 1582"

def groovyDate1 = new Date(d1)
assert groovyDate1 == "Tue Sep 25 00:00:00 JST 1582"
  • で、↑の結論に至るという話。
assert new Date("1582/10/15") as String == "Fri Oct 15 00:00:00 JST 1582" // 1582/10/15以降は正常
assert new Date("1582/10/14") as String == "Thu Oct 04 00:00:00 JST 1582"
assert new Date("1582/10/05") as String == "Tue Sep 25 00:00:00 JST 1582"
assert new Date("1582/10/04") as String == "Mon Sep 24 00:00:00 JST 1582"
assert new Date("1582/01/01") as String == "Fri Dec 22 00:00:00 JST 1581"
assert new Date("1581/12/31") as String == "Sun Dec 31 00:00:00 JST 1581" // 1581/12/31以前は正常
assert new Date("1581/01/01") as String == "Sun Jan 01 00:00:00 JST 1581"
assert new Date("1000/01/01") as String == "Mon Jan 01 00:00:00 JST 1000"

Jacocoでコードカバレッジを測ってみた。

  • Jacocoが出力してくれるhtmlでのレポート

  • Jacocoレポート形式をCoberturaの形式に変換して出力

経緯とか

今の現場ではEmmaを使用してコードカバレッジを測っていたようですが、EmmaはJava7対応していないらしくしばらくカバレッジが測定できていませんでした。
そのままじゃマズイよね。って事で解消するために調べた結果、今はJacocoが定番っぽいので試してみました。

ちょっと前まではカバレッジ測定のツールCoberturaとかEmmaが定番だったようですが、共にJava7に対応していないようです。
が、全て終わってからCoberturaを調べたら数年ぶりに更新されて対応されている??

Jacocoとは

Eclipseプラグインである「EclEmma」の開発チームが開発が2005年で止まっている「Emma」の代わりに開発したカバレッジ測定ツール。

Eclipseでの実行

Eclipseでもプラグインを入れることでカバレッジの測定が可能。

Mavenの設定方法

  • pom.xmlを編集
    • JUnit実行する「maven-surefire-plugin」の引数に「${jacocoArgs}」を設定
    • 「project/build/plugins/plugin」に「org.jacoco」、「jacoco-maven-plugin」を追加
    • 「project/reporting/plugins/plugin」に「org.jacoco」、「jacoco-maven-plugin」を追加
    • 参考
<build>
	<pluginManagement>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<configuration>
					<argLine>${jacocoArgs} -Xmx256m -XX:MaxPermSize=256m</argLine>
				</configuration>
			</plugin>
		</plugins>
	</pluginManagement>
<!-- 中略 -->
	<plugins>
		<plugin>
			<groupId>org.jacoco</groupId>
			<artifactId>jacoco-maven-plugin</artifactId>
			<version>0.7.1.201405082137</version>
			<executions>
				<execution>
					<id>prepare-agent</id>
					<phase>test-compile</phase>
					<goals>
						<goal>prepare-agent</goal>
					</goals>
					<configuration>
						<propertyName>jacocoArgs</propertyName>
						<includes>
							<include>*</include>
						</includes>
					</configuration>
				</execution>
				<execution>
					<id>report</id>
					<phase>prepare-package</phase>
					<goals>
						<goal>report</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
<!-- 中略 -->
	</plugins>
</build>
<!-- 中略 -->
<reporting>
	<plugins>
<!-- 中略 -->
		<plugin>
			<groupId>org.jacoco</groupId>
			<artifactId>jacoco-maven-plugin</artifactId>
		</plugin>
	</plugins>
</reporting>
  • 実行
    • コマンド
mvn clean jacoco:prepare-agent test jacoco:report
  • 結果
    • ↓に出力されます。
target/site/jacoco/index.html
    • ↓にバイナリ形式でも出力されているようです。
target/jacoco.exec

Jenkinsでの実行

    • 成果物の保存で↓を指定しておくといい感じ。
**/site/jacoco/**
  • HTMLで出力された結果もいい感じに見れるのでオススメ。(というかこちらの方が見やすい?)
    • 出力PATH
target/site/jacoco/index.html
  • Jacocoが出力してくれるhtmlでのレポート

Jacoco形式のレポートからCobertura形式に変換

これらは社内で試した内容なのですが、Jacoco形式は見難いという話が出たのでCobertura形式に変換してみました。

  • Jacocoのレポートが出力される
  • ↓を使用してCobertura形式に変換。
https://github.com/rix0rrr/cover2cover
  • Coberturaプラグインで変換した結果をまとめて集計。
    • が、Jenkinsで複数のGitリポジトリをビルドする方法がわからなかったので結局リポジトリに入れてしまった次第です。(参考blogはみつけたんですが。。。)
  • Jacocoレポート形式をCoberturaの形式に変換して出力

Emmaからの乗換える場合

Jacocoの設定をしてEmmaの設定を除去すればそれでOK