覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

MS-DOSコマンドでファイルパスからディレクトリのパスやファイル名を取得する

C:\app\SampleApp\Launcher.exe というパスがあった時に、
ファイルが存在するディレクトリのパス C:\app\SampleApp\ と ファイル名 Launcher.exe を抽出したい。という要件があった場合

これをWindowsのDOSコマンドで実現するために、


ディレクトリの抽出には以下を使用します。(以下は、 %1 のパラメータを対象としています)

%~dp1

ファイル名の抽出には以下を使用します。(以下は、 %1 のパラメータを対象としています)

%~nx1


上記のコマンドを実行するExtractPath.cmdというファイルを以下のように記述して

@echo off

echo [DirPath]:  %~dp1

echo [FileName]: %~nx1

パラメータにパスを与えて実行すると

ExtractPath.cmd C:\app\SampleApp\Launcher.exe


結果は以下のようになります。

C:\Samples\ExtractPath.cmd C:\app\SampleApp\Launcher.exe
[DirPath]:  C:\app\SampleApp\
[FileName]: Launcher.exe


無事に、DOSコマンドでもファイルパスからディレクトリのパスやファイル名の抽出が実現できました。

Visual Studio Code(vscode-go)のコード補完が効かなくなる

Golangのバージョンを1.9にアップデートしたら、Visual Studio Codeでのコード補完が全く効かなくなりました。
vscode-goプラグインで問題が起こっちゃってるようです。


オートコンプリートの候補としてPANICしか出てこない謎現象が発生します。


以下の手順で gocode をアップデートして、gocode close することで解消できます。

go get -u github.com/nsf/gocode
gocode close 


これでまともな候補が表示されるようになりました。よかったよかった。

PostgreSQL - テーブルとindexのサイズを確認する

PostgreSQLでテーブルのレコード数ではなく容量(サイズ)を知りたい場合があります。
その場合には以下のSQLを実行することで各テーブルと各indexのサイズを確認できます。

select
  objectname,
  to_char(pg_relation_size(objectname::regclass), '999,999,999,999') as bytes 
from (
  select 
   tablename as objectname 
  from pg_tables 
  where schemaname = 'public'

  UNION

  select 
   indexname as objectname 
  from pg_indexes
  where schemaname = 'public'
) as objectlist

order by bytes desc;


■実行結果サンプル

       objectname       |      bytes       
------------------------+------------------
 auditlog               |       99,589,824
 sampletbl1             |          294,912
 sampletbl1_col1_idx    |          172,032
 sampletbl1_seq_idx     |           73,728
 sampletbl1_pkey        |           65,536
 master1_pkey           |           16,384
 master2_pkey           |           16,384
 sampletbl2_seq_idx     |            8,192
 sampletbl2s_pkey       |            8,192
 master1                |            8,192
 master2                |            8,192
 sampletbl2             |                0


とても便利



関連エントリ

Class#newInstanceは非推奨になるようなので気を付けよう

Javaでリフレクションによるデフォルトコンストラクタ呼び出しでインスタンス生成する方法としてClass#newInstanceが挙げられると思います。

ただし、Class#newInstanceはJava9で非推奨(Deprecated)になるようです。(さらに以降のバージョンでAPI自体が削除になるんですかね・・・)

Class#newInstanceは、シグニチャ上に無いチェック例外がスローできてしまうため、それが問題で非推奨となったようです。
その辺の動きについて今回のエントリで確認してみます。


インスタンス化対象のクラス

今回は以下クラスのインスタンス化を行って動きを確認します。
このクラスは、デフォルトコンストラクタを実行するとFileNotFoundException(チェック例外)をスローするようになっています。

import java.io.FileNotFoundException;

public class SampleObject {

    public SampleObject() throws FileNotFoundException {
        throw new FileNotFoundException("target file not found.");
    }
}


Class#newInstanceでコード上に無い例外をスローしてみる

SampleObjectClass#newInstanceでインスタンス化するコードを書いて実行してみます。


■実行用のサンプルコード

public class ClazzNewInstanceTrial {

    public static void main(String[] args) {
        try {
            SampleObject obj = createSampleObject();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

    private static SampleObject createSampleObject() throws IllegalAccessException, InstantiationException {
        return SampleObject.class.newInstance();
    }
}

createSampleObjectメソッド内でClass#newInstanceを実行してSampleObjectのインスタンスを生成していますが、
createSampleObjectメソッドのシグニチャにはスローする例外としてIllegalAccessException, InstantiationExceptionのみが登場しており、
FileNotFoundExceptionは登場しません。


これを実行してみると以下の結果が出ます

■実行結果

Exception in thread "main" java.io.FileNotFoundException: target file not found.
    at sample.app.reflection.SampleObject.<init>(SampleObject.java:8)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)
    at sample.app.reflection.ClazzNewInstanceTrial.createSampleObject(ClazzNewInstanceTrial.java:16)
    at sample.app.reflection.ClazzNewInstanceTrial.main(ClazzNewInstanceTrial.java:7)

なんとまぁ、メソッドのシグニチャに登場していなかったのに、createSampleObjectメソッドがFileNotFoundExceptionをスローしています。
コード上に現れていないチェック例外がスローできてしまっています。


代替案の Constructor#newInstanceの場合

Class#newInstanceは使うなとなってどうすればいいかと言うと、Constructor#newInstanceによるインスタンス生成で代替すればいいようです。
(実際にはClass.getDeclaredConstructor().newInstance()を実行することになります)

SampleObjectのインスタンス化をしてみてClass#newInstanceとの例外に関する動きの違いを確認してみます


■実行用のサンプルコード

import java.lang.reflect.InvocationTargetException;

public class ConstructorNewInstance {

    public static void main(String[] args) {
        try {
            SampleObject obj = createSampleObject();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    private static SampleObject createSampleObject()
            throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        return SampleObject.class.getDeclaredConstructor().newInstance();
    }

}


これを実行してみると以下の結果が出ます

■実行結果

java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at sample.app.reflection.ConstructorNewInstance.createSampleObject(ConstructorNewInstance.java:23)
    at sample.app.reflection.ConstructorNewInstance.main(ConstructorNewInstance.java:9)
Caused by: java.io.FileNotFoundException: target file not found.
    at sample.app.reflection.SampleObject.<init>(SampleObject.java:8)
    ... 6 more

createSampleObjectメソッドからは、InvocationTargetExceptionでラップされたFileNotFoundExceptionがスローされて、それをcatchできています。
メソッドのシグニチャ通りの例外がスローされています。


蛇足

Java7から、java.lang.ReflectiveOperationExceptionがリフレクション関係の例外の親クラスとして定義されてますので
上記の実行サンプルのコードはReflectiveOperationExceptionを使ってもう少しシンプル記述できます。


■実行用のサンプルコード

public class ConstructorNewInstance2 {

    public static void main(String[] args) {
        try {
            SampleObject obj = createSampleObject();
        } catch (ReflectiveOperationException e) {
            e.printStackTrace();
        }
    }

    private static SampleObject createSampleObject() throws ReflectiveOperationException {
        return SampleObject.class.getDeclaredConstructor().newInstance();
    }

}

■実行結果

java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at sample.app.reflection.ConstructorNewInstance2.createSampleObject(ConstructorNewInstance2.java:14)
    at sample.app.reflection.ConstructorNewInstance2.main(ConstructorNewInstance2.java:7)
Caused by: java.io.FileNotFoundException: target file not found.
    at sample.app.reflection.SampleObject.<init>(SampleObject.java:8)
    ... 6 more

InvocationTargetExceptionでラップされたFileNotFoundExceptionがスローされて、それをReflectiveOperationExceptionでcatchできています


まとめ

Class#newInstanceConstructor#newInstanceの例外に関する動きの違いを確認しました。
Class.newInstance()を使っている箇所は、早めにClass.getDeclaredConstructor().newInstance() に置き換えましょう。



関連エントリ

MavenでOWASP Dependency CheckによるJavaライブラリの脆弱性をチェックする

OWASP Dependency Checkで使用しているJavaライブラリの脆弱性をチェックすることができます。

今回はMavenのpluginを使用します。


設定

pom.xmlに以下を追記します。

<plugins>
・・・
  <plugin>
    <groupId>org.owasp</groupId>
    <artifactId>dependency-check-maven</artifactId>
    <version>2.0.0</version>
    <configuration>
        <assemblyAnalyzerEnabled>false</assemblyAnalyzerEnabled>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>check</goal>
            </goals>
        </execution>
    </executions>
  </plugin>
・・・
</plugins>


脆弱性のチェック

pom.xmlへの追記が終わった状態で以下コマンドをを実行します

mvn dependency-check:check


すると以下のような出力がされます

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building sample-app 1.0.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- dependency-check-maven:2.0.0:check (default-cli) @ srcl ---
[INFO] Checking for updates
[INFO] starting getUpdatesNeeded() ...
[INFO] Download Started for NVD CVE - Modified
[INFO] Download Complete for NVD CVE - Modified  (5176 ms)
[INFO] Processing Started for NVD CVE - Modified
[INFO] Processing Complete for NVD CVE - Modified  (6004 ms)
[INFO] Begin database maintenance.
[INFO] End database maintenance.
[INFO] Check for updates complete (14381 ms)
[INFO] Analysis Started
[INFO] Finished Archive Analyzer (1 seconds)
[INFO] Finished File Name Analyzer (0 seconds)
[INFO] Finished Jar Analyzer (0 seconds)
[INFO] Finished Central Analyzer (4 seconds)
[INFO] Finished Dependency Merging Analyzer (0 seconds)
[INFO] Finished Version Filter Analyzer (0 seconds)
[INFO] Finished Hint Analyzer (0 seconds)
[INFO] Created CPE Index (1 seconds)
[INFO] Finished CPE Analyzer (1 seconds)
[INFO] Finished False Positive Analyzer (0 seconds)
[INFO] Finished Cpe Suppression Analyzer (0 seconds)
[INFO] Finished NVD CVE Analyzer (0 seconds)
[INFO] Finished Vulnerability Suppression Analyzer (0 seconds)
[INFO] Finished Dependency Bundling Analyzer (0 seconds)
[INFO] Analysis Complete (8 seconds)
[WARNING]

One or more dependencies were identified with known vulnerabilities in sample-app:

commons-beanutils-1.8.3.jar (commons-beanutils:commons-beanutils:1.8.3, cpe:/a:apache:commons_beanutils:1.8.3) : CVE-2014-0114


See the dependency-check report for more details.


[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 27.974 s
[INFO] Finished at: 2017-07-06T18:33:09+09:00
[INFO] Final Memory: 25M/899M
[INFO] ------------------------------------------------------------------------

今回の結果ではcommons-beanutilsの1.8.3 にCVE-2014-0114の脆弱性があることが指摘されています。


というわけで、簡単にJavaライブラリの脆弱性チェックができました。



関連エントリ