20210507のJavaに関する記事は6件です。

Oracle認定Java_silver対策メモ2

はじめに エンジニアとして働き始めはやくも5ヶ月目、そろそろ資格をとろうかと。。。ということで!「Oracle認定JavaSE Silver」の対策として、黒本をもとに各章ごとの重要そうなポイントをピックアップしまとめたものの後編です。前半の記事はこちらです。 7章 クラスの継承、インターフェース、抽象クラス インターフェイス  フィールド:定数のみ持つことができる。(自動的にpublic static finalがつく)  メソッド:publicな抽象メソッドやdefaultメソッド、staticメソッドを持つことができる。 <defaultメソッド> Java8 SEかより、defaultメソッドを利用することでインターフェイスにメソッドの実装ができるようになった。 default 戻り値型 メソッド名 (引数の型 引数名){  // 処理内容を記述 } ※defaultメソッドの注意点 インターフェイスを実装したクラスからdefaultメソッドを呼び出す。  → インターフェイス名.super.メソッド名() defaultメソッドの注意点として、オーバーライドする際にjava.lang.Objectに定義されているメソッドをデフォルトメソッドとしてオーバーライドすると、コンパイルエラーが起こるので注意!  → equals()、clone()、toStrign()メソッドなど defaultメソッドは、直接実装したクラスからしか呼び出すことができない。(階層を跨ぐことができない) ポリモーフィズムしたインスタンスを呼び出しについて フィールドを参照した場合、変数の方で宣言された方を使う メソッドを呼び出した場合、メソッド内の指示に従う コンストラクタ サブクラスのコンストラクタには、スーパークラスのコンストラクタを呼び出すsuper()が自動的に追加される。 8章 関数系インターフェース、ラムダ式 ラムダ式 ラムダ式とは、メソッドを変数と同様に扱うことができる文法です。 関数インターフェイス型 変数名 = (引数1,引数2,・・・) ->{return 処理}; // 引数の型は記述しなくてもよい。 関数インターフェイス型 変数名 = 引数 -> {return 処理}; // 引数が一つしかない場合は()を省略することができる。 関数インターフェイス型 変数名 = (引数) -> 処理; // 実行する処理が一つしかない場合は{}を省略することができる。 // また、{}を省略した場合、returnも省略する。(記載できない) ※ラムダ式の注意点 ラムダ式では、ローカル変数と同じ変数名のフィールドを持つことができない。 ラムダ式内からローカル変数にアクセスする場合、ローカル変数がfinalな変数でなくてはいけない。 主要な関数系インターフェイス Consumer Supplier Predicate Function <>(ジェネリクス型)のパラメータを受け取ることが可能なのは4つのうちFunctionのみ 9章 API 10章 例外処理 finallyが記述されている場合、例外がスローされなくてもfinally文が実行される。 例外処理の記述順はtry->catch->finallyでなくてはいけない クラスがキャストできない場合、その例外を示すClassCastExceptionがスローされる. catch()文にreturnがあっても先にfinallyを処理した後に戻される. 11章 モジュールシステム
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

jib-maven-pluginでAzure Container RegistryにSpring Bootアプリのイメージを登録する

以下のクイックスタートを参考にSpring BootアプリのイメージをAzure Container Registryに登録してみました。 クイックスタートと以下の点で異なる手順を試しました。 - Azure Container RegistryはAzure CLIではなくダッシュボードで作成 - Spring Initializrで作成したプロジェクトを利用 - Azure Container Registryでアクセスキーを発行 以下まとめます。 Azure Container Registryの作成 コンテナーレジストリを選びます。 SKUはBasicにしました。 作成後「アクセスキー」の管理者ユーザを「有効」にしました。クイックスタートの中ではAzure Container Registryの認証について特に書かれていないのですが、何もしないままだと認証エラーになってしまったので今回はこの手順を踏みました。 Azure Container Registryの準備は以上です。 Spring BootアプリとJibの準備 クイックスタートではSpring Boot on Docker Getting StartedのコードをCloneしていますが、私はSpring Initializrで作成したプロジェクトを使いました。依存性に加えたのはSpring Webのみです。 pom.xmlにjib-maven-pluginの定義を追加して、さきほどAzureで作成したAzure Container Registryのサーバを指定します。(ここでは作成するリポジトリ名をdemoにしました) 認証情報も設定します。 <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>jib-maven-plugin</artifactId> <version>3.0.0</version> <configuration> <to> <image>xxxxxxxxxxx.azurecr.io/demo</image> <auth> <username>xxxxxxxxxx</username> <password>xxxxxxxxxxxxxxx</password> </auth> </to> </configuration> </plugin> </plugins> </build> あとは以下でビルドするだけです。これでSpring BootアプリのイメージをAzure Container Registryに登録してくれます。 mvn compile jib:build リポジトリを確認すると無事作成されています。 認証周りはもう少し理解を深めたいです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Java HTMLをPDFに変換 

今日は Spire.PDF for Javaという無料のライブラリを使って、HTMLをPDFに変換する方法を紹介します。今回はSpire.PDF for Java 3.6.6以上のバージョンが必要なので、要注意です。また、従来の方法とは違って、今度はGUI機能も必須だから、Xvfbといったようなプログラムをダウンロードしておいてください。 下準備 1.E-iceblueの公式サイトからFree Spire.PDF for Java無料版をダウンロードしてください。   2.IDEを起動して新規プロジェクトを作成してから、インストールされたファイルにあった相応しいSpire.PDF.jarを参照に追加してください。 import com.spire.pdf.graphics.PdfMargins; import com.spire.pdf.htmlconverter.qt.HtmlConverter; import com.spire.pdf.htmlconverter.qt.Size; public class HtmltoPDF { public static void main(String[] args) { //HTML を名付ます。 String url = "https://www.google.com/"; String fileName = "Result.pdf"; String pluginPath = "D:/Qt/plugins_32"; HtmlConverter.setPluginPath(pluginPath); //PDFで保存ます。 HtmlConverter.convert(url, fileName, true, 1000000, new Size(600f, 900f), new PdfMargins(0)); } } 実行結果  
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

# Azure 向け Spring ライブラリまとめ

いくつか Azure 向けの Spring ライブラリを紹介してきましたが、今回はそのまとめです。必要な事は全て以下に書いてあると思います。 Azure Spring Boot その名の通り、Spring Boot 用のライブラリ群です。基本的に、Spring Boot 2.2/2.3/2.4 に対応しています。 対応しているサービスは、主な物を上げると以下の通り。 Active Directory / Active Directory B2C Cosmos DB Key Vault (Secret/Certificate) サービスバス ストレージ(BLOB) また、最新版は、以下のような作りになっています。 バージョンが、3.0 以降 名前空間が com.microsoft.azure から com.azure.spring Artifact Id が azure-spring-boot-starter-* で統一 たまにSDK間で依存関係の不具合がおきたりするので、dependencyManagement でBOMを指定しましょう。Spring Initializr で作ると、ちゃんと埋め込まれています。BOMとは依存関係のバージョンをしたりすると特殊なPOMらしいです。 Maven Repository: com.azure.spring » azure-spring-boot-bom <dependencyManagement> <dependencies> <dependency> <groupId>com.azure.spring</groupId> <artifactId>azure-spring-boot-bom</artifactId> <version>${azure.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> これに当てはまらないものは、すでに Deprecated になっているライブラリもありますので、使い始める際には注意したほうがよいです。 MSのドキュメントは更新が追いついていないせいか、古いライブラルを紹介している場合も多いので、原文(英語)を確認したり、Githubを当たった方が最新の情報を得られると思います。 Azure Spring Cloud Spring Cloud は、マイクロサービスベースのアプリを構築するために容易されたフレームワークです。Boot用というわけではなく、Spring アプリともシームレスに統合されているものです。 あまり強調しませんでしたが、以前に説明したKey Vault はBoot用、App Configuration は Cloud用のライブラリです。いまいちどのあたりに、その区切りとなる判断基準があるかわからないのですが、Key Vault だってマイクロサービスで使うでしょうに。 対応しているサービスは、主な物を上げると以下の通り。 キャッシュ(Azure Redis) イベントハブ サービスバス トピック&キュー ストレージキュー また、最新版は、以下のような作りになっています。 バージョンは、2.0 以降 名前空間が com.microsoft.azure から com.azure.spring Artifact Id が azure-spring-cloud-* または、 azure-spring-integration-* で統一 個別にサンプルが用意されているので、試してみると良いと思います。 キュー連携を試してみる 試しに、azure-spring-cloud-starter-storage-queue を試してみます。Azure Functionsにキュートリガーがあるので、こちらの使いごこちはどのような物かという単なる興味からです。 生のキュークライアントをDIする代わりに、のStorageQueueOperation を介してキューのオペレーションをスルみたいです。 PostがメンドウだったのでGetでエンキューしていますが、sendAsync でエンキュー、 receiveAsync でデキューしています。 チェックポイントクラスで、成功の可否を判定しているのですが、これがどういた意味をなしているかはちょっと分らなかったです。 @Autowired StorageQueueOperation storageQueueOperation; @GetMapping("/push") public String send(@QueryParam("message") String message) { this.storageQueueOperation .sendAsync(STORAGE_QUEUE_NAME, MessageBuilder.withPayload(message).build()) .subscribe(); LOGGER.info("Message {} has been sent successfully.", message); return message; } @GetMapping("/pull") public String receive() { this.storageQueueOperation.setMessagePayloadType(String.class); this.storageQueueOperation.setCheckpointMode(CheckpointMode.MANUAL); Message<?> message = this.storageQueueOperation.receiveAsync(STORAGE_QUEUE_NAME).block(); if (message == null) { LOGGER.info("You have no new messages."); return null; } LOGGER.info("Message arrived! Payload: " + message.getPayload()); Checkpointer checkpointer = message.getHeaders().get(AzureHeaders.CHECKPOINTER, Checkpointer.class); checkpointer.success() .doOnSuccess(Void -> LOGGER.info("Message '{}' successfully checkpointed", message.getPayload())) .doOnError(e -> LOGGER.error("Fail to checkpoint the message", e)) .subscribe(); return (String) message.getPayload(); } まとめ 日々変化しているので、数ヶ月前の状況が古くなっていることが多いのですが、一次情報(Github)を当たれば、ソースも公開されていますし、サンプルもありますし、何かあればIssue切れますし、便利な世の中だなと思っている今日この頃です。こまったら、ソース見ましょう。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java】equals()とは一体なんぞや

はじめに JavaSilverの学習中にて 「ふむふむ、equals()は2つのインスタンス間の同一性を判定するものなんだな」 「あれ?でもこっちには同値性を調べるって書いてる…」 「String型のequals()は親クラスのObject型のequals()を引き継いでるからデフォルトのままやろな……違うの!?なんで!?」 とまあ、概念の理解がなかなかに困難だったので備忘録としてまとめておきます。 同一性と同値性 前提知識として… ・同一性 複数の変数が同じインスタンスを参照しているどうか 下記の例だと、オブジェクト型の変数aにインスタンスaへの参照先を代入して、 オブジェクト型の変数bに変数aの中身(インスタンスaへの参照先)を代入しており、 変数は違えど参照先は同じインスタンスであるため、同一性であると言える。 Object a = new Object(); Object b = a; System.out.println(a == b); //result:true ・同値性 異なるインスタンスでも、その中身が等しいかどうか 下記の例だと、String型のa,bは異なるインスタンスだが、 中身の値は同じであるため、同値性であるといえる。 String a = "Hello"; String b = "Hello"; System.out.println(a == b); //result:true equals() Objectクラスで定義されているメソッドで、デフォルトでは同一性を調べるものとなっている。 public boolean equals(Object obj){ return (this == obj) } ただ、ここで注意すべきなのが、equals()は本来同値性を調べるもので、 オーバーライドを用いてクラスごとに再定義するのが普通である。 JavaSilverつまずき問題 混乱したのが下記の問題(JavaSE8 Silverの黒本より) //第3章 問12 実行結果はどうなるか public class Main{ public static void main(String[] args){ String a = "sample"; String b = "sample"; System.out.print(a == b); System.out.print(","); System.out.print(a.equals(b));//result:true,true } } System.out.print(a.equals(b));のコードが「はじめに」で述べてた箇所で、 「String型のequals()は親クラスのObject型のequals()を引き継いでるからデフォルトのままやろな……違うの!?なんで!?」 に繋がります。 そのときの自分の誤った考えとしては 「えっと、equals()を呼び出して、インスタンスa, bの同値性を調べるんだよな。 あ、でもString型のequals()はObject型のequals()を引き継いでるから同一性判定なのか。 じゃあa,bは異なるインスタンスだからこれはfalseだな」 と考えた結果、答えはtrueだったので「えぇっ!?」となりました(語彙力) (まあそもそも真ん中の行で「==」で同一性判定を行ってて、 そこがtrueだって分かったなら今回のequals()もtrueだってなりそうなもんですけどね…) 1.String型でもequals()はオーバーライドされている 「String型のequals()はObject型のequals()を引き継いでるから同一性判定なのか」 と述べていますが、半分不正解です。 Object型のequals()は同一性判定の定義となっていますが、 String型でequals()はオーバーライドされており、 2つのインスタンスが同値性の関係かを調べるものとなっています。 (コードは省略) おわりに 1,2時間ぐらいかけて勉強しましたが、正直まだまだ理解できていない部分も多いです。 また更新します。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Eclipse+Forgeでマイクラのmod開発~イベントハンドリングしてみようず

今回はイベントハンドリングの方法を書いていきます。だんだん、準備段階から開発段階に進んできた感じがしますね。イベントハンドリングができればプレイヤーが何かをしたときに爆発させたり建築ができたり色々と夢広がりんぐです。ちなみにこの記事の執筆時点でmunecraftもまだ勉強中なので今後大いに修正する可能性あり。。 環境 OS: Windows10 Jdk: openjdk version "15.0.2" 2021-01-19 ※16.xでもいいかもだけどgradleやらなにやら色々変わってしまって心配だったので今回は15で。 IDE: Eclipse IDE for Java Developers (Version 4.19.0) Buildship(Eclipseのgradleプラグイン): 3.0 Minecraft: Java版 1.16.5 Forge: 1.16.5 何はともあれイベントハンドリングをしてみる 仕組みの話とか色々ありますがまずは動かしてみたいよね~ということでサンプルコード。これを中心に解説していきます。前回の記事の空のmodをベースに少しコードを書き加えてみます。 EmptyMod.java package jp.munecraft.mod.test; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.player.PlayerEvent.ItemPickupEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @Mod("emptymod") public class EmptyMod { private static final Logger LOGGER = LogManager.getLogger(); public EmptyMod() { LOGGER.info("Welcome to munecraft mod!!!"); MinecraftForge.EVENT_BUS.register(this); } @SubscribeEvent public void onItemPickUp(ItemPickupEvent event) { LOGGER.info("Item Pickup!"); } } 実行してみましょう。いかにもアイテムをとった時にログを出すイベント処理のように見えますが、実際にアイテムを拾ってみると。。。 [22:29:02] [Render thread/INFO] [minecraft/AdvancementList]: Loaded 7 advancements [22:29:06] [Server thread/WARN] [minecraft/MinecraftServer]: Can't keep up! Is the server overloaded? Running 11568ms or 231 ticks behind [22:29:16] [Server thread/INFO] [jp.mu.mo.te.EmptyMod/]: Item Pickup! [22:29:16] [Render thread/INFO] [minecraft/AdvancementList]: Loaded 9 advancements [22:29:19] [Server thread/INFO] [minecraft/IntegratedServer]: Saving and pausing game... ログが出ましたね。ほら、簡単。 なんて話で終わりだとなんの説明にもならないのでここで少し解説。さらに詳細を後述していきます。 まずはコンストラクタの中のMinecraftForge.EVENT_BUS.register(this);。これは要するにForgeのイベントハンドラをイベントバス、という仕組みに登録する処理です。これをすることによって、今後EmptyModがイベントハンドラとして認識されます。 次に@SubscribeEventアノテーションがついたpublic void onItemPickUp(ItemPickupEvent event)。これは、イベントバスに対して、イベント発生時に呼び出してほしいメソッドにマークする処理になります。この合わせ技で、マイクラの中でプレーヤがアイテムを拾った時にpublic void onItemPickUp(ItemPickupEvent event)を呼び出してもらえるようになるという寸法です。 イベントバス Forgeではイベントバスという仕組みでイベントハンドリングの仕組みを提供しています。これはある意味名前の通りですが、イベントが発生するとイベントバスを通じてイベントバスに登録されているイベントハンドラを発火させていく、というものです。 Forgeには次の二つのイベントバスがあります。 Forgeのイベントバスこれは前述のサンプルコードにあるMinecraftForge.EVENT_BUSが該当します。こちらはメインのイベントバスで、基本的にゲームが開始(ワールドが読み込まれ始めるタイミング)以降のイベントを拾うためのイベントバスです。 FML(Forge Mod Loader)イベントバスこちらはゲームを開始する前、modを読み込んでいる段階で発火されるイベント群のイベントバスの模様。正直現時点では使意道があまりわかってないですw イベントハンドラの登録方法 明示的に各イベントバスのregister()を呼び出して登録する方法と、アノテーションを使う方法があります。正確にはほかにもaddListener()にラムダ式で渡す方法がありますがそちらは今度追記します。 明示的にregister()を呼び出す方法 public EmptyMod() { LOGGER.info("Welcome to munecraft mod!!!"); // こっちがForgeのイベントバスにイベントハンドラとしてthisを登録する方法 MinecraftForge.EVENT_BUS.register(this); } public EmptyMod() { LOGGER.info("Welcome to munecraft mod!!!"); // こっちはFMLのイベントバスにイベントハンドラとしてthisを登録する方法 FMLJavaModLoadingContext.get().getModEventBus().register(this); } 同じクラスをForgeとFMLの両方のイベントバスに登録しないようにしましょう。じゃないと後述する@SubscribeEentがどちらのイベントハンドラなのか混乱してランタイムエラーを引き起こすことになります。 ところでイベントハンドラとして登録しているthisは何のクラスもインターフェイスも継承/実装していません。上述したregister()メソッドはObject型を受け取るのでなんでも登録できちゃうんですね。じゃあどうやってイベントハンドラのメソッドを呼ぶんだ。。。と謎に思ってしまったけど、その種明かしが@SubscribeEventアノテーションにありました。これもまた後述。 クラスをアノテーションでイベントハンドラとして登録する方法 2つクラスを追加しました。 ForgeEventHandlerTest.java package jp.munecraft.mod.test; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import net.minecraftforge.event.entity.player.PlayerEvent.ItemPickupEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.FORGE) public class ForgeEventHandlerTest { private static final Logger LOGGER = LogManager.getLogger(); @SubscribeEvent public static void onItemPickupEvent(ItemPickupEvent event) { LOGGER.info("ForgeEventHandlerTest::onItemPickupEvent called."); } } ModEventHandlerTest.java package jp.munecraft.mod.test; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; @Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD) public class ModEventHandlerTest { private static final Logger LOGGER = LogManager.getLogger(); @SubscribeEvent public static void onFMLCommonSetupEvent(FMLCommonSetupEvent event) { LOGGER.info("ModEventHandlerTest::onFMLCommonSetupEvent called"); } } 起動してみるとまずゲームを開始する前にModEventHandlerTest::onFMLCommonSetupEvent calledがログに出力され、次にゲームを開始してアイテムを拾うとorgeEventHandlerTest::onItemPickupEvent called.がログに出力されます。うん、期待通り。 コードを見ると大体想像がつくと思いますが、@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.FORGE)アノテーションと@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)アノテーションがミソですな。前者は、このクラスがForgeのイベントバスに登録したいイベントハンドラであることを示し、後者はFMLのイベントバスに登録したいイベントハンドラであることを示しています。 注意してほしいのは、今回はメソッドがstaticな点。インスタンス化してイベントバスに渡していないので、このアノテーションで登録する場合はメソッドはstaticである必要があります。 イベントハンドラのメソッド ここが正直悩みました。。。なんのイベントが発生したときにどのメソッドが呼ばれるのか。。。メソッド名から識別している!?なら指定できるメソッドがわかるようにスーパークラスがあればいいけどイベントハンドラはObject型で受け取っていて、任意のクラスを渡せるし。。。 答えは引数でした。 先ほどのサンプルコードでonItemPickupEvent(ItemPickupEvent event)は引数にItemPickupEventを指定してます。Forgeは@SubscriveEventのメソッドの引数だけを確認して、該当するイベントが発生したときに発火してくれます。なので、メソッド名はhogeでもpiyoでも@SubscriveEventアノテーションを付けてItemPickupEventを引数につければアイテムを拾ったときに発火されます。 イベントハンドリングのポリモーフィズム 実はイベントハンドラのメソッドにはポリモーフィズムな仕組みが備わっています。例えば先ほどのItemPickupEventはPlayerEventというクラスを継承しています。例えば先ほどのコードを次のように書き換えてみる。 ForgeEventHandlerTest.java package jp.munecraft.mod.test; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import net.minecraftforge.event.entity.player.PlayerEvent.ItemPickupEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.FORGE) public class ForgeEventHandlerTest { private static final Logger LOGGER = LogManager.getLogger(); @SubscribeEvent public static void onItemPickupEvent(PlayerEvent event) { LOGGER.info("ForgeEventHandlerTest::onItemPickupEvent called."); } } すると、ItemPickupEventも含めた、PlayerEventを継承したすべてのイベントをハンドリングするようにコードが変わります(ログが膨大に出るので注意)。極端な話、最上位クラスのEventクラスを引数に指定するとゲーム中の(おそらく)すべてのイベントでハンドラが発火することになります(こちらもログが大量に出るので注意)。 FMLのイベントバスへの登録時の注意点 FMLのイベントバスに登録するイベントハンドラのメソッドには注意が要ります。ForgeのイベントハンドラはEventクラスを継承していればなんでも受け取れますが、FMLのイベントバスではIModBusEventを継承したイベントしか@SubscribeEventできません。 主なイベント を書こうと思ったけど。。。膨大にあるし全部はわからないので挫折。。いずれ使いでのある重要なイベントだけでもリファレンス化しようと思いますが。。とりあえずゲーム中のイベントとしてはnet.minecraftforge.eventパッケージは以下をあさってみてくださいな。クラス名から直感的にいつ発火するかわかりやすいイベントも多く存在しているので。特にプレイヤーが何かをしたときに発火させたくなることが多いと思うのでnet.minecraftforge.event.entity.playerの下を掘ると色々出てくると思います。 あと、今度記事にしようと思いますがコマンド追加関連で重要なのはnet.minecraftforge.event.RegisterCommandsEventですね。コマンド追加関連はネット上に転がっているドキュメントが軒並み古くて苦労したので次回記事にしようと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む