gradle クラスパスが長すぎて bootRun が動かない時、

build.gradle

task pathingJar(type Jar){
   dependsOn confogirations.runtime
   appendix = "pathing"
   doFirst {
      manifest {
         attributes "Class-Path": configurations.compile.files.collect {
            it.toURI().toURL().toString().replaceFirst("file:/", '/')
         }.join(" ")
      }
   }
}

bootRun {
   dependsOn pathingJar
   doFirst {
      classpath = files(sourceSets.main.output.files, pathingJar.archivePath)
   }
}


(参考)
https://stackoverflow.com/questions/5434482/how-can-i-create-a-pathing-jar-in-gradle

https://stackoverflow.com/questions/39756475/execution-of-gradle-bootrun-fails

https://qiita.com/loopsketch/items/eb7218d9bf60954abe30

任意のリポジトリのJARをGradle で実行するコンパイルで指定

Git-Hub に置いた maven リポジトリの場合を参考に、、

build.gradle

repositories {
    mavebCentral()
    maven { url 'https://github.com/yipuran/yipuran-core/mvn-repo'  }
}

dependencied {
    testCompile group: 'junit' , name: 'junit' , '4.12'
    compile 'org.yipuran.core:yipuran-core:4.8'
}

Maven ファイルのコピー

Maven で、ファイルコピーを実行するには、
Ant plugin で実行する。

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.5</version>
        <configuration>
            <target>
                <echo message="copy files"/>
                <copy file="target/daria.jar" tofile="dist/daria.jar"/>
            </target>
        </configuration>
    </plugin>
</plugins>

実行

 mvn antrun:run 

うんざりする東京五輪の影響。。。

東京五輪の影響で2020年の「山の日」が変わるだけではなかった!
「海の日」と「体育の日」も、2020年だけ変わるのか!!

2020年7月23日「海の日」
2020年7月24日「スポーツの日」← 名称も変わる!

しかたなく、10年以上前に作成した Java祝日計算をメンテナンスする。
天皇誕生日が変わるのはメンテナンスしなければならない想定内だけど、
もう、「うんざり!」の東京五輪、都民にとっても迷惑と感じてるのは自分だけではないはず。。。

osdn.net

10年以上経つこのプログラム、糞なプログラムだと思っている。。

Git-Hub に移すべきというのは、そう思うけど、最初の公開場所を移すのはかえって迷惑だろう。

=====
JavaScript 版も無事修正完了

Class の getPackageName() は、Java9 からであることに注意

ある程度の規模のプロジェクトまたは会社では、Java で開発といっても
未だに、Java 8 のままである。

だから以下のようなコードを書いても使うことができない。

自クラスと同じ場所(クラスパッケージ階層)に読込みたいリソースファイルを配置する設計の時、、

public static byte[] readBinary(String path) throws IOException {
   try{
      File file = Optional.ofNullable(
         ClassLoader.getSystemClassLoader()
         .getResource(Class.forName(Thread.currentThread()
         .getStackTrace()[2].getClassName())
         .getPackageName().replaceAll("\\.", "/") + "/" + path))
      .map(u->{
         try{
            return new File(u.toURI());
         }catch(URISyntaxException e){
            return null;
         }
      }).orElse(new File(path));
      try(InputStream in = new FileInputStream(file)){
         byte[] data = new byte[in.available()];
         in.read(data);
         in.close();
         return data;
      }
   }catch(ClassNotFoundException ex){
      throw new IOException(ex.getMessage(), ex);
   }
}

public static String readText(String path) throws IOException {
   try{
      File file = Optional.ofNullable(
         ClassLoader.getSystemClassLoader()
         .getResource(Class.forName(Thread.currentThread()
         .getStackTrace()[2].getClassName())
         .getPackageName().replaceAll("\\.", "/") + "/" + path))
      .map(u->{
            try{
               return new File(u.toURI());
            }catch(URISyntaxException e){
               return null;
            }
      }).orElse(new File(path));
      try(InputStream in = new FileInputStream(file);
         ByteArrayOutputStream out = new ByteArrayOutputStream()){
         in.transferTo(out);
         return out.toString();
      }
   }catch(ClassNotFoundException ex){
      throw new IOException(ex.getMessage(), ex);
   }
}

public static Reader getReader(String path) throws IOException {
   try{
      File file = Optional.ofNullable(
         ClassLoader.getSystemClassLoader()
         .getResource(Class.forName(Thread.currentThread()
         .getStackTrace()[2].getClassName())
         .getPackageName().replaceAll("\\.", "/") + "/" + path))
      .map(u->{
            try{
               return new File(u.toURI());
            }catch(URISyntaxException e){
               return null;
            }
      }).orElse(new File(path));
      return new FileReader(file);
   }catch(ClassNotFoundException ex){
      throw new IOException(ex.getMessage(), ex);
   }
}

public static Reader getReader(String path, Charset charset) throws IOException {
   try{
      File file = Optional.ofNullable(
         ClassLoader.getSystemClassLoader()
         .getResource(Class.forName(Thread.currentThread()
         .getStackTrace()[2].getClassName())
         .getPackageName().replaceAll("\\.", "/") + "/" + path))
      .map(u->{
            try{
               return new File(u.toURI());
            }catch(URISyntaxException e){
               return null;
            }
      }).orElse(new File(path));
      return new FileReader(file, charset);
   }catch(ClassNotFoundException ex){
      throw new IOException(ex.getMessage(), ex);
   }
}

これは、Java 8 では、java.lang.Class に、getPackageName() パッケージ名完全修飾名取得のメソッドが
存在しないので、上のコードを利用できない。

Java 9 から、getPackageName() が使えるので、Java 9 以降であれば上のコードは利用できる。

InteliJ 複数プロジェクトを1つのウィンドウで開く

1つのプロジェクトを1つの InteliJ ウィンドウで作業するのが基本みたいで、
Eclipse や、STS に慣れしたんでた者には、さらに怒り心頭。。。

InteliJ 複数プロジェクトを1つのウィンドウで開くようにするには、

・作業開始するのに開くプロジェクトを予め決めておく。
・作業開始プロジェクトを開く。
「プロジェクトの構造」を開く
・モジュールー>「モジュールのインポート」を実行
f:id:posturan:20191208133041j:plain
 作業として同時に開きたいプロジェクトを次に選択する。
・インポートの方法に注意が必要で、、以下のように、 Gradleプロジェクトなら自動インポートにして
 読込み対象の参照構造を維持させる。
f:id:posturan:20191208133103j:plain

プロジェクトフォルダの .idea フォルダ内に、{プロジェクト名}.iml というモジュール設定ファイルが生成される。

予め決めたプロジェクトを開くたびに、モジュール設定されたプロジェクトを1つのウィンドウで開いてくれる。

月末日までの日付ストリーム

任意の日付に対する月末日までの日付ストリームの生成は、
以下、2通り考えられる。

Stream.iterate で、+1 days する方法

LocalDate d = LocalDate.now();
Stream<LocalDate> s = Stream.iterate(d, e->e.plusDays(1))
.limit(d.lengthOfMonth() - d.getDayOfMonth() + 1);

IntStream で、任意日(day) ~末日で、mapToObj で生成する方法

LocalDate d = LocalDate.now();
Stream<LocalDate> s = IntStream.rangeClosed(d.getDayOfMonth(), d.lengthOfMonth())
.mapToObj(i->LocalDate.of(d.getYear(), d.getMonth(), i));

どちらが良いのか?

どんなに頑張っても31個より大きいストリームではないので、どっちでも良いような気もする。