スキップしてメイン コンテンツに移動

投稿

ラベル(Java)が付いた投稿を表示しています

Thymeleafのthymeleaf-layout-dialectライブラリはGraalVMで使えない (2023年2月時点)

筆者の開発しているプロジェクトでは、Spring BootのテンプレートエンジンにThymeleafを使っており、全画面共通のレイアウトテンプレートを定義するために thymeleaf-layout-dialect を利用していました。 このプロジェクトでGraalVMを使ってネイティブコードを生成しようと悪戦苦闘していたのですが、2023年2月時点では thymeleaf-layout-dialect がネイティブコンパイルに対応していないため無理という結論になりました。 native-imageのコマンド実行時にエラーになるクラスを --initialize-at-build-time 、 --initialize-at-run-time で手作業で追加していたのですが、追加する数が多すぎて無理でした。。。 それほどページ数は多くなかったので、泣く泣く thymeleaf-layout-dialect の利用をあきらめ、重複は増えてしまいますが、Thymeleaf標準機能だけで全テンプレートを書き換えました。 GitHub上のissueを見ていたところ、ライブラリの作成者も問題に気づいているようなので、今後対応されるかもしれません。 https://github.com/ultraq/thymeleaf-layout-dialect/issues/232

Spring Bootのコンテンツ配信でgzip圧縮を有効にする方法

Google App EngineのJava 17のStandard EnvironmentでSpring Bootアプリケーションを運用していたところ、サーバーから送信されるhtmlにgzip圧縮が効いていないことに気が付きました。 gzip圧縮が効いているかどうかは、下記のようなサイトに調べたいページのURLを入力すれば確認できます。 https://pagespeed.web.dev/ https://www.giftofspeed.com/gzip-test/ Spring Bootでgzip圧縮を有効にするにはapplication.propertiesに下記のように追記すればOKでした。ちなみにGoogle App Engine側の設定は特にいじっていません。 # 圧縮を有効にするかどうか server.compression.enabled = true # 圧縮対象のmite type server.compression.mime-types = text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json # 圧縮を効かせる最小レスポンスサイズ server.compression.min-response-size = 1024 Google App EngineのDash Boardで確認したところ、見事にネットワークの使用帯域が1/5になりました!

JOGLのプログラムが起動しない問題

JOGLのエラー JOGL - Java™ Binding for the OpenGL® API のプログラムを久しぶりに動かそうとしたところ、下記のエラーが出てしまい動きませんでした。 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 1 at jogamp.opengl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationImpl(WindowsAWTWGLGraphicsConfigurationFactory.java:171) at com.jogamp.nativewindow.GraphicsConfigurationFactory.chooseGraphicsConfiguration(GraphicsConfigurationFactory.java:424) at com.jogamp.opengl.awt.GLCanvas.chooseGraphicsConfiguration(GLCanvas.java:1560) at com.jogamp.opengl.awt.GLCanvas.addNotify(GLCanvas.java:611) at java.desktop/java.awt.Container.addNotify(Container.java:2804) at java.desktop/java.awt.Window.addNotify(Window.java:791) at java.desktop/java.awt.Frame.addNotify(Frame.java:495) at java.desktop/java.awt.Window.show(Window.java:1053) at java.desktop/java.awt.Component.show(Component.java:1728) at java.desktop/java.awt.Component.setVisible(Compon...

JetBrains社のIDE上のデータベースツールでSSLのエラーでデータベースに接続できない問題

JetBrainsのIDE内のツールを使ってデータベース(MySQL)に接続しようとしたところ、下記のエラーが出て接続に失敗しました。 Failed Cancel Copy Search Error Troubleshooting [08S01] Communications link failure The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate). 少し調べたところ、JetBrainsのIDE内のJavaを使っている部分のエラーであることがわかりました。根本の原因は、 こちらの記事 に書かれていました。 「接続先ホストからJavaが対応していないTLS(いわゆるSSL)のプロトコルバージョンを要求されたときに出る」ものとのことです。 サーバー側のTLSの設定を変えられない場合、Javaのクライアント側で対応していないTLSのプロトコルバージョンを許可することでこのエラーは回避できます(セキュリティレベルの低いプロトコルを許可することになるので、そのリスクを理解したうえで作業を実施してください)。 C:\Program Files\JetBrains\{JetBrainsのIDE}\jbr\conf\security\java.security 内の下記の記述の部分からTLSv1, TLSv1.1を削除します。 # Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3...

Spring Bootでwarファイルを作成する方法

Google App Engine JavaでSpring Boot + Gradleを使ってアプリケーションをデプロイする方法を調べた。 まずは、下記のオフィシャルを参考に、Gradle App Engine Pluginを導入 Using Gradle and the App Engine Plugin | App Engine standard environment for Java docs | Google Cloud MavenでSpring Bootアプリケーションを作成する方法 https://cloud.google.com/appengine/docs/standard/java11/building-app/writing-web-service Spring Bootアプリケーションを作成→Gradle App Engine Pluginを導入 下記の記事の方が参考になりました。 https://blog.uoneweb.net/2021/09/04/695/ https://zenn.dev/donchan922/articles/ea76614f72b15e

NetBeansが「invalid jdkhome specified」エラーで起動しな場合の対処法

Windows 10のPCでJavaのバージョンを入れ替えた後、NetBeansを起動しようとしたのですが、「invalid jdkhome specified」「Cannot find java 1.8 or higher」というエラーが派生して、NetBeansが起動しなくなってしまいました。 環境変数のJAVA_HOMEが原因かとも思いましたが、筆者の環境で使用している C:\Program Files\AdoptOpenJDK\jdk-8.0.292.10-hotspot\ が正しく設定されていました。 調査したところ、原因は C:\Program Files\NetBeans-12.0\netbeans\etc\netbeans.conf 内の netbeans_jdkhome の設定でした。 netbeans.conf にインストールしてあるJDKを指定して、無事起動するようになりました(下記は筆者の例ですので、各人の環境にインストールしてあるJDKを指定してください)。 netbeans_jdkhome="C:\Program Files\AdoptOpenJDK\jdk-8.0.292.10-hotspot" 編集時の注意点としては、Administrator権限でファイルを編集する必要があります。 Windowsの検索ボックスで「Command Prompt」を検索。 検索結果に出てきた「Command Prompt」プログラムを右クリックして、「Run as administrator」でプログラムを起動。 cd "C:\Program Files\NetBeans-12.0\netbeans\etc" のようにインストールしてあるNetBeansのetcディレクトリへ移動。 notepad netbeans.conf と入力してnotepadを起動。 notepadで netbeans_jdkhome のエントリを探して使いたいJDKのホームディレクトリを指定して、ファイルを保存。 筆者は、最初Administrator権限ではなく、普通のユーザで直接netbeans.confを編集してしまい、変更が反映されずにしばらく原因を探るのに時間がかかってしましました。

FirebaseのEmulatorを利用する際にJavaをインストール

Firebaseのエミュレータ起動に失敗 Windows環境で firebase emulators:start コマンドを実行してFirebaseのエミュレータを起動しようとしたところ、下記のようなエラーが発生しました。 i firestore: Firestore Emulator logging to firestore-debug.logosting ! firestore: Fatal error occurred: s are not running, calls to these services from the Functions emulator will affect p Firestore Emulator has exited because java is not installed, you can install it from https://openjdk.java.net/install/, Your requested "node" version "10" doesn't match your global version "14" stopping all running emulatorsirestore-emulator-v1.11.15.jar... i functions: Stopping Functions Emulator i firestore: Stopping Firestore Emulator ! firestore: Error stopping Firestore Emulator 解決法 Javaがインストールされていないとのエラーメッセージなので、 AdoptOpenJDK をインストールします。この記事を書いている時点でのLTSのJava 11をインストールして無事起動するようになりました。

JavaのServlet内で他のURLから取得したデータをそのまま出力するコード

JavaのServlet内で他のURLからデータを取得してそのまま、レスポンスを出力するためのコードサンプルです。 使っているのはJavaの標準ライブラリのみなので、移植性は高いと思います。googleの提供しているライブラリやApacheのcommonsのライブラリを使うともう少しコード量は減らせると思います(特に汎用的なcopyメソッドの部分)。 import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; public class ServletUtils { private static final int _20K_BYTES = 20480; public static void fetchUrlAndDirectlyRespond(HttpServletResponse resp, String contentType, String urlStr) throws MalformedURLException, IOException, URISyntaxException { URL url = new URI(urlStr).toURL(); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setRequestMethod("GET"); connection.connect(); ServletOutput...

JavaでTimeZoneを指定して日付をフォーマットする方法

国際的に使われるソフトウェアを開発している場合、日付のタイムゾーンを意識しなければならないことがあると思います。 JavaではZoneIdクラスとZonedDateTimeクラスを利用することで簡単に指定することができます。 下記にAsia/Tokyoのタイムゾーンを指定して、7日前の日付をuuuuMMddHHmmフォーマット(分単位まで表示。例: 2021年2月13日21時34分ならば202102132134)で出力するサンプルコードを示します。 private static final ZoneId TIMEZONE_TOKYO = ZoneId.of("Asia/Tokyo"); private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("uuuuMMddHHmm"); String date_7_days_before = ZonedDateTime.now(TIMEZONE_TOKYO).plusMinutes(-7).format(DATETIME_FORMATTER); System.out.println(date_7_days_before);

テキストをNグラムに分割するJavaプログラム

与えられたテキストをNグラム(n-gram)で分割するJavaプログラムです。 Javaの標準ライブラリのjava.util.ArrayList、java.util.Listを使っています。 public static List<String> splitByNGram(String src, int n) { List<String> chunks = new ArrayList<>(); for(int start = 0, len = src.length(); start < len; start++) { int end = start + n; chunks.add(src.substring(start, end < len ? end : len)); } return chunks; }

Javaで平仮名をカタカナに変換するプログラム

Javaで平仮名をカタカナに変換するプログラムです。 public static String conbertHiragana2Katakana(String str) { int delta = 'ア' - 'あ'; StringBuilder buf = new StringBuilder(str.length()); for (int i = 0; i < str.length(); i++) { char code = str.charAt(i); Character.UnicodeBlock block = Character.UnicodeBlock.of(code); if (block != null && block.equals(Character.UnicodeBlock.HIRAGANA)) { buf.append((char)(code + delta)); } else { buf.append(code); } } return buf.toString(); }

Java 3Dの開発環境の構築 (2020年3月版)

Java 3D 大昔に作ったJava3Dのアプリケーションを復活させようと悪戦苦闘しているのですが、 最近(といっても2012年)にJava3DはOpenGLベースに移行して、細々と開発が続いていることがわかりました。 https://gouessej.wordpress.com/2012/08/01/java-3d-est-de-retour-java-3d-is-back/ https://jogamp.org/wiki/index.php/Java3D_FAQ (参考) いまだに残っているoracleのページのJava 3Dのバージョンは1.5.1です。 筆者はWindows 10環境ではインストール試していません。 https://www.oracle.com/technetwork/java/javase/tech/index-jsp-138252.html Java 3Dの開発環境の構築 https://jogamp.org/deployment/java3d/  のダウンロードページからjarなどを落としてもよかったのですが、mavenでプロジェクト管理しているので、多少古いバージョンの1.6.0.1をpom.xmlに追記して対応しました。 https://mvnrepository.com/artifact/com.massisframework.j3d/java3d-core https://mvnrepository.com/artifact/com.massisframework.j3d/vecmath <!-- https://mvnrepository.com/artifact/com.massisframework.j3d/vecmath --> <dependency> <groupid>com.massisframework.j3d</groupid> <artifactid>vecmath</artifactid> <version>1.6.0.1</version> </dependency> <!-- https://mvnrepository.c...

Amazon Product Advertising API 5.0のJavaのサンプルコード

Amazon Product Advertising APIがjsonベースの5.0に移行することが発表されました。 Amazonが提供しているSDKを利用していない場合は、APIのリクエストのインターフェースがXMLからJSONに変わるので、コードの書き換えは結構面倒です。 Amazonの公式ページ でもSDKを使用しないバージョンのサンプルコードが公開されていますが、ApacheのHttpComponentsのライブラリとjsonのライブラリが依存関係に含まれていたので、とにかくAPIを動かしてみたい人向けに 標準のJDKだけで動作するサンプルコードを書きました。 (ただし実運用ではJacksonやGSONなど、何らかのjsonライブラリは必須です。) package com.dukesoftware.amazon; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; // Java8で動くように、あえてvarなどのJava8では使えないJava機能は未使用 // スクラッチパッドを使うと便利 // https://webservices.amazon.co.jp/paapi5/scratchpad/ public class AmazonProductAdvertisingApiV5 { public static void main(String[] args) { // request生成部分はJacksonやGSONなどのライブラリを使用するのが現実的 String jsonRequest = "{" ...

Java 8の機能利用に伴うSpring 4へのバージョンアップ

下記の順序で環境を更新していったときに、問題が起こったのでメモしておきます。 Spring 3 + Java 7: もともとの環境。 Spring 3 + Java 8 (Java 8のラムダ機能などのJava 8からの新機能は未使用): 問題なく動作。 Spring 3 + Java 8 (Java 8のラムダ機能などのJava 8からの新機能を使用): 起動時に下記のExceptionが発生 org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: URL ...(途中省略)... java.lang.ArrayIndexOutOfBoundsException: xxx Googleで調べたところJava 8から導入された新機能を使う場合は、Spring 4に更新しないといけないようです。 Mavenとかは、使っていなかったので、Spring Frameworkから提供されているspring-xxx系のjarすべてをバージョン3.X系からバージョン4.X系のものに手動で置き換えました。 (Spring Frameworkはバージョン5.X系ももう出ているのですね。既に置いていかれているorz...) 無事にアプリケーションが起動するようになりました! ただ普通は、こんな乱暴にjarを入れ替えることは難しいので、アップデートはもっと慎重にやるべきでしょうね。

Google App Engineで外部のURLにアクセス

Google App Engine(GAE)から外部のネットワークへ接続する際の注意 Google App Engine(GAE)の開発環境の移行の際にJava 7からJava 8へ移行しました。 その際、GAEから、java.net.URL.openConnectionを使って普通に外部ネットワークのAPIを呼び出そうとすると下記のエラーが発生するようになってしまいました。 java.net.UnknownHostException: ホスト名 いろいろ調べていくと、下記のページにたどり着きました。 https://cloud.google.com/appengine/docs/standard/java/issue-requests 上記の表を間単に日本語訳すると URLのフェッチ方法 Java 7 Java 8 UrlFetch API Calls com.google.appengine.urlfetch.*以下のクラスを使う。無料で使用できる部分あり。 com.google.appengine.urlfetch.*以下のクラスを使う。無料で使用できる部分あり。 Javaネイティブのjava.net.URL.openConnectionなどを使う方法 無料ユーザも制限なく利用可能。 無料ユーザは、利用不可。 java.net.UnknownHostException、java.net.SocketTimeoutException、java.io.IOException とかが投げられる。 まとめると、 GAEで外部ネットワークへアクセスする方法には「GAEが提供するUrlFetch API Calls」「Javaネイティブのjava.net.URL.openConnection」の2つ方法がある。 Java 7では、「GAEが提供するUrlFetch API Calls」「Javaネイティブのjava.net.URL.openConnection」は無料でどちらの方法も利用可能。 Java 8で無料で利用できるのは「GAEが提供するUrlFetch API Calls」のみ。 Java 8で「Javaネイティブのjava.net.URL.openConnectionの方法」は課金ユーザーのみ利...

Goolge App Engineの開発環境の更新 (Java)

Google Plugins for EclipseからCloud Tools for Eclipseの移行 長らくEclipse Luna (4.4) + Google Plugin for Eclipseで開発を続けてきたのですが、Google App Engineの開発ページを覗いたら下記のようなメッセージが出ていてびっくり。 The Google Plugin for Eclipse is deprecated and will be removed in January 2018. Migrate to Cloud Tools for Eclipse and/or the GWT Eclipse Plugin as soon as possible to avoid disruption. Google Plugin for Eclipseは、2018年の1月でサポート打ち切りで、Cloud Tools for Eclipseに移行しなさいとのこと。 せっかくなので最新のeclipseを使って下記の設定で開発環境を再構築することにしました。 移行方法 最新のJDK 8 を http://www.oracle.com/technetwork/java/javase/downloads/index.html からダウンロードしてインストール。JDKをダウンロード Java 9 も試そうかとも思ったのですが、2017年9月現在Google App Engine側はまだJava 8までしかサポートしていないので、 Eclipseを  http://www.eclipse.org/downloads/eclipse-packages/  からダウンロード。私は、Eclipse IDE for Java Developersをダウンロードしました。 EclipseでGoogle App Engineの開発を行うための設定を https://cloud.google.com/eclipse/docs/quickstart  を読んで実施。 Google Cloud SDKをダウンロード Google Cloud Tools for Eclipse をEclipse Marketplace.を通してインス...

Java: Identify Country From IP Address

Identify Country From IP Address Many people sometimes would like to identify country from IP address when you check access log or something. Most of the people google with keywords like "ip address country" or "whois ip" or something, and then use the internet service which they find. In this post, I will show you program for identifying country from IP address. I wrote the program in Java, but if you an average developer you can easily translate into the program language you prefer. Using File Provided by RIR IP address is allocated, registered and managed by regional internet registry ( RIR ). There are five organization based on covering region: African Network Information Centre (AfriNIC): Africa American Registry for Internet Numbers (ARIN): the United States, Canada, several parts of the Caribbean region, and Antarctica. Asia-Pacific Network Information Centre (APNIC): Asia, Australia, New Zealand, and neighboring countries Latin America and ...

Java: Coloned IPv6 Address To BigInteger

IPv6 Address to Long I have written code for converting coloned IPv6 IP address to BigInteger value in Java. I have already written similar code for IPv4 IP address (see this post ). The function is useful when you compare IP addresses based on numeric magnitude relationship. Java Code public static BigInteger colonIpV6_to_BigInteger(String colonedIP) { String[] addrArray = colonedIP.split(":", -1); BigInteger num = BigInteger.ZERO; BigInteger block = BigInteger.valueOf(65536); for (int i = 0; i < addrArray.length; i++) { if(!addrArray[i].equals("")) { int power = 8-i; BigInteger value = BigInteger.valueOf(Long.parseLong(addrArray[i], 16) % 65536L); value = value.multiply(block.pow(power)); num = num.add(value); } } return num; } Here is an example. // following code output "22170076769632982771575277020213308075606016"...

Java: Dotted IPv4 Address To BigInteger

IPv4 Address to Long I have written code for converting dotted IPv4 IP address to BigInteger value in Java. This code is inspired by PHP's ip2long function. The function is useful when you compare IP addresses based on numeric magnitude relationship. Java Code public static BigInteger dotIPv4_to_BigInteger(String dottedIP) { String[] addrArray = dottedIP.split("\\."); BigInteger num = BigInteger.ZERO; BigInteger block = BigInteger.valueOf(256); for (int i = 0; i < addrArray.length; i++) { int power = 3-i; BigInteger value = BigInteger.valueOf(Integer.parseInt(addrArray[i]) % 256); value = value.multiply(block.pow(power)); num = num.add(value); } return num; } Here is an example. // following code output "2071690107" System.out.println(dotIPv4_to_BigInteger("123.123.123.123"));