20210912のJavaに関する記事は7件です。

【AtCoder】JavaとCOBOLで解き比べ。

こんばんは。 AtcoderをCOBOLで解く人は少ないようです。 自分はAtCoderの成績は全く振るいませんが、一応COBOL歴10年ちょいですので、解いてみました。久々にCOBOLを書くと、文法(IF文の構成)やお作法(8カラム目からじゃないと記述できない)を結構忘れており苦戦しました。プログラムを読むと書くとではやはり違うと実感しました。 でも自分の母国語だと思っているCOBOLで解くのは楽しかったです。 Atcoder ABC-215のA問題を使用しました。 ※少ないですが、COBOLで解いている方も数人はいらっしゃるようです。  ただ、A問題は数人ですが、B,Cになると0人のようです。本格的な数学問題だと難しいのでしょうか。 COBOL PROGRAM-ID. Main. DATA DIVISION. WORKING-STORAGE SECTION. 01 ESU PIC X(15). PROCEDURE DIVISION. ACCEPT ESU. IF ESU = 'Hello,World!' THEN DISPLAY 'AC' ELSE DISPLAY 'WA' END-IF. STOP RUN. Java import java.util.Scanner; import java.util.Arrays; import java.util.ArrayList; public class Main{ public static void main(String args[]){ Scanner sc = new Scanner(System.in); String s = sc.next(); if(s.equals("Hello,World!")){ System.out.println("AC"); }else{ System.out.println("WA"); } } } COBOLの方が速い? COBOLは、8ms、Javaですと100msでした。 数回試しましたがこの傾向にあります。 やはり事務処理言語としてCOBOLの高速性は事実なんですかね。 C問題は速度を試されることが多いので、COBOLで解いたらできたりするかな・・。 優れているなら、今後も技術として残っていってもいいのにね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【俺的】COBOL→Java言語移行ガイド(全体構造編)

検証環境 COBOL Java cobc (GnuCOBOL) 3.1.2.0 java 14.0.1 2020-04-14 はじめに 前回の記事では、「なぜマイグレーションが進んでいるのか」「マイグレーションのいいところと課題点」を見ていきました。今回はCOBOLとJavaで、「全体的な書き方でどう変わってくるのか」を書いていこうと思います。 閲覧してほしい方 これからCOBOLからオープン系へのマイグレーションに従事する方 COBOLとJavaの言語的違いを知っておきたい方 COBOL習熟者で、将来オープン言語を触らなければならないがわからない方 COBOL未経験でマイグレーションされる方や、これからCOBOLエンジニアからJavaエンジニアに移る方の駆け出し資料として参考になれば幸いです。 全体構造の比較 まずはCOBOLの全体構造、Javaの全体構造(main)を見てみます。 COBOL *--1---------2---------3---------4---------5---------6 IDENTIFICATION DIVISION. PROGRAM-ID. EXAMPLE. ENVIRONMENT DIVISION. DATA DIVISION. PROCEDURE DIVISION. MAIN SECTION. MAIN-S. * TODO CODE APPLICATION LOGIC HERE MAIN-E. STOP RUN. Java(mainクラス) package com.qiita.zama_8722; public class Example { public static void main(String[] args) { // TODO code application logic here } } オープン系言語同士であれば似通ったところが多いと思いますが、COBOLとオープン系言語の場合、全体的な書き方が大きく変わってきます。 1.COBOLには4つのDIVISIONがある COBOLには DENTIFICATION DIVISION ENVIRONMENT DIVISION DATA DIVISION PROCEDURE DIVISION があり、それぞれのDIVISIONで何を書かなくてはいけないかが決められています。 詳細はこちらを御覧ください。 例えば、データ項目(変数)はDATA DIVISIONに(その中でもこのモジュールのみで使用すものはWORKING-STORAGE SECTION、呼び出し元モジュールの項目を引き継ぐ場合はLINKAGE SECTIONに)まとめて書く必要がありました。 また、COBOLは古い言語で、入出力がテープの時代でしたので、メインプログラムではENVIRONMENT DIVISIONに、「JCLで定義されたテープ1は入力なのか出力なのか」「そのテープのレイアウトはどうなっているのか」を定義してあげる必要がありました。 しかし、Javaになると、変数の定義は随所で可能になります。メソッドの中で定義すればそのメソッド内でのみ使用可能になり、メソッドの外に書けばそのクラス内で使用可能(クラス変数)になったりします(アクセス修飾子によればクラス外からも使用可能)。また、オープン系言語はテープを使いませんので、ENVIRONMENT DIVISONで定義している内容全体的に不要になります。 2.COBOLはモジュール、Javaはメソッドを呼ぶ 外部のライブラリや基盤機能を使用するにあたって、COBOLとJavaでは呼び出しや値の受け渡しの仕組みが違います。 下位の機能を呼び出したいとき、COBOLはCALL文を使用して下位モジュール自体を呼び出し、呼び出されたモジュールはメインから一通り実行します(つまり、下位モジュールのこのSECTIONだけ実行というのはありません)。 COBOLで外部機能(モジュール)を呼び出す例 メインモジュール *--1---------2---------3---------4---------5---------6 IDENTIFICATION DIVISION. PROGRAM-ID. MAINMODULE. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 MSG PIC X(5). PROCEDURE DIVISION. MAIN SECTION. MAIN-S. PERFORM SUBMODULE. DISPLAY MSG. MAIN-E. STOP RUN. ***************************************************** SUBMODULE SECTION. SUB-S. CALL 'SUBMODULE' USING MSG. SUB-E. EXIT. サブモジュール *--1---------2---------3---------4---------5---------6 IDENTIFICATION DIVISION. PROGRAM-ID. SUBMODULE. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 HELLO PIC X(5) VALUE 'HELLO'. LINKAGE SECTION. 01 MSG PIC X(5). PROCEDURE DIVISION USING MSG. MAIN SECTION. MAIN-S. MOVE HELLO TO MSG. MAIN-E. GOBACK. 一方Javaは、呼び出したいクラスをインスタンス化した上で、呼び出したいメソッドを指定し、呼び出し先クラスは呼び出されたメソッドのみを実行します。ただし、クラス変数等の初期化を行うコンストラクタ(ここではpublic Library())は、インスタンス化時に自動で実行されます。 Javaで外部クラスを呼び出す例 呼び出し元Javaクラス package com.qiita.zama_8722; public class Example { public static void main(String[] args) { Library lib = new Library(); String msg; msg = lib.getHello(); System.out.println(msg); } } 呼び出し先Javaクラス package com.qiita.zama_8722; public class Library { private String msg; public Library() { // 初期値は"Hello" msg = "Hello"; } public String getMsg() { return this.msg; } public void setMsg(String msg) { this.msg = msg; } } COBOL、Javaの処理の流れを図にすると、以下のようになります。 端的にまとめると、COBOLは手続型言語、Javaはオブジェクト指向言語です。ちなみに、それぞれの意味は、 手続き型言語 【procedural language】 手続き型言語とは、プログラミング言語の分類の一つで、コンピュータが実行すべき命令や手続きを順に記述していくことでプログラムを構成する言語。 手続き型言語(procedural language)とは - IT用語辞典 e-Words オブジェクト指向言語 【object-oriented language】 オブジェクト指向言語とは、プログラミング言語のうち、互いに関連するデータの集合とそれらに対する手続き群をひとまとめにした「オブジェクト」(object)をプログラムの基本的な構成単位として扱うことができるもの。 オブジェクト指向言語(object-oriented language)とは - IT用語辞典 e-Words です。 3.COBOLとJavaの値の受け渡し方の違い 上記の図でも少し説明を入れていますが、COBOLはモジュール間で値を受け渡しするとき、呼び出し元はCALL文の後ろにUSING句を記載し、そこに呼び出し先モジュールに渡したい項目(もしくはCOPYレイアウト)を記載します。呼び出し先では、LINKAGE SECTIONとPROCEDURE DIVISIONのUSING句に受け取る項目(もしくはCOPYレイアウト)を記載します。実行結果の返却も渡されたCOPYレイアウトに入れることによって、呼び出し元モジュールでUSING句に記載したCOPYレイアウトに結果が入ります。 Javaの場合、「値が返ってくるメソッド」「値が返ってこないメソッド」の2つがあります。 「値が返ってくるメソッド」は、メソッド名の前に「返す値の型」を記載し、返す値はreturn文に記載します(先程の呼び出し先JavaクラスのgetMsg()がまさにそうです)。 一方、「値が返ってこないメソッド」は、メソッド名の前にvoidを記載します。voidと記載すれば、そのメソッドにreturn文は書きませんので、返却値がありません。 まとめ ここまで、COBOLとJavaで、全体的な構造や外部機能の呼び出し方がどう違うのかをざっくり見てきました。 次回は、項目の定義方法や基本文法の書き方の違いを見ていこうと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Application Insights2.xでSpring Bootを可視化する

Application Insights2.xとSpring Boot APMとしてApplication Insights2.xを使い、Spring Bootの稼働状態を可視化する方法について解説します。 Application Insightは3.xがすでに出ていますが、正直2.xの方が使い勝手がいいです… エージェントと設定ファイルの用意 以下の2つのファイルを準備します。 applicationinsights-agent-2.6.3.jar AI-Agent.xml applicationinsights-agent-2.6.3.jarは以下からダウンロードします。 AI-Agent.xml <?xml version="1.0" encoding="utf-8"?> <ApplicationInsightsAgent> <Instrumentation> <BuiltIn enabled="true"> <!-- capture logging via Log4j 1.2, Log4j2, and Logback, default is true --> <Logging enabled="true" /> <!-- capture outgoing HTTP calls performed through Apache HttpClient, OkHttp, and java.net.HttpURLConnection, default is true --> <HTTP enabled="true" /> <!-- capture JDBC queries, default is true --> <JDBC enabled="true" /> <!-- capture Redis calls, default is true --> <Jedis enabled="true" /> <!-- capture query plans for JDBC queries that exceed this value (MySQL, PostgreSQL), default is 10000 milliseconds --> <MaxStatementQueryLimitInMS>1000</MaxStatementQueryLimitInMS> </BuiltIn> </Instrumentation> </ApplicationInsightsAgent> コンテナで動かす場合はDockerfileに以下のように記述し、エージェントと設定ファイルをJVMに認識させます。AI-Agent.xmlはapplicationinsights-agent-2.6.3.jarと同じところに配置し、かつその場所がWORKDIRである必要があります。 Dockerfileの抜粋 COPY ./build/resources/main/applicationinsights-agent-2.6.3.jar /usr/local/applicationinsights-agent-2.6.3.jar COPY ./build/resources/main/AI-Agent.xml /usr/local/AI-Agent.xml WORKDIR /usr/local CMD java -Xmx2g -javaagent:/usr/local/applicationinsights-agent-2.6.3.jar -jar /usr/local/api-SNAPSHOT.jar 依存関係の設定 依存する以下のJARをbuild.gradleで認識させる必要があります。 バージョン/2021-09-07 時点 用途 必要性 1 com.microsoft.azure:applicationinsights-spring-boot-starter 2.6.3 Application Insightsについての設定をapplication.propertiesに集約することができる 必須 2 com.microsoft.azure:azure-spring-boot-metrics-starter 2.3.5 MicrometerのラッパーでJVM内部の主要なメトリクスを自動で吸い上げてくれる 必須 3 com.microsoft.azure:applicationinsights-logging-log4j2 2.6.3 ログをテレメトリーとして送信する。一連の流れとして可視化するという意味では良いがログの量が多いと負荷がかかる ログ量次第 build.gradle dependencies { implementation 'com.microsoft.azure:applicationinsights-spring-boot-starter:2.6.3' implementation 'com.microsoft.azure:azure-spring-boot-metrics-starter:2.3.5' implementation 'com.microsoft.azure:applicationinsights-logging-log4j2:2.6.3' com.microsoft.azure:azure-spring-boot-metrics-starterの導入でNoClassDefFoundError: javax/xml/bind/JAXBExceptionが発生した場合は依存関係に以下を追加します。 implementation 'javax.xml.bind:jaxb-api:2.3.0' 送信先のApplication Insightsの指定 送信先のApplication Insightsを指定する方法は複数ありますが、環境変数を指定する方法が一番可搬性があります。 APPINSIGHTS_INSTRUMENTATIONKEY=$instrumentationKey 例 APPINSIGHTS_INSTRUMENTATIONKEY=e286f9f0-bbf5-430b-9f2c-xxxxxxxxxxx データソース別にメトリクスを取得する あとで書きます…
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AvastによってSpring Bootのjarファイルが消滅する現象

事象 java(OpenJDK11)コマンドでSpring Boot(v2.5.4)のjarファイルを実行すると、一定時間の後にプロセスが停止してjarファイルが消滅する。 Spring Bootが正しく起動しなければ(例えばクラスパスが不足しているとか、メインメソッドでSpringApplicationを実行しないとか)、これは発生しない。 原因 avastのファイルシールド(メインシールド)が断りも無く削除していた。メインシールドを切るか、例外ディレクトリに作業ディレクトリを追加すると事象は発生しなくなった。 Spring Bootが正しく起動しないと発生しないのでSpring Boot側の問題かとも思ったが、もちろんそんなことは無かった。消す時に確認するモードにしているはずなんだが、勝手に消されてしまうようだ。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

(JAVA勉強用メモ)3. 演算子・判定構造

数値リテラルの型変換 大きな範囲の値を小さな変数に代入するときは、明示的なキャストが必要。 (数値リテラルはデフォルトで特定の型をもっており、整数はint型、小数はdouble型が使用される。) int i = 10; short a = (short)i; //『大』を『小』に代入 long l = 10L; int b = (int)l; //『大』を『小』に代入 double d = 10.0; float c = (float)d; //『大』を『小』に代入 long d = 10; //『小』を『大』に代入するのは問題ない ただし、byte型やshort型に整数リテラルを代入する場合、 その値が型の範囲に収まるのであればエラーは発生しない。 byte a = 127; //『大』を『小』に代入しているが、127はbyte型の範囲内なのでOK byte b = 128; // 128はbyte型の範囲外なのでNG(コンパイルエラー) byte c = (byte)128; // 型の範囲外でも、キャストしていればエラーにはならない int d = 10L; //←※NG(これができるのはbyteとshortのみ。intではできない) 同一性と同値性 同一性:同じインスタンスであること(参照先が同じであること)。==で比較する。 同値性:同じ値であること。equalsメソッドで比較する。 Sample.java public class Sample { private int num; public Sample(int num) { this.num = num; } public equals(Object obj) { if (obj == null) return false; // 比較対象がnullのときはfalseを返却 if (obj instanceof Sample) { // Sampleクラスのインスタンスであるかどうか Sample s = (Sample) obj; return s.num = this.num; // 【クラスごとに比較処理を実装】 } return false; // Sampleクラスのインスタンスでない場合はfalseを返却 } } Main.java class Main { public static void main(String[] args) { Sample s1 = new Sample(10); Sample s2 = new Sample(10); System.out.println(s1 == s2); // 同一性はFALSE System.out.println(s1.equals(s2)); // 同値性はTRUE } } ちなみに、Objectクラスに実装されているequalsメソッドは同一性を返却する。 Object.java public boolean equals(Object obj) { return (this == obj); } Stringクラスのコンスタントプール String a = "sample"; String b = "sample"; System.out.println(a == b); // TRUE 変数aとbに異なる参照を代入しているが、☝のコードはTRUEを返却する。 これは、String s = [文字列]の形で変数を宣言した際、同じ文字列が使われている場合には 同じ参照先が使用されるという仕組みになっているからである。 この仕組みをコンスタントプールという。 String a = "sample"; String b = new String("sample"); System.out.println(a == b); // FALSE:`new String()`で変数宣言するとコンスタントプールは使用されない System.out.println(a.intern() == b.intern()); // TRUE:intern()メソッドを使用すると、メモリ内にある文字列への参照を戻し、その結果は必ず同じになる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Spring Boot + Excel Upload + CSV出力

PostmanでエクセルをPOSTし、Spring側でCSV出力 末尾の参考サイトのソースをもとに、PostmanでExcelをPOSTし、受信側(spring boot)でCSVライブラリの「OrangeSignal CSV」を利用してCSV出力した。 CSVのヘッダに日本語の列名を指定するところで物凄くつまったので、サンプルソースを記載する。 @Service public class ExcelService { @Autowired TutorialRepository repository; public void save(MultipartFile file) { try { List<Tutorial> tutorials = ExcelHelper.excelToTutorials(file.getInputStream()); repository.saveAll(tutorials); // 区切り文字と囲み文字、エスケープ文字を指定して CSV 形式設定情報を構築 CsvConfig cfg = new CsvConfig(',', '"', '"'); List<TutorialCSVData> tutorialCSVList = tutorials.stream().map(TutorialCSVData::toCSVDataFromPOJO).collect(Collectors.toList()); File fileout = new File("Tutorial.csv"); Csv.save( tutorialCSVList, fileout, cfg, new CsvEntityListHandler<TutorialCSVData>(TutorialCSVData.class)); } catch (Exception e) { throw new RuntimeException("fail to store excel data: " + e.getMessage()); } } public ByteArrayInputStream load() { List<Tutorial> tutorials = repository.findAll(); ByteArrayInputStream in = ExcelHelper.tutorialsToExcel(tutorials); return in; } public List<Tutorial> getAllTutorials() { return repository.findAll(); } } 「OrangeSignal CSV」では、CSV出力にPOJOクラスが利用できる。 POJOクラスでは、@CsvEntity アノテーションと @CsvColumn アノテーションをつける。 参考元ソースには、データベースに格納する「Tutorial」Entityがあるが、 CSVに日本語項目を出力したかったので、別途「TutorialCSVData 」を作成し、TutorialからTutorialCSVDataに変換している。 OrangeSignal CSVサイトのユーザーガイドにある「ColumnNameMappingBeanListHandler」を使って、 項目列とPOJOオブジェクトフィールド(の変数名)を対応付けていたが、CSVの列が100以上の場合はしんどい。 100項目の定義したくないので、なんとかならないか調べたところ、@CsvEntityを使っている場合は、 「CsvEntityListHandler」を使えばよいということがわかった。 ここはユーザーガイドにも説明があるので、私の理解力がなかったようです。(ちょっと試してうまくいかなかったのであきらめてた) 将来、同じように困る人用にサンプルを載せておきます。 ちなみに公式のユーザーガイドにあるColumnNameMappingBeanListHandler#addColumnメソッドは誤記で、正しくはcolumnメソッドでした。詳細はJavadoc参照。 package com.bezkoder.spring.files.excel.model; import com.orangesignal.csv.annotation.CsvColumn; import com.orangesignal.csv.annotation.CsvEntity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor @CsvEntity public class TutorialCSVData { @CsvColumn(name = "番号") public String id; @CsvColumn(name = "タイトル") public String title; @CsvColumn(name = "詳細") public String description; @CsvColumn(name = "補足") public String published; public static TutorialCSVData toCSVDataFromPOJO(Tutorial tutorial) { return new TutorialCSVData( Long.toString(tutorial.getId()), tutorial.getTitle(), tutorial.getDescription(), String.valueOf(tutorial.isPublished())); } } CsvConfigクラスで””で囲ったり、改行コード(WIN, Mac, Linux)を指定できる。 CSV出力結果 Tutorial.csv "番号","タイトル","詳細","補足" "1","Spring Boot Tut#1","Tut#1 Description","false" "2","Spring Boot Tut#2","Tut#2 Description","true" "3","MySQL Database Tut#3","Tut#3 Description","true" "4","Hibernate Tut#4","Tut#4 Description","false" "5","Spring Cloud Tut#5","Tut#5 Description","true" "6","Microservice Tut#6","Tut#6 Description","false" "7","MongoDB Database Tut#7","Tut#7 Description","true" "8","Spring Data JPA Tut#8","Tut#8 Description","true" 補足情報 「OrangeSignal CSV」利用のためのpom.xmlの設定です。 pom.xml <dependency> <groupId>com.orangesignal</groupId> <artifactId>orangesignal-csv</artifactId> <version>2.2.1</version> </dependency> 公式のクイックスタートではバージョンが「2.2.2-SNAPSHOT」となってますが、 Intellij環境ではmavenのエラーになり、読み込まれませんでした。 参考: Spring Boot: Upload/Import Excel file data into MySQL Database https://www.bezkoder.com/spring-boot-upload-excel-file-database/ ソースを動かす場合、エクセルのシート名は ExcelHelperクラスのSHEETで「Tutorials」に定義されているので注意。(POSTするエクセルのシート名に変更) OrangeSignal CSV http://orangesignal.github.io/orangesignal-csv/index.html https://github.com/orangesignal/orangesignal-csv/issues/29 おわり。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

NDK at /Users/user.name/Library/Android/sdk/ndk/XX.X.XXXXX did not have a source.properties file エラーが発生する

やりたいこと Androidアプリをビルドしたい。 ./gradlew build エラー文 以下のエラーが発生。 ❯ ./gradlew build FAILURE: Build failed with an exception. * What went wrong: A problem occurred configuring project ':renderscript-toolkit'. > com.android.builder.errors.EvalIssueException: NDK at /Users/user.name/Library/Android/sdk/ndk/21.3.6528147 did not have a source.properties file * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. * Get more help at https://help.gradle.org BUILD FAILED in 1s 原因 対応するバージョンのNDKがインストールされていない。 解決策 NDKのインストール 以下から、エラーログに記載されていたバージョンのNDKをインストールする。 https://developer.android.com/studio/projects/install-ndk#specific-version gradle build の実行 ❯ ./gradlew build
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む