FrontPage
概要 †
- 世界的に使われている言語
- 必ずintelliJを使う!
疑問 †
- intelliJの外部ライブラリと、pomで書く依存関係ってどう違うの?
- intelliJのMavenのところのdeployとかtestってどうやって使うの?
- public static void...のstaticってどういう意味?どういう時に必要なの?
- アットマークで指示しているものはなに?
- アノテーション・アノテーション型って何?
バージョン †
- Javaでいうと7, 8の間はデカかったけど8, 11の差はそうでもない
- Java strategyというのがあって、1 version / yearでリリースし、3年に一回安定版のJavaを作るみたいなポリシーがあるらしい。現在8, 11が安定サポート対象
- SPA (Single something somethin)というフロントエンドのReactに代表されるフレームワークがあって楽しい
- SDKは下方互換性強い
- 変更があったとしても安定ソートになっていない仕様のソートで少し順序が違うとかそれくらい
ディレクトリ構造 †
Map/Reduce †
- map(T -> R) は、 T のデータ型を R のデータ型に1:1の変換です。 ・ flatMap(T -> Stream<R>) は、 T のデータ型から Stream<R> に1:Nの変換です。
Javadoc †
大変便利で、クラスの概要やメソッドの概要を記述しておくと、その情報からHTML形式のドキュメントファイルを生成してくれます。Java Platform SEのAPIリファレンスは実際に、この機能を使って生成しています。
アノテーション †
- 自作する場合はjavaファイルを自分でかく必要がある。
- Javaではアノテーションを記述するためにはアノテーション型を使います。
- クラス
- インターフェース
- メソッド
- メンバ変数
- メソッド引数
- 例えば、Javaプログラムの単体テスト用ライブラリである「JUnit 4」では、テスト用プログラムにあるアノテーションが付いたメソッドをテスト用メソッドとして実行できます。
- Javaには標準アノテーション型として、java.langパッケージに「Override」「Deprecated」「SuppressWarnings?」が定義されています。
スレッドプール †
Context †
- The request.setAttribute() sets an attribute in the request scope and is thus only available within the same request/response cycle. The servletContext.setAttribute()
- スコープとは、サーブレットやJSPを跨いでデータを共有したい場合に用いる保存領域のこと。
- https://qiita.com/shuyam/items/a9a1be62f52009748844
- GAE Standardのセッション管理
- この実装では、App Engine のデータストアと memcache を使用してセッション データを保管する。
- で、どうやってsessionのattiributeを見るの??なくない??
- mvnのPはprofile。pomの中にprofiles/profile/idに指定するところを-Pで指定すると、そのプロファエイルの中に書いてあるdependencyなどが追加でインストールされるなど。複数のプロファイルを読み込むこともできる。
- Dはdefineで、system propertyのレベルなので結構広い範囲で有効。C++での-Dに近いものがあるのでわかりやすいね。
- -DをrequiredProperty()みたいな感じで取得する方法があるらしい。多分これはPOMのpropertiesにあるbigtable.versionみたいなやつを取得する関数で、POIMの設定として強制的に追加するための関数なんじゃないかなあと思っている
- Celeniumの自動化をしても結局メンテナンスコストはかかる
- 画面テストのメンテは実はUnitTest?よりコストがたかいので、メンテできないような亮のテストを作ってはならない。
- 記録機能はそこまで重要ではなく、それなりのコストが必要になる
- guavaというGoogleせいのライブラリがあって、これがC++のbits/std++.hみたいな感じでいろんなデータ構造とか簡単に値チェックするための関数を提供していてうれしいらしい。
POM †
- MavenはProject Object Model(POM)によるプロジェクト管理ツール
- https://kengotoda.gitbooks.io/what-is-maven/primer/build-lifecycle.html
- Maven
- Javaのビルドツール
- Mavenは内部でAntを使用しており、Antで使用できる全ての組込ターゲットを直接使用できる
- Antではオレオレbuild.xmlを書かないといけなかったり、依存JARが多いと全部サイト巡ってダウンロードする必要があるみたいな悲しい感じだった。→プロジェクトのディレクトリ構造にルールを作った。→依存jarは自動ダウンロードするようにした。→また、ビルドも、コンパイルしてテストしてZIPで固めて…をするようにした。
- 依存ライブラリ (jar) は自動ダウンロードされる。
- jarはローカルレポジトリと呼ばれるフォルダに保存される。settings.xmlの<localRepository>で設定することが出来る。
- プラグイン
- ゴールとは、何らかの成果物。
- プラグインは、「複数のゴール」と「それらのゴールを達成するためのルール」が組み合わさったもの。フェーズとゴールの関係は 1 対多。
- maven [プラグイン]:[ゴール]で、あるプラグインのゴールを生成するプロセスが走る。
- プラグインが省略した場合は、javaプラグインがデフォルトで入る(java:packageとか)
- 自分でプラグインを作成するためのプロジェクトを作ることもできる
- アーティファクト
- アーティファクトは、プロジェクトの成果物 = jar
- mvm [フェーズ名]とすることで以下ができる。
- clean (一時ファイルの削除)
- validate (プロジェクトの状態確認)
- compile (プロジェクトのコンパイル)
- test-compile (テストコードのコンパイル)
- test (ユニットテストの実行)
- package (アーティファクトの作成)
- 通常targetディレクトリの中にアーティファクトが作成される。
- 例えば、mvm packageと打つと、それに必要なcompile, test-compile, testも走る。
- integration-test (インテグレーションテストの実行)
- verify (アーティファクトの検証)
- install (アーティファクトをローカルリポジトリに配置)
- deploy (アーティファクトをリモートリポジトリに配置)
- ビルド・ライフサイクル
- 「コンパイル→テスト→JAR作成」などのビルドにおける作業の順番を定義したもの
- 通常defaultライフサイクルというものが使われており、これは23個の直鎖状の依存関係からなる
- cleanは、一時ファイルの再利用のためdefault life cycleには含まれておらず、cleanライフサイクルという別のものに入っている。
- Mavenレポジトリ
- JARなどの成果物やJavadocをライブラリを整理してまとめておく場所のこと。他人と共有することもある(リモートレポジトリ)し、そうじゃない(ローカルレポジトリ)こともある。
- ローカルレポジトリ
- デフォルトでは~/.m2/repository
- リモートリポジトリにも公開されていないライブラリを使う場合には、まず mvn install でそのライブラリをプライベートリポジトリにインストールしてやると使えるようになる。
- 他のリポジトリからダウンロードしたライブラリを保管したり、installゴールでJARをインストールしたりするために使う
- リモートレポジトリ
- プライベートリポジトリは、自分でレポジトリを作って、会社内だけに公開とかが出来る。
- バージョン
- バージョンにSNAPSHOT修飾子を含めることで、使い手とMavenに対して安定版ではないことを伝える
- 安定バージョンは数字とドットのみ
- 他にもga, alpha, betaなどの修飾子がある。
- スナップショットバージョンとリリースバージョンは、<distributionManagement>などを使って違うリモートレポジトリを設定することができる (参考)
- セントラルレポジトリには、誰でもライブラリを登録することが出来る http://samuraism.jp/diary/2012/05/03/1336047480000.html
- WebDAVでアクセスするので、何らかのプラグインが必要
- デプロイは二つの方法がある
- deployフェーズ: プライベートレポジトリに主にSNAPSHOTバージョンを公開
- maven-release-pluginプラグイン: 安定バージョンの公開に使う。
- mvn release:prepare release:perform
- 権限がないと言われたら、~/.m2/settings.xmlにユーザ名とパスワードを入れないといけないというのがよくあるミス
- javacって何
- jarは実はJava Archive、実際には単なるzipに変な情報を足したもの
- JARファイルは.javaファイルではなく.classファイルを使用するので、javacコマンドでコンパイルする必要があります。
- jar cvf Test.jar test/で作れて、もうtarみたいなかんじ。
- 実際問題jar tvf Test.jarとするとMETA-INFとかが入っているだけなので、実質zip
- JARの識別する仕組みとして、groupId, artifactId, versionを特定するようにした。
- ビルドの仕組みもガチガチに決まっている。Default -> Clean -> SIteで、それぞれには9, 3, 4個の手順がある。
- これをライフサイクルの各フェーズという。
- ゴールは、ビルドの個々のタスク、コンパイル、JAR作成、ファイルのコピーなどをする。
- ゴールは全てプラグインが提供する、ゴールは「プラグイン名:ゴール名」compiler:compileみたいな形をしている。
- 要するにゴールは「コンパイルしろ」「テスト走らせろ」みたいな一つの行動に相当していて、これはプレでファインド。
- profileという機能があって、これを使うと本番・保守・開発でDBの接続設定を切り替えるとかできる
- $M2_HOMEというところにMavenのInstall Directoryがある
- .m2にダウンロードしたJARが格納
- java -cpはクラスパスを指定している
- java -jar Test.jar Test.jarにメイン・マニフェスト属性がありませんと言われるが、これはmain関数がどのクラスのものなのかがわからないため。これの修正のためには、Main-Class: test.Testというマニフェストを追加すると良い。
- Javaの特徴は、JVM (Java virtual machine)というマシンの上で仮想化されているので、どんな環境でもJavaが動作する
- VMが整然とシャットダウンされた場合には、JVMは登録されているシャットダウンフックを実行します。整然としたシャットダウンとは以下のものを指します。
- デーモンでないスレッドが全て終了した
- System.exitが呼ばれた
- ユーザ割り込みでの停止(Ctrl + C、SIGINT)
- GroupId?
- 他の全てのプロジェクトと区別するための名前です。 一般に使われるのは ドメイン名を逆にしたものです。 com.example など。 これをそのままパッケージ名のフォーマットに使うのが一般的です。
- ArtifactId?
- バージョンを除いた jar ファイルの名前です。 プロジェクト名といったほうがわかりやすいと思います。 たとえば project_a などにします。
- Version
- Intellij IDEA だと、 デフォルトで 1.0-SNAPSHOT となっていたりしますが、 フォーマットは決まっていません。 1.0.0 のようにもできます。
- packageはソースファイル内のクラスが所属するパッケージ名を指定するのに用います。 これをソースコードに書くと、mavenでコンパイルしている場合はtargetディレクトリを勝手にほってくれるので便利という感じっぽ。定義上一つのソースに一つしか存在しない。package文を省略すると、クラスは名前無しのパッケージに所属することになる。
- import文はくrスのロードではなく、クラスライブラリ探索のための省略ができるよと言うだけらしい。フルパスで書けば動くは動く。その性質から、当然名前衝突する可能性もあるので、*でimportするのは控えるのが良い。
- しかし、Javaにはパッケージ名の衝突を防ぐ仕組みはなく、インターネットドメイン名(DNSドメイン名)をパッケージ名として利用することを推奨している。
- JavaのdependencyがLogging version 2とLogging version 3のように衝突する場合は、エラーメッセージがちゃんと出るのでどちらかをexcludeで消さないといけない。
- 「compile」フェイズでは、maven-compiler-plugin の compile というゴールが実行されます。
- intelliJのビルドは、pomがあるところで実行しているっぽい。
- pomのreimportをした
- IntelliJでpomを変えたときには、reimportをしないとdependencyなどが反映されないっぽい。。。
- Javaのstatic
- static メソッドは、そのものがクラスのインスタンスではなく、クラスに属します。それ以上でもそれ以下でもない
Javaのfinal
final変数はconstみたいなもの。ぶんかとして 普通の変数と区別するために大文字にすることが多い。
final classは継承付加を表す関数。
ServeletのdoGetとかdoPostとかは当然HTTPリクエストに対応している
デザインパターン †
Builderパターン †
Pythonとかだと引数の名前にたいしてf(name="hoge")とかできるけど、Javaではできない。これを解決したいね、というやつ。
基本的には、インスタンスを直接作るのではなく、作ってくれる大工インスタンスを作る時点でビルダーパターンと言える。
Builderを使いたくなる理由
引数が多くなると、順番を正確に覚えておくのが難しくなる。
つまり引数の渡し間違いが発生しやすくなる
任意の値があると、適当な値をわざわざ渡す記述を書く必要がある。
つまり記述量が無駄に多くなる
↑の例でいうと、 ageは任意の値です。任意だけど、コンストラクタに引数として与えなければならない以上記述はしないといけないですね。無駄なことです。
DAO †
In computer software, a data access object (DAO) is an object that provides an abstract interface to some type of database or other persistence mechanism.
サーブレット †
というかJSPでいじる変数ってsessionに書き込まれたAttributeから得る感じなのか…なるほど
Datastoreのkindには_ah_SESSIONというのがあって、javaのセッション管理は自動的にここのkindが使われる
Javaのdo filterを考えるときには、二つのフィルタがあってそのあいだの順序はweb.xmlで決める(めんどいし順序に依存しないようにfilterを設計するのが大事)
chain.doFilteより上が前処理、下が後処理
フィルタ
リクエスト・リスポンスの整形をすることができる。生のリクエストは結構汚いので、サーブレットが処理する前後でいろんなデータ正しい状態にするための機能
FilterChain?のdoFilterメソッドによって一連の処理が実行されるので、これより前で処理を行うか後ろで処理を行うかで、クライアントからの要求と応答のどちら側でフィルタリングを行うか決定する事ができます。
JSP Standard Tag Library (JSTL) Tutorial -
手順としては、
- pom.xml のproject/properties/bookshelf.storageTypeとかにstringを格納する
- this.getServletContext?().getInitParameter?("bookshelf.storageType");とかで何のデータベースを利用しようとしているのかを確認する
- サーブレットのinitでthis.getServletContext?().setAttribute("dao", dao);をして初期化
- リクエストが来ると、doGetにプログラムポインタがくる。
- doGetの中で、this.getServletContext?().getAttribute("dao");をしてDAOを取得
- ?cursor=%sみたいなやつを、req.getParameter("cursor")で取得する(getAttributeとかはまじで型を限定しないような形になっているっぽい、具体的にはObject型)
- サーブレットでreq.setAttribute("var", arr)を何回もして配列や変数を登録。配列はList<T>を突っ込む。
- サーブレットでreq.getRequestDispatcher?(jsp).forward(req, resp)をする
- jspで${var}が使えるようになっているのでフロントのテンプレートを頑張る。クラスの場合、クラスのメンバ変数には、var.imageURLみたいな感じで親子的にアクセスできる。
JSPファイル
Webサーバ上で動くプログラム
Javaの中でもウェブサーバでレスポンシブに動くプログラムをサーブレットと言うらしい。
JSPがpythonでやっていたプログラマブルなHTMLに相当している
JSPはServlet containerがJavaServlet?に変換して、その役割で働く
Servlet ContainerはServletをspin upしたあと、すぐに落とさない(CGIは寝る)。マシン単体でのスケールアップについて責任を追っているので、マルチスレッド対応している。
サーブレットコンテナとして一番有名なのは「Apache Tomcat」
JavaServer Pages が使われています。これは Java テンプレート エンジンの一種ですが、サーブレットとして実行されます。
getSessionという概念がある。これを使って以下のようにすると、reqにもsessionにもかきこまれるようになるみたい。
req.getSession().setAttribute("cursor", endCursor);
req.getSession().setAttribute("page", "list");
intelliJ †
メソッドのコードや定義の確認のためにはC-bで行ける(Alt-Leftかも)
intellliJで、文字列リテラルにs: とかo:とかついているのは、呼び出し元の型がstringかObjectかという違いによるもの
というか関数の中の変数としてthisを渡していたりするときも、それがどの方7日がわからなくならないようにbuilder:とかがついている
- ショートカット
- C-N Navigate class search
- CS-Nでnavigate file
- C-SpaceでCode completion
- A-F7でFind Usage
- C-Qでドキュメントを読む
- C-Bで宣言を見る
- C+F12で現在編集中のファイルへ
- S+F6 全変数rename
Jetty †
- 100%Javaで開発されたJava Servletコンテナ/Webサーバである。WebSocketなどのプロトコルもサポートする。Jetty はオープンソース (Apache 2.0 License) でリリースされている。JBoss、Apache Geronimoといった他のプロジェクトでも利用されている。
- 単純で効率的な組み込みやすいWebサーバとなるよう意図して開発されている。
- サイズが小さいので、組み込み型 Java アプリケーションにWebサービスを提供するのに適している。
- その一方で、Apache HadoopやGoogle App Engineといった大規模でスケーラビリティが重視されるサービスにおいても採用されている[2]。
- 2009年1月、WebtideはJettyのコアコンポーネントをcodehausからEclipse Foundationに移管することを発表した。
- サーブレットの一種でTomcatと双璧をなしているらしい。GAEで採用されているのはびっくりした。
- Tomcatに比べると軽量で、Apache+Tomcatではオーバースペックになっている可能性。TomcatのHTTPサーバ機能は開発者向けで本番環境向けではないが、JettyはHTTPSがついているのでApacheがいらない。あと起動が早い。
- Maven Surefire プラグインはユニットテストの実行のためのもの。JUnitと何が違うの?
未整理 †
- intelliJでJDKを帰るにはProject Structureとかいうのを使えば良い
- mavelはlifecycleというものがあるclean, site, deployがデフォルトで、siteはドキュメントを作るためのコマンド。
- その他にもvalidate, comile, test, package, verify, installなどいろいろなコマンドがあって、これらの動きを制御するための情報がpom.xmlに書いてある。
- IDEは適切に選ぶ。
- node.jsとかはIntelliJ Ultimateを使ったり、JavascriptはVSCodeを使うのが良い。
- pom.xmlのbuild as maven projectを押した
- あとSDKはデフォルトで走らなかったからreadlink -f $(which java)をしてGoogleのJDKを使った
- javaのデフォルトのJDKを調べる方法
- readlink -f $(which java)
- コマンドを走らせるときはものすごく気をつける!!!
- そもそもいい加減に走らせない。何をやろうとして走らせているのかを把握して作業する。
- mavenはjavaのビルドツール
- javaのPOMとは?pom.xmlというファイルによってビルドできる
- A Project Object Model or POM is the fundamental unit of work in Maven.