Java 7環境でのMavenのPluginがダウンロード失敗する
Java 7環境のMavenでダウンロードが行われない
環境を設定してもMavenの命令のダウンロード処理が失敗する事がある。
環境
現象
命令に対し、以下のように「Received fatal alert: protocol_version」になりダウンロードが失敗する。
C:\work\test>mvn archetype:generate [INFO] Scanning for projects... Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-archetype-plugin/maven-metadata.xml [WARNING] Could not transfer metadata org.apache.maven.plugins:maven-archetype-plugin/maven-metadata.xml from/to central (https://repo.maven.apache.org/maven2): Received fatal alert: protocol_version
原因
参考サイトにあるようにレポジトリへの接続には「TLS」というプロトコルを使うらしく、2018/06/18 からはTLSv1.0, 1.1はサポート外になったらしい
解決
Java7はデフォルトでTLSv1.0で通信するらしい、幸いにJAVA7はv1.2もサポートしているらしく、MavenでTSLを指定して実行することが可能だった
mvn -Dhttps.protocols=TLSv1.2 archetype:generate [INFO] Scanning for projects... Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-archetype-plugin/maven-metadata.xml Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-archetype-plugin/maven-metadata.xml (918 B at 0.4 KB/sec) Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-archetype-plugin/3.1.2/maven-archetype-plugin-3.1.2.pom Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-archetype-plugin/3.1.2/maven-archetype-plugin-3.1.2.pom (11 KB at 18.1 KB/sec) ...省略
自動化
少し探しづらいが、以下のファイルから一番長い行から、最後に「-Dhttps.protocols=TLSv1.2」をつけとけば常に適用される。 C:\apache-maven-3.3.9\bin\mvn.cmd
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %CLASSWORLDS_JAR% "-Dclassworlds.conf=%M2_HOME%\bin\m2.conf" "-Dmaven.home=%M2_HOME%" "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %CLASSWORLDS_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
以下に修正
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %CLASSWORLDS_JAR% "-Dclassworlds.conf=%M2_HOME%\bin\m2.conf" "-Dmaven.home=%M2_HOME%" "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %CLASSWORLDS_LAUNCHER% %MAVEN_CMD_LINE_ARGS%-Dhttps.protocols=TLSv1.2
参考
このサイトがすごく役に立った。
Java7 環境で maven が失敗する (Received fatal alert: protocol_version) - Qiita
Ubuntu 18にJava開発環境構築
今回は仕事でJavaのソースを渡されていて、開発環境を構築してみることになったんで、手順をメモしてみる
JreとJDKのインストール
Javaの開発なのでまずはJRE(Java Rutime Environment)とJDK(Java Development Kit)をインストールする。
※ 参考までにJreとJdkの種類 - Oracle Jre/Jdk : 基本Oracleが提供する有料Javaの指す(月額3千円ぐらい) - Open Jre/Jdk : オープンソースJAVA(無料) 基本はOpenJre/Jdkを使う感じかな…
ローカルの最新Jreをインストールする場合、
$ sudo apt install default-jre $ sudo apt install openjdk-8-jre $ sudo apt install openjdk-8-jre-headless $ sudo apt install openjdk-11-jre $ sudo apt install openjdk-11-jre-headless
※GUIが不要な場合はheadless版にする
続けてJDKのインストール、バージョンを指定してインストールする。
$ sudo apt install default-jdk $ sudo apt install openjdk-8-jdk $ sudo apt install openjdk-8-jdk-headless $ sudo apt install openjdk-11-jre $ sudo apt install openjdk-11-jre-headless
※GUIが不要な場合はheadless版にする
インストールされたJavaのバージョンを確認
$ java -version
aptの中からインストール可能なバージョンを探すコマンド
$ sudo apt search openjdk-\(\.\)\+-jdk$ Sorting... Done Full Text Search... Done openjdk-11-jdk/bionic-updates,bionic-security 11.0.4+11-1ubuntu2~18.04.3 amd64 OpenJDK Development Kit (JDK) openjdk-8-jdk/bionic-updates,bionic-security 8u222-b10-1ubuntu1~18.04.1 amd64 OpenJDK Development Kit (JDK)
結果として、openjdk-11-jdk,openjdk-8-jdkが検索されている。
Javaのバージョンを切り替える場合
「update-alternatives --config java」命令で使用するJavaのJDKバージョンを切替可能
$ sudo update-alternatives --config java There are 2 choices for the alternative java (providing /usr/bin/java). Selection Path Priority Status ------------------------------------------------------------ * 0 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 auto mode 1 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 manual mode 2 /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java 1081 manual mode Press <enter> to keep the current choice[*], or type selection number:
JAVA_HOME設定
$ export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 $ export PATH=${JAVA_HOME}/bin:${PATH}
自動化
.profileに設定を追加
export JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64" export PATH=${JAVA_HOME}/bin:${PATH}
Mavenのインストール
今回のソースはMavenでビルド管理しているみたいなので、Mavenもインストールします。
特定バージョンをダウンロードしてインストール
- Maven 3.3.9をダウンロード ソースでは3.3.9が使われていたので、最新ではなく、古いバージョンんをダウンロードします。
$ cd /usr/local/lib/ $ sudo wget https://archive.apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz $ sudo tar -zxvf apache-maven-3.3.9-bin.tar.gz $ sudo rm apache-maven-3.3.9-bin.tar.gz
- 環境設定
$ export M2_HOME=/usr/local/lib/apache-maven-3.3.9 $ export PATH=${M2_HOME}/bin:${PATH}
- 自動化
.profileに設定を追加
$ export M2_HOME="/usr/local/lib/apache-maven-3.3.9" $ export PATH=${M2_HOME}/bin:${PATH}
aptを利用したインストール
- Mavenを検索
$ sudo apt policy maven maven: Installed: (none) Candidate: 3.6.0-1~18.04.1 Version table: 3.6.0-1~18.04.1 500 500 http://us.archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages 500 http://us.archive.ubuntu.com/ubuntu bionic-updates/universe i386 Packages 500 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages 500 http://security.ubuntu.com/ubuntu bionic-security/universe i386 Packages 3.5.2-2 500 500 http://us.archive.ubuntu.com/ubuntu bionic/universe amd64 Packages 500 http://us.archive.ubuntu.com/ubuntu bionic/universe i386 Packages
- すでにある場合は削除する
$ sudo apt remove maven
- Mavenの最新版をインストール
$ sudo apt install maven
- インストールされた場所
$ ls -lsa/usr/share/maven $ ls -lsa/etc/maven
Mavenのバージョンを確認
$ mvn -v
Maven archetypeからプロジェクトを作成する
sourceフォルダーの直下に新しいプロジェクトを作成する場合
$ cd soruce $ mvn archetype:generate
最初に必要なプロジェクトテンプレートをダウンロードする。
その後からはInteractiveに設定を進めればOK
- 最終的に以下のフォルダー構成が生成される
source {artifactId} src main java {packageName} test ... pom.xml
{}の部分はプロジェクト生成時に入れた値
Maven コマンド
作成したプロジェクトルートから実行する
- mvn compile : ソースをコンパイルする
- mvn test-compile : テストコードをコンパイルする
- mvn test : テストを実施
- mvn clean : ソース以外のフォルダをクリアする
- mvn package : コンパイル、テスト後、Jarファイルまで生成
- mvn exec:java : pom.xmlにexec-maven-pluginを追加することで実行可能になる
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.5.0</version> <configuration> <mainClass>{プロジェクトのスタートクラス}</mainClass> </configuration> </plugin>
Eclipse インストール
$ wget https://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/mars/2/eclipse-java-mars-2-linux-gtk-x86_64.tar.gz
中の実行ファイルで起動できたので、とりあえずはここまで
CsvHelperで出力にダブルクォーテーションをつける
概要
CsvHelperでcsv出力でダブルクォーテーションを設定しようとして、かなり苦労したのでメモっておく
検索してみると「CsvWriter.Configuration.QuoteAllFields」をTrueにするSampleばかり出てきたけど、CsvHelper Ver12にはこのプロパティは存在しなかった。
プロパティで検索してみたら「Configuration.ShouldQuote」を使えと作者からの回答が見つかったため、解決した。
Configuration.ShouldQuote 使ってダブルクォーテーションを出力する
using (StreamWriter sw = new StreamWriter(File.Create(_outFilePath), utf8_Bom)) { using (var writer = new CsvHelper.CsvWriter(sw)) { //writer.Configuration.QuoteAllFields = true; writer.Configuration.ShouldQuote = (field, context) => true; writer.WriteRecords<GeocodingOutput>(output); } }
CustomConverterを使ってみる
ShouldQuoteでは全カラムに適用されるため、任意の項目にだけ適用する場合は、TypeConverterでMapしないと行けないらしい。
とりあえず、サンプルになりそうな部分だけメモ
ClassMapで各出力項目毎にConverterを指定して、出力内容をカスタムできる
public class CsvOutput { public string a { get; set; } public string b { get; set; } } // ClassMap public class CsvOutputMap : CsvHelper.Configuration.ClassMap<CsvOutput> { public CsvOutputMap() { Map( x => x.a).TypeConverter(new CsvDoubleQuoteConverter); Map( x => x.b).TypeConverter(new CsvNonDoubleQuoteConverter); } } // Converter public class CsvDoubleQuoteConverter : CsvHelper.TypeConversion.StringConverter { public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData) { row.Configuration.ShouldQuote = (field, context) => true; string ret = base.ConvertToString(value, row, memberMapData); row.Configuration.ShouldQuote = (field, context) => false; return ret; } } public class CsvNonDoubleQuoteConverter : CsvHelper.TypeConversion.StringConverter { public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData) { string ret = base.ConvertToString(value, row, memberMapData); return ret; } } using (StreamWriter sw = new StreamWriter(File.Create(_outFilePath), utf8_Bom)) { using (var writer = new CsvHelper.CsvWriter(sw)) { writer.Configuration.RegisterClassMap(new CsvOutputMap()); writer.WriteRecords<GeocodingOutput>(output); } }
参考
https://github.com/JoshClose/CsvHelper/issues/1180 https://teratail.com/questions/97817
AppSettingから設定値を取得する
.Netの環境変数ファイル(*.config)から値を取得する方法について
以前のやり方が使えなくなったみたいなので、新しい方法をメモる
今はうまくいかない以下の方法
Configuration.ConfigurationManager.AppSettings("KEY")
.config
<configuration> <appSettings> <add key="KEY_ID1" value="abcd" /> <add key="KEY_ID2" value="9999" /> </appSettings> </configuration>
System.Configuration.AppSettingsReader
System.Configuration.AppSettingsReader setting = new System.Configuration.AppSettingsReader(); var keyId1= setting.GetValue(KEY_CLIENT_ID, Type.GetType("System.String"));
うまく取得できたが、キーがなかったりすると、そのままエラーになるので、エラー処理が必要
.Net Core
.Net Coreで利用する場合、NuGetから「System.Configuration.ConfigurationManager」のインストールを行い、以下のソースを参照
var result = Configuration.ConfigurationManager.OpenExeConfiguration(Environment.GetCommandLineArgs()(0)); if(result.HasFile){ string settingValue = Configuration.ConfigurationManager.AppSettings("key"); }
※例はコンソールアプリケーションの場合
Google Map Apiを利用してみる
諸事情により、Wep APIを利用するコーディングを試すことになったので、メモる
Google Cloud Platformの登録
Google Map Apiを利用するためにはGoogle Cloud Platformへの登録が必要、クレジットカード必須。 https://cloud.google.com 登録を完了すると、デフォルトのプロジェクトが生成される。
認証キーを生成する。
サイドメニューから「APIとサービス→認証情報」へ
認証情報を作成から、APIキーを選択し、認証キーを作成する。
APIキーの制限設定画面からはアプリケーション制限からHTTPやIPアドレスでの制限をかけれるらしい、とりあえず、テストだけにはなしで問題なし
Google Map Apiを有効にする。
サイドメニューから「APIとサービス→ライブラリー」へ
「Maps JavaScript API」を探して、「有効」にする。
管理画面へ移動
これで、Javascript用Map Apiが利用可能になった。
用件によって「Geocoding API」や「Places API」の有効化が必要になる。
Map APIを利用して座標の地図を表示してみる。
HTML
googleのapiが読まれたタイミングでinitMapが実行され、表示される
<div id="map" style="height:500px;width:500px;"></div> <script> function initMap() { var MyLatLng = new google.maps.LatLng(34.7088812,135.4881584); var Options = { zoom: 15, //地図の縮尺値 center: MyLatLng, //地図の中心座標 mapTypeId: 'roadmap' //地図の種類 }; var map = new google.maps.Map(document.getElementById('map'), Options); } </script> <script src="http://maps.google.com/maps/api/js?key={API_KEY}&language=ja&callback=initMap"></script>
Geocoding APIを利用して、住所から座標を取得する方法
もともとこれをやって見るための準備だったので、これを有効にする。 これにより、Web APIからのResponseを取得する様にしてみる。
.NETのコンソールプロジェクトを作成し、必要なパッケージを追加する。
先ずはパッケージの追加 + Microsoft.AspNet.WebApi.Client + Newtonsoft.Json
レスポンス用クラスを宣言(Google GeocodeからのレスポンスのJson型)
public class MyResponse { public List<AddressComponent> results { get; set; } public string status { get; set; } } public class AddressComponent { public List<address_components> address_components { get; set; } public string formatted_address { get; set; } public Geometry geometry { get; set; } public string place_id { get; set; } public List<string> types { get; set; } } public class Geometry { public Bounds bounds { get; set; } public Point location { get; set; } public string location_type { get; set; } public Bounds viewport { get; set; } } public class Bounds { public Point northeast { get; set; } public Point southwest { get; set; } } public class Point { public decimal lat { get; set; } public decimal lng { get; set; } } public class address_components { public string long_name { get; set; } public string short_name { get; set; } public List<string> types { get; set; } }
実行プログラム
class Program { static HttpClient _client = new HttpClient(); static List<String> _list = new List<string>(); static Dictionary<String,string> _result = new Dictionary<String, string>(); static void Main(string[] args) { _list.Add("東京タワー"); _list.Add("543-0001"); RunAsync().GetAwaiter().GetResult(); foreach (var item in _result) { // JsonからNewtonsoft.Jsonを利用してDeserializeしている。下のresult3と結果は同じ var conv = Newtonsoft.Json.JsonConvert.DeserializeObject<MyResponse>(item.Value); Console.WriteLine($"{item.Key}=X:{conv.results[0].geometry.location.lat},Y:{conv.results[0].geometry.location.lng}"); } Console.ReadLine(); } static async Task<String> GetResultAsync(string address) { //Json形式で返す様にしている。 HttpResponseMessage response = await _client.GetAsync(new Uri($"https://maps.googleapis.com/maps/api/geocode/json?address={address}&key={API_KEY}")); var result = response.EnsureSuccessStatusCode(); var result2 = await response.Content.ReadAsStringAsync(); //Jsonの文字列を取得する。 var result3 = await response.Content.ReadAsAsync<MyResponse>(); //Deserializeした結果を受け取る return result2; } static async Task RunAsync() { // BaseAddressは指定しているが、今回は毎回Full Urlを送っているため、何でも良い(はず) _client.BaseAddress = new Uri("https://maps.googleapis.com/maps/api/geocode/"); _client.DefaultRequestHeaders.Accept.Clear(); _client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json")); try { foreach (var item in _list) { var result = await GetResultAsync(item); _result.Add(item, result); } } catch (Exception e) { Console.WriteLine(e.Message); } } }
テスト用コードがいっぱい残っているが、とりあえず、ここまで
トリガー作成メモ
TRIGGER作成
基本文法
CREATE TRIGGER [dbo].[TR_TABLE_NAME] ON [dbo].[TABLE_NAME] AFTER INSERT,DELETE,UPDATE AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; -- Insert statements for trigger here END GO
トリガーでのINSERT,UPDATE,DELETEの判定
少し面倒だが、こんな形で判定が可能だった
-- Insert IF EXISTS (SELECT * FROM inserted) AND NOT EXISTS(SELECT * FROM deleted) BEGIN --inserted action END -- Update IF EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted) BEGIN --updated action END -- Delete IF EXISTS (SELECT * FROM deleted) AND NOT EXISTS(SELECT * FROM inserted) BEGIN --deleted action END
トリガーで更新値を変更する
自分自身へのUPDATEを発行する
UPDATE [dbo].[TABLE_NAME] SET [CLM_NAME] = 'ABC' FROM [dbo].[TABLE_NAME] T INNER JOIN inserted I ON I.KEY = T.KEY
Styleの適用方法色々メモ
自分の以下の対象ターゲットのプロパティを固定する
青い四角のスタイルを設定する。
<Grid> <Grid.Resources> <Style TargetType="Rectangle"> <Setter Property="Fill" Value="Blue"/> </Style> </Grid.Resources> <Rectangle Height="10" Width="10" /> </Grid>
キー名をつけてそれぞれのスタイルを指定する。
<Grid> <Grid.Resources> <Style x:Key="sty1" TargetType="Rectangle"> <Setter Property="Fill" Value="Blue"/> </Style> <Style x:Key="sty2" TargetType="Rectangle"> <Setter Property="Fill" Value="Red"/> </Style> </Grid.Resources> <StackPanel> <Rectangle Height="10" Width="10" Style="{StaticResource sty1}"/> <Rectangle Height="10" Width="10" Style="{StaticResource sty2}"/> </StackPanel> </Grid>
Style.Triggerでのスタイル適用
プロパティの設定値によって、スタイルの変更を指定する。
<Grid.Resources> <Style TargetType="TextBox"> <Style.Triggers> <Trigger Property="IsEnabled" Value="True"> <Setter Property="Background" Value="White"/> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Background" Value="Silver"/> </Trigger> </Style.Triggers> </Style> </Grid.Resources>