- 投稿日:2020-05-22T23:06:43+09:00
初心者の単語No4(Javaコマンド、JVM)
フィールド
・クラスで宣言した変数名
・レコードを抗セする単位。
(その他の意味 分野・領域など)javaコマンド
Javaアプリを起動するコマンド。
(Javaプログラムを実行する)コマンドのオプション
オプション 概要 -classpath 関連するclassファイルの検索先 --module-path モジュールの検索先 -jar jarファイルを実行 -version Javaバージョンを表示 例:Test.jarを実行する例。パラメーターとして「太郎」を設定。
> java -jar Test.jar "太郎"
※その他コマンド系は、またそのうち纏めて記述します。
JVM(Java Vitual Machine)
Javaのプログラムを動かすためのソフトウエア。
その他の言い方として、「Java仮想マシン」「JavaVM」Javaは、どのマシンでもJavaが動作することを思想として作られた言語。
JVMの仕組み
①Javaプログラム⇒②JVM⇒③OS
①を解釈し、③のOSで実行可能な形式のコードに変換して動作させる。
②のJVMはJavaで作ったプログラムをプラットフォームに依存しないで動かすために必須ということ。①から②の際にテキストコードをバイナリコード(マシン語)に変換
②から③の際にバイナリコードを読み込んでネイティブコードに変換JVMの構成
大まかに3つに分けた領域が存在する。
1.New領域
2.Old領域
3.Permanent領域
がある。
1から2の領域ではヒープ。
3の領域では非ヒープ領域。ヒープ
OSやアプリケーションなどのシステムが利用するメモリ領域のこと。
※JVMのヒープ領域はオプションで自由に設定を変更可能。1.New領域
⇒更に3つの領域に分類される。
⇒オブジェクトがインスタンス化された際にEden領域に配置
⇒Edenのメモリがいっぱいになると、オブジェクト退避のためにFrom領域とTo領域に格納。
2.Old領域
⇒New領域に格納されているオブジェクトで使用期間が長い情報が管理されている。
⇒OldがいっぱいになるとFullGCと呼ばれる処理が頻繁に起こる。
※FullGCは重い処理の為実行されている間はシステムが止まる。
3.Permanent領域
⇒クラスやメソッドなどの情報が格納。
【補足】
GCはガーベージコレクションの略。
⇒メモリ領域中の使用済みのメモリ領域を整理し、空き領域を作ること
- 投稿日:2020-05-22T22:38:06+09:00
Javaのdouble型
double型
double型は小数点以下を持つ数になります。
int型は整数で、1とか3とかです。
対してdouble型は1.2とか3.5とかの少数点以下に定義します。小数同士の計算
【例】
Main.javaclass Main { public static void main(String[] args) { double number1 = 8.9; double number2 = 1.2; System.out.println(number1 + number2); System.out.println(number1 - number2); } }上記の例だと結果は11.1と7.7になります。
- 投稿日:2020-05-22T20:59:01+09:00
7日でJAVAを習得する方法
今日はTwitterであるものを見つけました
「
未経験からフリーランスエンジニアを目指すなら
最低1年は勉強しないとダメですよね?
いいえ、違います!
プログラミング習得は
7日あれば誰でも可能です
」よくあるプログラミングスクールの売り文句ですね
7日で本当にプログラミングを習得できるのか、僕がやってきたJavaの勉強方法を元に検証してみようと思います。
前提
if文、for文くらいは学校で聞いたことあるけどいまいち覚えておらず、オブジェクト指向プログラミング(OOP)は知らないものとします
メンターのような人はおらず、すべて一人で勉強するものとします
インターネットを使え、必要な本は事前に入手しているものとします(ただし、Twitterで人に聞く、などはできないものとします)
Javaを勉強する7日間は仕事や用事などはないものとします
自分用のメモは取らないものとします(メモを取る時間のほうが長くなってしまうため)検証
では早速はじめていこうと思います
僕が最初に取り掛かったもの、それは…Progate
インターネットでちょっと調べると真っ先に出てきますね!
途中まで無料で受講できる上に、Javaの実行環境が用意されている状態でスタートできるためかなりのスピードでこなすことができます
今回は月額費用約1000円を払い、有料のコースも受講します
Progateはこちらから先に言っておきますが、ステマ的なものではないですw
最も早く勉強を進める方法として、初期段階ではProgateはかなり有効だと思っていますJavaのコースはI~Vまでありますが、8時間もやれば終わるでしょう
途中で道場?みたいなのがありますがそれは無視していきましょう
何せ時間がないですから!Progateで理解できること
変数、if文、for文などの基本的な構文
クラス、メソッド、インスタンス、カプセル化、継承、ジェネリックスなどのオブジェクト指向プログラミングに関する部分スラスラわかるJava 第2版
Progateでおおよその部分は最速で流していけますが、Progateでは出てこない部分があります
例外処理、インターフェース、関数型インターフェース、ラムダ式、ストリーム、リフレクションなどなど…
Progateは最速で勉強するための優れたツールだとは思いますが、内容量がめっちゃ少ないです
正直、Progateの内容を完璧に習得したとしても何かが作れるレベルではありませんProgateでは出てこなかった部分をスラスラわかるJava 第2版でささっと勉強してしまいましょう!
スラスラわかるJava 第2版はこちらからここで注意をしておくと、スラスラわかるJava 第2版は若干分かりづらい部分があります
何故かというと、Progateでは説明、コーディング、実行という過程があったのですが、スラスラわかるJava 第2版は説明、問題で終わりです
サンプルコードは出てくるのですが、実行結果がイメージしづらく若干分かりづらいです
しかし、この本の説明はかなり丁寧なためしっかり読めば理解できますスラスラわかるJava 第2版で理解できること
例外処理、インターフェース、関数型インターフェース、ラムダ式、ストリーム、リフレクション、マルチスレッド、アノテーション、コレクションなどなど…ただし、これら全てをはじめから完璧に覚える必要はありません
例外処理、インターフェース、関数型インターフェース、ラムダ式、ストリームあたりがなんとなく理解できればそれでOKです
何故かというと、この後死ぬほど出てくるのでここで必死になっても…って感じだからです知っているところは飛ばしてしまって良いです
それであれば大体10時間くらいで読破&理解までいけると思いますJava SE 8 Silver 問題集
俗に言う黒本です
Java SE 8 Silver 問題集はこちらから今まではなんとなくだった理解が、この本を読むとしっかり脳みそに刻み付けられます
この本は何回か読めば簡単にJava Silverを取ることができるようになりますと、言う意味ではかなり価値があると思うのですが、今回は時間がありません
staticメソッドとインスタンスメソッドの違いが理解できていればここは飛ばしてもう次に行ってしまいましょう(別に資格が目的ではないので!)Java プログラマ Gold SE 8
俗に言う紫本です
Java プログラマ Gold SE 8はこちらから資格取得が目的であればJava Goldの黒本も読むべきですが、今回は紫本だけで良いでしょう
Java GoldはSilverでは出てこなかったもう少し詳細な情報が載っています
ここらへんからようやくJavaっぽさが出てきますw今までは理解したとこで何が作れるの??ってレベルでしたが、流石にJava Goldレベルになるともうちょっとマシになり、ファイルへの読み書き、データベースアクセス、マルチスレッドらへんが実装できるようになります
Java プログラマ Gold SE 8で理解できること
JDKに同梱されているライブラリーの使い方
関数型インターフェース、ラムダ式、ストリームなどなどこの本は結構内容も重いので、48時間くらい取りましょうか
デザインパターン(TECHSCORE)
次の本は…と言いたいところですが、ちょっと一休み、GoFのデザインパターンを学びましょう
デザインパターンに関する本はいろいろあるのですが、どれも実装例を書いてあるだけであまり意義を感じなかったので無料で見れるWebサイトで済ましてしまいましょうTECHSCOREがかなりわかりやすく解説してくれてます
デザインパターン(TECHSCORE)はこちらからここで重要なのは、実装方法に囚われないことです
今理解したいのは実装方法ではなくデザインパターンですここは3時間くらいでささっと終わらせちゃってください
Effective Java 第3版
この本はJavaの生みの親であるJoshua Blochさんの著書を翻訳したものです
初版から3版まで出ていますが、それぞれで内容が違います
3版ではJava SE 8の内容も記載してくれているため、まさにそのまま使える手法が載っていますこの本を読む前提として、Javaの基本とデザインパターンがなんとなくでもわかってないといけません
逆に言えば、この本を読んで意味がわかるレベルであればもはや初心者は抜け出したと思っても良いでしょう
Effective Java 第3版はこちらからEffective Java 第3版で理解できること
Javaの設計、実装で気を付けなければならない点
不変オブジェクトの有用性この本でびっくりするのは、Java Goldで一生懸命勉強した内容が「そんなもん使うな」と一蹴されているところですw
コーディング規約とかもこの本を元に作られてるのかな?っていうのをよく見かけるので、これが理解できればなんとなくの設計、実装はできちゃいますこの本もかなり重いので、60時間くらいとっておきますか
Spring Boot 2 プログラミング入門
さて、Javaという言語についてはここまでである程度理解できたと思います
ここからは、実際に仕事で使う領域を触っていきましょう(ごめんなさい、ここまでのは理解してても仕事になるかは微妙なんです…)Javaのフレームワークと言えばSpring Framework!!!
その新顔でSpring Bootというのがいます
めっちゃかんたんにいうと、Javaを使ってWebサーバーが作れるようになります
Spring Boot 2 プログラミング入門はこちらからこの本はかなり丁寧に解説してくれており、インターネットで適当なWebサイトを見るよりはるかに質が良いです
ただし、中身がちょっと古いんですよね…環境構築はSTSを~みたいなこと言っているんですが、今はSpring initializrを使ってしまえば一発で環境構築終わりますw
いやー、めっちゃ便利ですよね
僕はこの本読み始めてからSpring initializrの存在を知ったので読み始めでめっちゃ躓いた思い出がありますwこの本では最初のほうでGroovyという言語を用いてコードを書いているのですが、ここまで来た人であれば勘でJavaに直せます
ちなみに、ビルダーはMavenを使ったパターン、Gradleを使ったパターンで解説がされているのですが、絶対にGradleを使ってください今はインターネットでいろいろ調べるとしっかりMavenでのパターンの解説もされているのですが、Spring Frameworkとそれに付随するライブラリー各種は脱XMLを目指しています
MavenだとXMLで書かないといけないのですが、GradleはJavaっぽい感じで書けます
Javaっぽいというか、実際にはGroobyなんですけどねSpring Boot 2 プログラミング入門で理解できること
MVCの基本
環境構築
Thymeleaf(テンプレートエンジン)の使い方
データベースアクセスこの本はWebサービスを作る、というのがひとつの目標になっているため、Thymeleafを使った画面周りの解説が結構多いです
SpringよりもThymeleafの解説のほうが多いような気がするくらい多いですw言い忘れていたのですが、データベースアクセスはMybatisを使ってしまうのでデータベースアクセス部分は飛ばしてしまって結構です
その代わり、Mybatisのドキュメントを読んでおいてください
Mybatisの公式ドキュメントはこちらから
Mybatis-Springの公式ドキュメントはこちらからMybatisのドキュメントってなぜかバラバラになってるんですよね…w
Mybatisをちょっと検索してみると、日本語化が不安、みたいなことが書いてあったりするんですが、全くそんなことないです
かなりわかりやすく、無駄な部分が少ないためちょっと空いた時間でスラスラ読めてしまいますMybatisの他にもHibernateというのも人気らしいのでそっちも勉強しといたほうが良いかもですね
Spring Boot 2 プログラミング入門とMybatisの公式ドキュメントを合わせて15時間くらいとしましょうか
Spring Boot 2 プログラミング入門は分厚いですがすっ飛ばせる場所が多くて良いですねSpring 徹底入門
とうとうこれで最後です
これが読めれば、かなりイケイケな感じ?になれると思いますちょっと古いのですが、Springの重要な部分が網羅されています
説明もかなり丁寧でわかりやすく、Spring Boot 2 プログラミング入門で触れなれなかった部分もしっかり解説されています
Spring 徹底入門はこちらからただ動けば良い、ではなく、Springの機能を使っていかに良いシステムを作るか、いかに開発工数を減らすか、みたいな部分が書いてあります
僕もまだこの本読破した訳ではないので知らない部分もあるのですが、ほぼすべてがここに詰まっていると言っても良いレベルだと思いますw
ただ、バージョンアップに伴って追加された書き方や、非推奨となった書き方があったりするのでそこらへんはこの本を読んだ後に追っかけていきましょう
下記の記事が簡潔に説明してくれているので是非見てみてください
令和時代に「Spring入門」「Spring徹底入門」を読むとき気をつけるべきN個のことこの本はほぼ丸暗記なので、24時間くらいでささっと読破しちゃってください
わからない部分は後で見返せばいいんです検証結果
7日でJavaを習得することができるのか、結果発表です
まずは必要な時間を計算してみましょう
Progate
8時間スラスラわかるJava 第2版
10時間Java プログラマ Gold SE 8
48時間Effective Java 第3版
60時間デザインパターン(TECHSCORE)
3時間Spring Boot 2 プログラミング入門 + Mybatis公式ドキュメント
15時間Spring 徹底入門
24時間合計168時間!
7日*24時間は168時間なので…
結論!
7日でJAVAを習得することはできます!!!!
いやー、7日でJAVAを習得することってできたんですね
寝ずに7日集中力が続けばですけど…wまとめ
プログラミングスクールは嘘つきではない、ということが証明できました
独学はどうしても嫌だ、という人はプログラミングスクールという手もありなんじゃないでしょうか
本だったら全て合わせても3万円あれば足りるくらいなので、メンターに相当価値がないと費用対効果は良いとは言えないですがでも、あえて7日でプログラミングを習得しようとするなんてなんて無謀なことか…
7日でプログラミングを習得しようとしている人たちは頑張ってください
- 投稿日:2020-05-22T19:01:17+09:00
java(オーバーライド)
オーバーライドを活用する
Hero.javapublic class Hero { String name = "勇者"; int hp = 100; //逃げる public void run() { System.out.println(this.name + "は逃げ出した!"); } }SuperHeroクラスにrun()を再定義する
SuperHero.javapublic class SuperHero extends Hero{ boolean flying; //撤退する public void run() { //Heroクラスにも定義してあるが、再定義(上書き)できる System.out.println(this.name + "撤退した!"); } }HeroとSuperHeroのrun()を呼び出す
Main.javapublic class Main { public static void main(String[] args) { Hero h = new Hero(); h.run(); SuperHero sh = new SuperHero(); sh.run(); } }実行結果
勇者は逃げ出した!
勇者は撤退した!継承の禁止
Stringクラスと宣言時にfinalがついてるクラスは継承できない
Main.javapublic class Main extends String{Stringクラス禁止は、javaのAPIリファレンスでも確認できる
Main.javapublic final class Main {オーバーライドの禁止
宣言時にfinalが付けられたメソッドは、子クラスでオーバーライドできない
Hero.javapublic class Hero { String name = "勇者"; int hp = 100; //逃げる public final void run() { //run()はオーバーライドできない System.out.println(this.name + "は逃げ出した!"); } }
public final void run()
先ほどの、SuperHeroクラスのrun()メソッドは無効になる
- 投稿日:2020-05-22T17:36:19+09:00
【弊社新人に向けて】isXXX系メソッドについて
isXXX系メソッドって例えば?
File
クラスのisFile
やisDirectory
メソッドなどがあります。
Fileクラス公式ドキュメント特徴は?
シンプルに
boolean
を返します。
boolean
とはtrue
やfalse
といった真偽値を表すデータ型です。
if文
の分岐条件やwhile文
の継続条件として用いることができます。isXXX系メソッドのコード例
例として
isBlank
メソッドを作成してみます。isBlank// 指定された値が空文字かを判定する。 // 空文字であれば true。 // そうでなければ false を返す。 public boolean isBlank(String value) { if (value.isEmpty()) { return true; } return false; }使い方は?
先程作成した
isBlank
を例にコードを示します。まず
if文
です。分岐条件として使用するif (isBlank(value)) { // 文字が入力されていない場合の処理 System.out.println("文字が入力されていません。"); } else { // 文字が入力されている場合の処理 System.out.println("入力された文字は「" + value + "」です。"); }
if(isBlank(value))
この様に記述することで、
「値が入力されていなければ」という意図を、読み手に対して明確に伝えることができます。続いて
while文
です。
!isBlank
とすることでtrue
とfalse
を反転させています。継続条件として使用するwhile (!isBlank(value)) { // 文字が入力されている場合の処理 System.out.println("入力された文字は「" + value + "」です。"); }
while(!isBlank(value))
としています。
if文
同様、「値が入力されていれば」という意図が明確です。value.isEmpty()でいいじゃん
間違いではありません。
しかし、時としてblank
の定義は変更されることがあります。
先程のisBlank
は、単に空文字であるかどうかのみ判定しています。もし、引数が
null
だったら?
null
に対してメソッド呼び出しを行うと例外が発生してしまいます。// value の中身が null だと java.lang.NullPointerException が発生 value.isEmpty()null に対応する
空文字の判定処理をメソッド化しておくことで、
null
対応も容易に行うことができます。
では、実際にisBlank
をnull
に対応させてみます。isBlank// 指定された値が null または空文字かを判定する。 // null または空文字であれば true。 // そうでなければ false を返す。 public boolean isBlank(String value) { if(value == null) { return true; } if(value.isEmpty()) { return true; } return false; // 以下の様に書くことも出来ますが、新人向けということで。 // return value == null || value.isEmpty(); }
isBlank
に以下のロジックを追加しただけです。追加された行if(value == null) { return true; }この様に、1箇所に修正を加えるだけで、
isBlank
を呼び出している箇所全てに変更を適用することができます。
コードを書き終え、いざテストをしようとした段階でblank
にはnull
も含まれるよ、なんて言われても問題ありません。まとめ
他の誰かが、明日の、1週間後の、1年後の自分がそのコードの面倒を見ることになるかもしれません。
こんな感じで処理をまとめてしまえば後々楽になります。
- 投稿日:2020-05-22T17:32:01+09:00
[Firebase]アプリをアンインストールしてもFirebase AuthのcurrentUserがnullにならない問題
- 投稿日:2020-05-22T16:23:55+09:00
文字列リテラルとインスタンス
(新人エンジニアのふぎと君。
今日はJavaのコードをせっせと書いているみたい)Stringクラスのインスタンス
「…と、ほなそろそろStringクラスで文字列作るか」
String string1 = "Hello"; String string2 = new String("Hello");「遊び心を加えて書き方変えてみたで」
「これは先輩もくすっと笑ってくれるやろ!」先輩のもとへ
「先輩、コード書いたんで見てください」
「おもろいですやろ」
「んー、どれどれ・・・?」
「おん?」
「なあふぎと、お前この違いわかってへんのと違うか?」
「・・・?どの違いですか?」
「Stringクラスの初期化の仕方の違いや」
「違いって・・・どっちもStringクラスのインスタンスを
つくってるんと違うんですか」
「そうとも言えるし、そうやないとも言える」
「1つはリテラルで、もう1つはインスタンスや」String string1 = "Hello"; //リテラル String string2 = new String("Hello"); //インスタンス「ええっ」
「そうなんですか」先輩ガチレク発動
「newしてつくった文字列はな」
「メモリのヒープ領域におかれんねん」
「ヒープ領域…?(;^ω^)」
「ざっくり言うたら『材料の保管庫』って感じや」
「プログラムの実行に必要なデータを置いとくとこやな」
「あーなるほど」
「話もどすけどな」
「newして作った文字列はヒープ領域におかれるんに対して」
「代入演算子で作った文字列はヒープにおかれた後」
「その参照が文字列リテラルプールに登録される」
「モジレツリテラルプール?」
「せや」
「ここに登録されたんと同じ文字列が次に作られたとき、」
「プログラムは文字列リテラルプールに登録された文字列の
参照を返して、新しいインスタンスはつくらへん」
「なんとなくわかってきましたわ」
「同じ文字列やったら同じインスタンスを使いまわすってことですね?」
「まあ、ざくっと言うたらそうや」
「そもそもインスタンスの作成はコンピュータにとって
しんどい仕事やねん」
「せやから、よく使うStringクラスはそのしんどい仕事を
なるべくせえへんようにできるようになっとる訳やな」
「ほへー」
「勉強なりました」
「ありがとうございました(*´ω`)」参考
https://it-trend.jp/development_tools/article/32-0041
川場隆『Javaオブジェクト指向徹底解説』(秀和システム)
- 投稿日:2020-05-22T15:29:54+09:00
WSLでjupyter+Javaを使うときにClassPathを指定する
JupyterLab+Javaを使う場合にクラスパスを設定するぞ.
設定ファイルはどこだ
$ jupyter kernelspec list
java /path/to/jupyter/kernels/java python3 /path/to/jupyter/kernels/python3
通常のJavaとは違うjava-libというkernelを作るぞ
$ cd /home/user_name/.local/share/jupyter/kernels/
$ mkdir java-lib
$ cd java-lib
$ ln -s ../java/ijava-1.3.0.jar
$ cp ../java/kernel.json ./
$ vi kernel.jsonkernel.json{ "argv": [ "java", "-Xmx8g", "-cp", "/path/to/lib/dir/*:/path/to/java-lib/ijava-1.3.0.jar", "io.github.spencerpark.ijava.IJava", "{connection_file}" ], "display_name": "Java-lib", "language": "java", "interrupt_mode": "message", "env": { } }できた.
以下のコードでクラスパスがズラズラ出てくれば成功.Properties properties = System.getProperties(); String clsPath = properties.getProperty("java.class.path"); System.out.println(clsPath);しかし,実行ファイルごとにクラスパスを変更することはできないようだ.
ま,特定のlibファイルにjarファイルを全部入れておくという罰当たりなやり方で何とかなりそう.しかし,Eclipseに慣れすぎているので,補完があまり効かないJupyterLabでどこまでコードが書けるか自信がない・・・
- 投稿日:2020-05-22T14:56:09+09:00
Chocolateyを使ったWindowsのJava環境最新化
ChocolateyでWindows10 64bitのJava開発環境を最新化します。
Chocolateyは、Ubuntu/Debian系のapt-getのWindows版といった感じのソフトです。
年に1度ほどする作業で、当然次にするときに忘れているので、メモしておきます。
記事「Chocolateyを使った環境構築の時のメモ」を参考にしています。とあるチュートリアルに従ってChocolateyをインストールしてごく稀に使っているだけなので、素晴らしいソフトかまるで判断できないです。ただ、リリースノートがあまりされていないのが気になります。
手順
まずは、Powershellを管理者権限で起動します。コマンドプロンプトだと警告でるのでやめました。
インストール済パッケージ確認
choco list -lo
でインストール済みパッケージを一覧確認です。Powershell管理者権限> choco list -lo adoptopenjdk8 8.242.8 chocolatey 0.10.15 maven 3.6.3 3 packages installed.一括アップデート
choco upgrade all -y
でインストール済みパッケージを一括でアップデートします。Powershell管理者権限choco upgrade all -y個別アップデート(おまけ)
個別にパッケージをアップデートする場合は
choco upgrade [packageName]
です。Powershell管理者権限choco upgrade [packageName]
- 投稿日:2020-05-22T14:32:58+09:00
WSLでJupyterLab Javaを使う
Windows10でJupyter Lab+Javaを使いたかったので試してみた.
インストール
Jupyterインストール
$ sudo pip install jupyterlab widgetsnbextension
$ jupyter lab --generate_config
$ cd .jupyter/
$ emacs jupyter_notebook_config.pyjupyter_notebook_config.py# c.NotebookApp.use_redirect_file = True c.NotebookApp.use_redirect_file = FalseJupyter用JavaKernelのインストール
$ git clone https://github.com/SpencerPark/IJava.git
$ cd IJava/
$ ./gradlew installKernel実行
$ jupyter lab
または,Windows上で以下のようなショートカットを作成
ショートカットを実行すると,ブラウザ上にJupyterLabが無事立ち上がる.
すごいすごい.ブラウザ上にLauncherが立ち上がるので,Javaを選べばとりあえずは動く.
しかし,classpathの読み込み方がわからん.ClassPathが設定できなきゃ何もできないなあ.
とりあえずClassPathの設定方法を調べよう.
- 投稿日:2020-05-22T14:32:58+09:00
Windows10のWSLでJupyterLab+Javaを使う
Windows10でJupyterLab+Javaを使いたかったので試してみた.
Jupyter Notebook上でJavaが動いたらなんか便利そうじゃない?インストール
Jupyterインストール
$ sudo pip install jupyterlab widgetsnbextension
$ jupyter lab --generate-config
$ cd .jupyter/
$ emacs jupyter_notebook_config.pyjupyter_notebook_config.py# c.NotebookApp.use_redirect_file = True c.NotebookApp.use_redirect_file = FalseJupyter用JavaKernelのインストール
$ git clone https://github.com/SpencerPark/IJava.git
$ cd IJava/
$ ./gradlew installKernel実行
$ jupyter lab
または,Windows上で以下のようなショートカットを作成
ショートカットを実行すると,ブラウザ上にJupyterLabが無事立ち上がる.
すごいすごい.ブラウザ上にLauncherが立ち上がるので,Javaを選べばとりあえずは動く.
しかし,classpathの読み込み方がわからん.ClassPathが設定できなきゃ何もできないなあ.
とりあえずClassPathの設定方法を調べよう.ClassPathの設定の仕方はこちら.
https://qiita.com/toritorix/items/6f1675166223960a1e85
- 投稿日:2020-05-22T11:22:06+09:00
GradleでS3を使用する時にNoSuchFieldError:REQUIRES_LENGTHと出て困った話
発生状況
AWS SDK for Java を使用してS3にファイルアップロードしようとしたら下記のようなエラーが発生した
Exception in thread "main" com.amazonaws.AmazonClientException: Unable to complete transfer: REQUIRES_LENGTH at com.amazonaws.services.s3.transfer.internal.AbstractTransfer.unwrapExecutionException(AbstractTransfer.java:286) at com.amazonaws.services.s3.transfer.internal.AbstractTransfer.rethrowExecutionException(AbstractTransfer.java:265) at com.amazonaws.services.s3.transfer.internal.AbstractTransfer.waitForCompletion(AbstractTransfer.java:103) at core.AwsApplication.main(AwsApplication.java:64) Caused by: java.lang.NoSuchFieldError: REQUIRES_LENGTH at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1731) at com.amazonaws.services.s3.transfer.internal.UploadCallable.uploadInOneChunk(UploadCallable.java:168) at com.amazonaws.services.s3.transfer.internal.UploadCallable.call(UploadCallable.java:148) at com.amazonaws.services.s3.transfer.internal.UploadMonitor.call(UploadMonitor.java:115) at com.amazonaws.services.s3.transfer.internal.UploadMonitor.call(UploadMonitor.java:45) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:834)ファイルアップロードのソースコードは公式を参照しているので間違いはないはず
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/HLuploadFileJava.htmlbuild.gradleに追加するコードもMVNRepositoryから参照してるので大丈夫なはず
https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3/1.11.784調べたこと
コンソールに表示されている下記のファイルを確認したら
HandlerContextKey
クラスにあるはずのREQUIRES_RENGTH
フィールドが存在していのが原因っぽいcom.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1731)解決方法
下記サイトで質問している内容が参考になりそう
https://stackoverflow.com/questions/49085110/error-in-using-aws-java-sdk-s3読んでみたら
aws-sdk-core
のライブラリもbuild.gradle
に追加する必要がある...らしいってことでMVNRepositoryから下記を追加してみる
https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-core/1.11.784
build.gradle
はこんな感じで記述してみた(aws-java-sdk-s3
とwas-java-sdk-core
のバージョンは一緒じゃないとダメらしい)build.gradledependencies { ... ... -- 省略 -- compile group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: '1.11.784' compile group: 'com.amazonaws', name: 'aws-java-sdk-core', version: '1.11.784' }実行してみたら...
Object upload started 2020-05-22 11:20:42.603 WARN 19566 --- [anager-worker-1] com.amazonaws.util.Base64 : JAXB is unavailable. Will fallback to SDK implementation which may be less performant.If you are using Java 9+, you will need to include javax.xml.bind:jaxb-api as a dependency. Object upload complete
ちゃんとアップロード完了したみたいです!
とりあえず解決しました
- 投稿日:2020-05-22T10:54:02+09:00
[AndroidStudio] ActionBarDrawerToggleのハンバーガーメニューの色変更
タイトルの通りです。
自分用メモ。ハンバーガーメニューを白色にしたい場合
MainActivity.javaActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer,toolbar, R.string.drawer_open, R.string.drawer_close); /* ハンバーガーメニューのdrawableをtoggleから取得 */ DrawerArrowDrawable arrowDrawable = toggle.getDrawerArrowDrawable(); /* 色の変更 */ arrowDrawable.setColor(getResources().getColor(R.color.colorWhite)); /* 色を変更したdrawableを再びセット */ toggle.setDrawerArrowDrawable(arrowDrawable);以上です。
他にいい方法があれば教えてください。
- 投稿日:2020-05-22T08:11:19+09:00
OpenTracing チュートリアル 前半
OpenTracing チュートリアル 前半
上記に公開されている中から、今回はJava のチュートリアルをやってみようと思います。
実行環境
[root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.7.1908 (Core) [root@localhost ~]# java -version openjdk version "1.8.0_252" OpenJDK Runtime Environment (build 1.8.0_252-b09) OpenJDK 64-Bit Server VM (build 25.252-b09, mixed mode) [root@localhost ~]# mvn -v Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f) Maven home: /usr/local/apache-maven Java version: 1.8.0_252, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el7_8.x86_64/jre Default locale: ja_JP, platform encoding: UTF-8 OS name: "linux", version: "3.10.0-1062.9.1.el7.x86_64", arch: "amd64", family: "unix" [root@localhost ~]# docker -v Docker version 19.03.5, build 633a0eaJaeger のdocker コンテナを起動する
Jaeger のGetting Started で公開されているコマンドを参考にJaeger のコンテナを起動します。
[root@localhost java]# docker run -itd --name jaeger \ > -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \ > -p 5775:5775/udp \ > -p 6831:6831/udp \ > -p 6832:6832/udp \ > -p 5778:5778 \ > -p 16686:16686 \ > -p 14268:14268 \ > -p 9411:9411 \ > jaegertracing/all-in-one:1.8 \ > --log-level=debug Unable to find image 'jaegertracing/all-in-one:1.8' locally 1.8: Pulling from jaegertracing/all-in-one b9b0c98e35fd: Pull complete 48b3359c5f38: Pull complete Digest: sha256:c6b9104263c3d5aefee645181ca50ab5dd26fde41092dcdf6f026808a6af008d Status: Downloaded newer image for jaegertracing/all-in-one:1.8 8138fc00c6ea7fcc4e619fb99f3980a17e2b2a517f2c43f92c75a9ab0026355c各Port の役割は下記の通りとなっているようです。
Port Protocol Component Function 5775 UDP agent accept zipkin.thrift over compact thrift protocol (deprecated, used by legacy clients only) 6831 UDP agent accept jaeger.thrift over compact thrift protocol 6832 UDP agent accept jaeger.thrift over binary thrift protocol 5778 HTTP agent serve configs 16686 HTTP query serve frontend 14268 HTTP collector accept jaeger.thrift directly from clients 9411 HTTP collector Zipkin compatible endpoint (optional) コンテナが起動できていることを確認できたら、Web ブラウザからJaeger UI にアクセスしてみます。
OpenTracing のチュートリアルのソースをgit clone
下記に、チュートリアルのソースが公開されておりますので、ローカルリポジトリに複製します。
$ git clone https://github.com/yurishkuro/opentracing-tutorialREADME.md に記載されている通りに、ビルドできるかを確認します。
[root@localhost java]# cd opentracing-tutorial/java [root@localhost java]# mvn clean package (中略) [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 02:01 min [INFO] Finished at: 2020-05-21T01:48:42+09:00 [INFO] ------------------------------------------------------------------------無事、ビルドに成功しました。
Lesson 1 のソースをビルドして実行してみる
ディレクトリ構成確認
[root@localhost java]# cd src/main/java/lesson01/ [root@localhost lesson01]# tree . ├── README.md ├── exercise │ └── Hello.java └── solution └── Hello.java複製してきたソースには処理が記載されていないので、README.md を見つつ、ソースを編集
src/main/java/lesson01/exercise/Hello.javapackage lesson01.exercise; import com.google.common.collect.ImmutableMap; import io.jaegertracing.internal.JaegerTracer; import io.opentracing.Span; import io.opentracing.Tracer; import lib.Tracing; public class Hello { private final Tracer tracer; private Hello(Tracer tracer) { this.tracer = tracer; } private void sayHello(String helloTo) { // Operation: tracer.buildSpan("operationName"); // Generating trace information: tracer.buildSpan(); // Trace start: .start(); Span span = tracer.buildSpan("say-hello").start(); // Set span tags: span.setTag("key", value); span.setTag("hello-to", helloTo); // this goes inside the sayHello method String helloStr = String.format("Hello, %s!", helloTo); // Set span logs: span.log(ImmutableMap.of("key1", "value1", "key2", "value2")); span.log(ImmutableMap.of("event", "string-format", "value", helloStr)); System.out.println(helloStr); // Set span logs: span.log(ImmutableMap.of("key1", "value1")); span.log(ImmutableMap.of("event", "println")); // Trace end: span.finish span.finish(); } public static void main(String[] args) { if (args.length != 1) { throw new IllegalArgumentException("Expecting one argument"); } String helloTo = args[0]; // Service: Tracing.init("serviceName"); try (JaegerTracer tracer = Tracing.init("hello-world")) { new Hello(tracer).sayHello(helloTo); } } }
- すぐに動作を確認したい場合、時間がない場合には、下記で短縮も可能です。
[root@localhost java]# cp src/main/java/lesson01/solution/Hello.java src/main/java/lesson01/exercise/Hello.javaビルド
[root@localhost java]# mvn clean package (中略) [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 16.242 s [INFO] Finished at: 2020-05-22T06:33:55+09:00 [INFO] ------------------------------------------------------------------------実行
[root@localhost java]# ./run.sh lesson01.exercise.Hello Bryan 06:35:41.228 [main] DEBUG io.jaegertracing.thrift.internal.senders.ThriftSenderFactory - Using the UDP Sender to send spans to the agent. 06:35:41.346 [main] DEBUG io.jaegertracing.internal.senders.SenderResolver - Using sender UdpSender() 06:35:41.457 [main] INFO io.jaegertracing.Configuration - Initialized tracer=JaegerTracer(version=Java-1.1.0, serviceName=hello-world, reporter=CompositeReporter(reporters=[RemoteReporter(sender=UdpSender(), closeEnqueueTimeout=1000), LoggingReporter(logger=Logger[io.jaegertracing.internal.reporters.LoggingReporter])]), sampler=ConstSampler(decision=true, tags={sampler.type=const, sampler.param=true}), tags={hostname=localhost.localdomain, jaeger.version=Java-1.1.0, ip=127.0.0.1}, zipkinSharedRpcSpan=false, expandExceptionLogs=false, useTraceId128Bit=false) Hello, Bryan!Jaeger UI でソース通りにトレース情報が生成できているかを確認
- Service Name
- Operation Name
- Span Tag
- Span Log
Lesson 2のソースをビルドして実行してみる
README.md を見つつ、ソースを編集
src/main/java/lesson02/exercise/Hello.javapackage lesson02.exercise; import com.google.common.collect.ImmutableMap; import io.jaegertracing.internal.JaegerTracer; import io.opentracing.Scope; import io.opentracing.Span; import io.opentracing.Tracer; import lib.Tracing; public class Hello { private final Tracer tracer; private Hello(Tracer tracer) { this.tracer = tracer; } private void sayHello(String helloTo) { // Operation: tracer.buildSpan("operationName").start(); // Generating trace information: .buildSpan(); // Trace start: .start(); Span span = tracer.buildSpan("say-hello").start(); try (Scope scope = tracer.scopeManager().activate(span)) { // Set span tags: span.setTag("key", value); span.setTag("hello-to", helloTo); String helloStr = formatString(helloTo); printHello(helloStr); } finally { span.finish(); // Trace end: span.finish } } private String formatString(String helloTo) { // Operation: tracer.buildSpan("operationName").start(); // Generating trace information: .buildSpan(); // Trace start: .start(); Span span = tracer.buildSpan("formatString").start(); try (Scope scope = tracer.scopeManager().activate(span)) { String helloStr = String.format("Hello, %s!", helloTo); // Set span logs: span.log(ImmutableMap.of("key1", "value1", "key2", "value2")); span.log(ImmutableMap.of("event", "string-format", "value", helloStr)); return helloStr; } finally { span.finish(); // Trace end: span.finish } } private void printHello(String helloStr) { // Operation: tracer.buildSpan("operationName").start(); // Generating trace information: .buildSpan(); // Trace start: .start(); Span span = tracer.buildSpan("printHello").start(); try (Scope scope = tracer.scopeManager().activate(span)) { System.out.println(helloStr); // Set span logs: span.log(ImmutableMap.of("key1", "value1")); span.log(ImmutableMap.of("event", "println")); } finally { span.finish(); // Trace end: span.finish } } public static void main(String[] args) { if (args.length != 1) { throw new IllegalArgumentException("Expecting one argument"); } String helloTo = args[0]; // Service: Tracing.init("serviceName"); try (JaegerTracer tracer = Tracing.init("hello-world")) { new Hello(tracer).sayHello(helloTo); } } }ビルド
[root@localhost java]# mvn clean package (中略) [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 11.413 s [INFO] Finished at: 2020-05-22T07:35:12+09:00 [INFO] ------------------------------------------------------------------------実行
[root@localhost java]# ./run.sh lesson02.exercise.Hello Bryan 07:36:58.491 [main] DEBUG io.jaegertracing.thrift.internal.senders.ThriftSenderFactory - Using the UDP Sender to send spans to the agent. 07:36:58.637 [main] DEBUG io.jaegertracing.internal.senders.SenderResolver - Using sender UdpSender() 07:36:58.734 [main] INFO io.jaegertracing.Configuration - Initialized tracer=JaegerTracer(version=Java-1.1.0, serviceName=hello-world, reporter=CompositeReporter(reporters=[RemoteReporter(sender=UdpSender(), closeEnqueueTimeout=1000), LoggingReporter(logger=Logger[io.jaegertracing.internal.reporters.LoggingReporter])]), sampler=ConstSampler(decision=true, tags={sampler.type=const, sampler.param=true}), tags={hostname=localhost.localdomain, jaeger.version=Java-1.1.0, ip=127.0.0.1}, zipkinSharedRpcSpan=false, expandExceptionLogs=false, useTraceId128Bit=false) 07:36:58.847 [main] INFO io.jaegertracing.internal.reporters.LoggingReporter - Span reported: d9d0cc339032bb7e:e553869b15fef330:d9d0cc339032bb7e:1 - formatString Hello, Bryan! 07:36:58.848 [main] INFO io.jaegertracing.internal.reporters.LoggingReporter - Span reported: d9d0cc339032bb7e:b5937236a352f98b:d9d0cc339032bb7e:1 - printHello 07:36:58.848 [main] INFO io.jaegertracing.internal.reporters.LoggingReporter - Span reported: d9d0cc339032bb7e:d9d0cc339032bb7e:0:1 - say-helloJaeger UI でソース通りにトレース情報が生成できているかを確認
- formatString
- Operation Name
- Span Log
- printHello
- Operation Name
- Span Log
- trace.scopeManager().active(span) makes the given span the currently active span. Once the scope is closed, the previous scope becomes current, thus re-activating previously active span in the current thread.
- Scope is auto-closable, which allows us to use try-with-resource syntax.
- If there is already an active span, it will act as the parent to the span created by buildSpan().
- 和訳
- trace.scopeManager().active(span) は、与えられたスパンを現在アクティブなスパンにします。スコープを閉じると、前のスコープがカレントになり、現在のスレッドで以前にアクティブだったスパンが再びアクティブになります。
- スコープは自動で閉じることができるので、リソースとの試行錯誤の構文を使用することができます。
- 既にアクティブなスパンがある場合は、そのスパンが buildSpan() で作成されたスパンの親として動作します。
という記載があるので、
処理順番 メソッド名 親子関係 1 sayHello 親 2 formatString 子 3 printHello 子 長くなりそうなので、lesson03, lesson04 は別の機会で別途記事を作成しようと思います。
参考URL
- Getting Started | OpenTracing
- What is Distributed Tracing? | OpenTacing
- Tutorials | OpenTracing
- OpenTracing Overview | OpenTracing
- Spans | OpenTracing
- Scopes | OpenTracing
- Getting started | Jaeger
- Architecture | Jaeger
- OpenTracing Tutorial - Java
- Lesson 1 - Hello World
- Lesson 2 - Context and Tracing Functions
- Jaeger's Tracing Instrumentation Library for Java
- OpenTracingチュートリアルをやってみた(その1)
- 投稿日:2020-05-22T04:43:07+09:00
【Kotlin】内容の重複したファイルを削除する【Java】
やりたいこと
あるディレクトリの中に内容の重複したファイルが大量に有る時、1つだけ残して重複したものを削除します。
やり方
ファイル全体を比較すると処理コストが高くて大変です。
そこで今回はファイルのハッシュ(ダイジェスト)を比較することとし、以下の方針で実装しました。
- ファイルのハッシュを取ってダイジェストを取得
- ダイジェストが
Set
に既存かチェック- 存在していれば削除
- 存在していなければ
Set
にadd
サンプルコード
とりあえず動くサンプルは以下の通りです。
import java.io.File import java.security.MessageDigest val sha256 : MessageDigest = MessageDigest.getInstance("SHA-256") fun getDigest(bytes: ByteArray): List<Byte> = sha256.digest(bytes).toList() fun getFiles(pathToDir: String): List<File> = File(pathToDir).listFiles()?.toList() ?: emptyList() fun main() { val files = getFiles(/* 処理対象ディレクトリのパス */) val set = HashSet<List<Byte>>() var count = 0 files.forEach { val digest = getDigest(it.readBytes()) if (set.contains(digest)) { if (it.delete()) { println("Deleted:\t${it.name}") count++ } else { println("Fail delete:\t${it.name}") } } else { set.add(digest) } } println("\n\n$count deleted.") }実行結果
折り畳み
Deleted: 43_3のコピー.gif Deleted: 46_3のコピー2.gif Deleted: 70_1のコピー2.gif Deleted: 94_1のコピー.gif Deleted: 50_3のコピー2.gif Deleted: 66_1のコピー.gif Deleted: 95_1のコピー.jpg Deleted: 58_3のコピー.gif Deleted: 63_1のコピー.gif Deleted: 32_1のコピー.jpg Deleted: 55_3のコピー.gif Deleted: 62_3のコピー.gif Deleted: 49_3のコピー.gif Deleted: 9_1のコピー2.gif Deleted: 47_3のコピー.gif Deleted: 96_1のコピー.jpg Deleted: 71_1のコピー.gif Deleted: 52_3のコピー2.gif Deleted: 64_1のコピー2.gif Deleted: 61_3のコピー.gif Deleted: 56_3のコピー.gif Deleted: 60_3のコピー2.gif Deleted: 31_1のコピー.jpg Deleted: 57_3のコピー2.gif Deleted: 98_1のコピー2.jpg Deleted: 34_1のコピー.jpg Deleted: 68_1のコピー.gif Deleted: 53_3のコピー.gif Deleted: 42_3のコピー.gif Deleted: 74_1のコピー2.gif Deleted: 30_1のコピー.gif Deleted: 36_1のコピー2.gif Deleted: 65_1のコピー.gif Deleted: 100_1のコピー.jpg Deleted: 37_1のコピー.gif Deleted: 35_1のコピー2.gif Deleted: 45_3のコピー.gif Deleted: 99_1のコピー.jpg Deleted: 87_1のコピー2.jpg Deleted: 33_1のコピー.jpg Deleted: 73_1のコピー.gif Deleted: 1_7のコピー.jpg Deleted: 48_3のコピー.gif Deleted: 54_3のコピー2.gif Deleted: 51_3のコピー.gif Deleted: 67_1のコピー.gif Deleted: 93_1のコピー2.gif Deleted: 44_3のコピー2.gif Deleted: 72_1のコピー2.gif Deleted: 97_1のコピー2.jpg 50 deleted.解説
ハッシュの取り方
java.security.MessageDigest
を利用しました。
これは特にライブラリ等を導入せずJava
標準で使えます。今回はテキトーに
SHA-256
を指定しましたが、「極限まで重複を回避したいぜ!」という場合はSHA-512
を指定してあげればいいと思います。重複管理
恐らく
HashSet
を使うのが一番簡単かつコストも低いと思います。
また、ByteArray
ではequals
周りに不安があるため、ここではList
に変換して取り扱っています。
- 投稿日:2020-05-22T01:51:11+09:00
【Java】Selenide+ChromeDriverでサクッと統合テスト入門<2020年5月更新>
はじめに
アプリケーションの機能を開発したら他の機能とうまく連動するか、どんな挙動か調べるために統合テスト(結合テスト)やりますよね。
今回はJavaで開発したWebアプリケーションの簡単な統合テストを目視じゃなくて、自動化しちゃおう(当たり前か)ということでSelenide+ChromeDriverを使ったハンズオンをやろうと思います。
※本格的にテストやるならMockitoなど使ってMock呼んでテストする方がいいです。
開発環境
macOS Catalina 10.15.4
IntelliJ IDEA 2018.3.6
Google Chrome 81.0.4044.138
Selenide 5.2.2
aShot 1.5.3準備
使うライブラリをpom.xmlに記述します。
pom.xml
<dependency> <groupId>com.codeborne</groupId> <artifactId>selenide</artifactId> <version>5.2.2</version> <scope>test</scope> </dependency> <dependency> <groupId>ru.yandex.qatools.ashot</groupId> <artifactId>ashot</artifactId> <version>1.5.3</version> </dependency>次にChromeDriverを使うためにドライバをダウンロードします。(以下リンク)
https://chromedriver.chromium.org
- Downloadsをクリック
- Chromeのバージョンに合わせてドライバを選択(今回は81.0.4044.138)
- MacOSならmac64.zipを選択しダウンロード後、任意の場所に格納(あとで使うのでパスを覚えておく)
基本設定
・Chromeドライバのパスの設定
・ChromeDriverインスタンスの生成
これでSelenideを用いたChromeの自動操作が可能になります。System.setProperty("webdriver.chrome.driver", "<ドライバのパス>/chromedriver"); WebDriver webDriver = new ChromeDriver();最終行にclose()を書くことでウィンドウを閉じます。
webDriver().close();基本操作
以下、テストに必要な操作の中から、基本的なものを説明します。
リンクに遷移
webDriver.get("https://hoge.com/");もう一つメソッドがあります。
webDriver.navigate().to("https://hoge.com/");【補足】
get()とnavigate().to()はほとんど同じメソッドだと思ってもらって構いません。両者の違いは、SPA(シングルページアプリケーション)を操作する際に出てきます。SPA内ではget()がページを更新して遷移するのに対し、navigate().to()はページを更新せずに遷移します。get()はブラウザ履歴やcookieを保持せず、navigate().toは保持します。SPAではnavigate().to()の方がより人間が操作してるのに近いテストを実施できるといえます。戻る・進む
戻る
webDriver.navigate().back();進む
webDriver.navigate().forward();更新
更新
webDriver.navigate().refresh();要素の取得
HTMLのid要素を取得
webDriver.findElement(By.id("hoge"));class要素を指定できたりもしますが、取得結果が一意にならないことが多いのでid取得がおすすめです。
ボタンのクリック
ボタンのHTMLのid要素を取得し、クリック
webDriver.findElement(By.id("hoge")).click();フォームの入力
フォームのHTMLのid要素を取得し、sendkeys()で入力
webDriver.findElement(By.id("hoge")).sendKeys("ほげほげ");挙動は実際に画面に入力しているかのように一文字一文字入力されていきます。
フォームに入力されている値の消去
フォームのHTMLのid要素を取得し、clear()で消去
webDriver.findElement(By.id("hoge")).clear();値の更新処理で既存の入力内容を消去したい場合に便利です。
スクリーンショットの撮影
一行目で全画面をスクショできるようにページサイズを最小化しています。最小化しないとChromeは自動でウィンドウサイズを調整してしまうので、画面全体がうまく写りません。三行目で画像のパスを指定しています。
webDriver.manage().window().setPosition(new Point(-2000, 0)); Screenshot screenshot = new AShot() .shootingStrategy(ShootingStrategies.viewportPasting(100)) .takeScreenshot(webDriver); ImageIO.write(screenshot.getImage(), "PNG", new File("<画像保存場所のパス>/<画像名>.png"));(おまけ)統合テストコードの例
【テストシナリオ】
- hogeアプリケーションのログイン画面にアクセスする
- 管理者ユーザのメールアドレスとパスワードをフォームに入力
- ログインボタンをクリック
- 投稿リストの投稿1の編集ボタンをクリック
- フォームの投稿名を消去
- 投稿名に投稿2と入力
- 更新ボタンをクリック
- 更新完了後の画面をスクリーンショット
System.setProperty("webdriver.chrome.driver", "hoge/chromedriver"); WebDriver webDriver = new ChromeDriver(); webDriver.get("https://hoge.com/home"); webDriver.findElement(By.id("email")).sendKeys("admin@xx.xx.xx"); webDriver.findElement(By.id("password")).sendKeys("pass"); webDriver.findElement(By.id("loginButton")).click(); webDriver.navigate().to("https://hoge.com/edit?topicId=1"); webDriver.findElement(By.id("topicName")).clear(); webDriver.findElement(By.id("topicName")).sendKey("投稿2"); webDriver.findElement(By.id("updateButton")).click(); webDriver.manage().window().setPosition(new Point(-2000, 0)); Screenshot screenshot = new AShot() .shootingStrategy(ShootingStrategies.viewportPasting(100)) .takeScreenshot(webDriver); ImageIO.write(screenshot.getImage(), "PNG", new File("hoge/screenshot.png")); webDriver.close();おわりに
selenideで検索してもJavaじゃなくてPythonの情報が出てきちゃうのでまとめてみました。
統合テストの例は想像上のwebアプリケーションの想像上のテストなのであしからず。
ありがとうございました。参考
・Difference between webdriver.get() and webdriver.navigate()
・Seleniumクイックリファレンス