あるプログラマの日記

プログラマのメモ、出来事、考えたこと、勉強とかの雑記

Debian 9 に Maven をインストール 、その後、動作確認

1. Debian 9 に Maven をインストールする。

# apt-get install maven 

..snip..

maven (3.3.9-4) を設定しています ...
update-alternatives: /usr/bin/mvn (mvn) を提供するために自動モードで /usr/share/maven/bin/mvn を使います

2. インストール後に Maven のバージョンを確認

# mvn -version
Apache Maven 3.3.9
Maven home: /usr/share/maven
Java version: 1.8.0_25, vendor: Oracle Corporation
Java home: /usr/lib/jvm/jdk1.8.0_25/jre
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "4.9.0-9-686-pae", arch: "i386", family: "unix"

3. プロジェクトの作成
途中、'groupID': は com.myapp を、'artifactId': は myapp を入力、それ以外は Enter を入力

$ mvn archetype:generate
[INFO] Scanning for projects...
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/2.5/maven-clean-plugin-2.5.pom
Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/2.5/maven-clean-plugin-2.5.pom (4 KB at 0.9 KB/sec)
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/22/maven-plugins-22.pom

..snip..

Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 1470: 
 
Choose org.apache.maven.archetypes:maven-archetype-quickstart version: 
1: 1.0-alpha-1
2: 1.0-alpha-2
3: 1.0-alpha-3
4: 1.0-alpha-4
5: 1.0
6: 1.1
7: 1.3
8: 1.4
Choose a number: 8: 

.. snip ..

Define value for property 'groupId': com.myapp
Define value for property 'artifactId': myapp
Define value for property 'version' 1.0-SNAPSHOT: : 
Define value for property 'package' com.myapp: : 
Confirm properties configuration:
groupId: com.myapp
artifactId: myapp
version: 1.0-SNAPSHOT
package: com.myapp
 Y: : 
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: maven-archetype-quickstart:1.4
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.myapp
[INFO] Parameter: artifactId, Value: myapp
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: com.myapp
[INFO] Parameter: packageInPathFormat, Value: com/myapp
[INFO] Parameter: package, Value: com.myapp
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: groupId, Value: com.myapp
[INFO] Parameter: artifactId, Value: myapp
[INFO] Project created from Archetype in dir: /home/xxxx/project/work/myapp

.. snip ..

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 19:50 min
[INFO] Finished at: 2020-01-26T15:45:40+09:00
[INFO] Final Memory: 13M/61M
[INFO] ------------------------------------------------------------------------

4. 検証する。

$ cd myapp

$ mvn validate
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building myapp 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.977 s
[INFO] Finished at: 2020-01-26T15:48:00+09:00
[INFO] Final Memory: 4M/15M
[INFO] ------------------------------------------------------------------------

5. コンパイルする。

$ mvn compile
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building myapp 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-resources-plugin/3.0.2/maven-resources-plugin-3.0.2.pom

..snip..

Downloaded: https://repo.maven.apache.org/maven2/com/thoughtworks/qdox/qdox/2.0-M9/qdox-2.0-M9.jar (310 KB at 34.4 KB/sec)
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /home/xxxx/project/work/myapp/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:22 min
[INFO] Finished at: 2020-01-26T15:50:49+09:00
[INFO] Final Memory: 14M/37M
[INFO] ------------------------------------------------------------------------

6. テストする。

~/project/work/myapp$ mvn test
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building myapp 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-surefire-plugin/2.22.1/maven-surefire-plugin-2.22.1.pom

..snip..

Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-junit4/2.22.1/surefire-junit4-2.22.1.jar (83 KB at 48.7 KB/sec)
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.myapp.AppTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.369 s - in com.myapp.AppTest
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 56.263 s
[INFO] Finished at: 2020-01-26T16:04:26+09:00
[INFO] Final Memory: 16M/40M
[INFO] ------------------------------------------------------------------------

7. パッケージを生成する。

~/project/work/myapp$ mvn package
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building myapp 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-jar-plugin/3.0.2/maven-jar-plugin-3.0.2.pom

..snip..

[INFO] Building jar: /home/xxxx/project/work/myapp/target/myapp-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 28.561 s
[INFO] Finished at: 2020-01-26T16:08:19+09:00
[INFO] Final Memory: 12M/97M
[INFO] ------------------------------------------------------------------------

8. フォルダ構成を確認する。

$ tree
.
├── pom.xml
├── src
│   ├── main
│   │   └── java
│   │       └── com
│   │           └── myapp
│   │               └── App.java
│   └── test
│       └── java
│           └── com
│               └── myapp
│                   └── AppTest.java
└── target
    ├── classes
    │   └── com
    │       └── myapp
    │           └── App.class
    ├── generated-sources
    │   └── annotations
    ├── generated-test-sources
    │   └── test-annotations
    ├── maven-archiver
    │   └── pom.properties
    ├── maven-status
    │   └── maven-compiler-plugin
    │       ├── compile
    │       │   └── default-compile
    │       │       ├── createdFiles.lst
    │       │       └── inputFiles.lst
    │       └── testCompile
    │           └── default-testCompile
    │               ├── createdFiles.lst
    │               └── inputFiles.lst
    ├── myapp-1.0-SNAPSHOT.jar
    ├── surefire-reports
    │   ├── TEST-com.myapp.AppTest.xml
    │   └── com.myapp.AppTest.txt
    └── test-classes
        └── com
            └── myapp
                └── AppTest.class

28 directories, 13 files

9. pom.xml を変更する。
pom.xml のバックアップを取ってから、編集する。

$ cp -aiv pom.xml pom.xml.`date +%Y%m%d`
'pom.xml' -> 'pom.xml.20200126'

$ vi pom.xml
$ diff -u pom.xml.`date +%Y%m%d` pom.xml
--- pom.xml.20200126	2020-01-26 15:45:40.525060334 +0900
+++ pom.xml	2020-01-26 16:56:36.444269386 +0900
@@ -51,6 +51,15 @@
         <plugin>
           <artifactId>maven-jar-plugin</artifactId>
           <version>3.0.2</version>
+          <configuration>
+            <archive>
+              <manifest>
+	        <addClasspath>true</addClasspath>
+                <classpathPrefix>lib/</classpathPrefix>
+                <mainClass>com.myapp.App</mainClass>
+              </manifest>
+	    </archive>
+          </configuration>
         </plugin>
         <plugin>
           <artifactId>maven-install-plugin</artifactId>

10. パッケージを再生成する。
clean してから package を作成する。

$ mvn clean
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building myapp 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/3.1.0/maven-clean-plugin-3.1.0.pom

$ mvn package
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building myapp 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ myapp ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
..snip..

[INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) @ myapp ---
[INFO] Building jar: /home/xxxx/project/work/myapp/target/myapp-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 16.653 s
[INFO] Finished at: 2020-01-26T16:59:54+09:00
[INFO] Final Memory: 12M/99M
[INFO] ------------------------------------------------------------------------

11. 動作を確認
作成後の jar ファイルを実行して動作を確認する。

$ LANG=C java -jar target/myapp-1.0-SNAPSHOT.jar
Hello World!

Debian 9 へ OpenJDK をインストール

Debian 9 へOpenJDKをインストールする。

# apt-get update

# apt-get install default-jdk


複数のバージョンがインストールされている場合は、
下のコマンドでバージョンを切り替える。

 # update-alternatives --config java

 
切り替えたjava のバージョンを確認する。

# java -version

openjdk version "1.8.0_232"
OpenJDK Runtime Environment (build 1.8.0_232-8u232-b09-1~deb9u1-b09)
OpenJDK Server VM (build 25.232-b09, mixed mode)

# javac -version
javac 1.8.0_232


http://openjdk.java.net

レトロコードの不吉な匂い

最近の仕事は、過去に java で開発したシステムのバージョンアップを行っていますが
java のバージョンは過去のままで行っています。(レトロ)

10年くらい前に開発していたシステムですが、今見直すとリファクタリングした方が良いと思うコードがところどころあります。コードの「不吉な匂い」が...

 

数年前の自分は、もはや他人。
過去に自分が書いたコードも、現時点で見直すと「何か変」ということもあったりします。

コードが属人化してしまっているのを見ると他のプログラマーからの介入を防ぐためか、リファクタリングを避けて障壁を築いているのかと思ってしまうことがある...
(勘繰りが過ぎると!)

属人化は、長期的にみてプロジェクトチームや企業の損失なります。
他の人で対応できないため特定の個人だけで対応することになり
内部の問題が顕在化しないため、導入後に問題が発生したりするなど様々な弊害がでます。


改めて「リファクタリング」というのは
外部的な振る舞いを保ちつつ、内部構造を改善すること。
外部の動作や機能は変化しないままで、

内部コードの設計や構造を変更して改善すること。

 

「内部構造を改善すること」とは、

すぐ理解できるような構造にすること。

コードを見てその目的がわかるようにすること。

 

人が理解しづらいコードは、コードを見てもその目的がわからないため
コードが読みにくく変更や追加を行うのに時間がかかり、
かつバグを作りこんでしまうリスクも高くなります。

 

プログラムは完成した後も頻繁に仕様が変更されたり

機能が追加されたりするものです。
将来の仕様変更に備えてコードの修正箇所を正確に速く見つけてることができ

るようにしておくと作業効率が良くなり、バグが入り込む余地も少なくなります。


なので、常に、変更・追加がしやすいように理解しやすく見通しがよいコードに
保っておく必要があります。
オブジェクト指向プログラミングの利点を活かせるようにしておくことが重要です。
ポイントは
 ・可読性
 ・再利用性
 ・柔軟性


リファクタリングの目的
 ・設計の向上
 ・設計の劣化防止
 ・理解しやすいコードを保つ
 ・バグの特定
 ・プログラミングの迅速化

 

リファクタリングを始める前に、対象コードに対するテストコードを

書くことが必須です。

人の手が入るとどうしてもバグが入り込む余地がでてくるので
小さなステップでリファクタリングを繰り返して、その都度、自動テスト(JUnitなど)を行うようにするのが安全です。


リファクタリングのタイミング

 ・過去に作成したときに良いと思えた設計が現時点で

  見直すとミスマッチであると認識できた時点でリファクタリングを行う。

 ・重複コードを発見した時
  コードの重複部部をなくす。メソッド化する。
  それによって結果的にコード量を減らすことができます。

 ・コードを理解するときにリファクタリングを行う。

 

新年、明けましておめでとうございます。

あけましておめでとうございます。

今年もよろしくお願いします。

昨年の前半は以前から携わっていたシステムへの追加機能の開発と、後半は
過去に開発したシステムをベースに違うバージョンのシステムを開発していました。

今年も昨年後半の案件を継続して行う予定です。

 

「2020年の抱負」は、もっと多くの方とかかわれるようなことをやること。
今の仕事は継続して続けて行きたいのですが、さらに、もっと多くの方と

かかわる仕事もすることです。

 

昨年は、体調面では体の故障や不調が続きました。
左手のテニス肘、右ふくらはぎ肉離れ、肋骨の骨折、謎の発熱と神経痛…
整形外科と内科に頻繁に行きました。特に整形外科の込み具合は半端なかった。
午前9時に整形外科に行ったのだが午後を過ぎても診察の順番がまわってこなかった。
この時、もうここの整形外科のお世話にはなりたくないものだとつくづく思いました。


この間、仕事は休むこともなく続けていました。
肉離れした時は、松葉杖で出勤しましたが、かなり大変だった。
職場に着いたときはくたくた、怪我していない左足が筋肉痛になってしまった。

 

最近は右手でつっぱたり、右の手首を回すと痛くて
腱鞘炎なのかと思っていましたが、調べてみると症状が
三角線維軟骨複合体(TFCC)というのに似ています。

 

今年は、健康面でもっと注意する必要がありそうです。
普段の生活で無理しないようにするのと、もっと体を鍛えようと思います。

最近のお仕事

近況ですが、java での開発から C/C++, JavaScript を使った開発が今はメインになっています。

現在、ざっくりとした要求仕様から、[基本仕様]-[詳細仕様] が確定していない状態で開発するスタイルが板に付いています。実装(コーディング)前の設計段階で、曖昧な仕様箇所を redmine のチケットにあげています。曖昧な箇所は、レアケースな処理やイレギュラーなイベントが起こった場合の処理がほとんどです。エラーが発生した場合、内部でどのように処理を行うか、処理を継続するか、終了するか。外部ではユーザーにどのようにエラーイベントの内容を伝えるか。エラーメッセージを表示するか。初期状態にもどすか、など。

仕様が決まる過程で、いろいろと意見をいったり、仕様に納得できないときは、仕様の根拠を突き詰めて追及してしまうため、煙たがられる面もありますが恣意的で不合理な仕様に対しては、できるかぎり抵抗しています。

過去の仕事では、仕様確定の進め方・過程で考えさせられることが多かったです。要求仕様を出す側も、それを元に開発を進める側も、どの仕様がベストなのかがわからない場合いくつかの選択肢を抽出して、その内容をお互いで共有した後、内容について議論し合ってから要求仕様を出す側で仕様を決定してもらうというのがベストだと考えています。

思い出したように...

3年以上放置して思い出したように更新しています。

久しぶりにというか、書いていたことも忘却しかけている。しばらくすると放置状態になってしまうので、過去の仕事のことなどを日記に書き残していこうかなと思っています。長い間プログラマー・SEとして、仕事をしてきました。現在も継続しています。フリーになったのは今から13年ほど前で、今も現役のフリーでバリバリやっています。


フリーになるまでは、ソフトウェア開発会社, 所謂 Sler にいました。SIerは 2社経験しています。その前は電機メーカーのディーラー/販売会社で営業をしていました。経歴としては、もとはプログラマー・SEではなく営業職から転職したので、特殊だと言われることが多いです。


今、現在の仕事は自社の製品に搭載するソフトウエアの開発をおこなっています。なので仕事は製品が存在するかぎり継続しています。リリース後はプロジェクトはいったん終了しますが、基本はエンドレスです。

要求仕様問題プロジェクト その過程

 要求仕様に関しては、いつも確定しないまま実装に入ってインクリメンタルな開発を行うことが多かった。しかし、ついこの前の組み込み系通信システムの開発は完全なウォーターフォール型でした。結果はなんとか結合テストまで完了しましたが、その過程は散々でした。ウォーターフォール型では、設計に入る前に仕様が確定されることが前提ですが、T.B.D 項目以外にも仕様変更ではなく仕様漏れがけっこうありました。

 数人で実装しましたが、あいまいな仕様のまま実装した箇所は、結合試験ではまともに動作しなかった。当然といえば当然の成り行きです。短い期間で開発しなければならないプレッシャーがプロジェクトにあり、この圧力からプロジェクトリーダーは常にプロジェクトの建前上の進捗に執着して、実質的な問題点をおざなりにする傾向があったと思います。いや何が実質的な問題なのかもちゃんとわかっていなかったのではないかと思います。問題点をプロジェクトリーダーに報告してもその問題が根本的に解消されることはなかったし不明点が明確になることもなかった。開発時に、あまりにも不明点が多すぎましたが、それを問題としてクライアントにあげることができなかったのが致命的でした。クライアントへの進捗報告や打合せは、プロジェクトリーダーが行っていましたが、そこで問題点をクライアントに報告することをしていなかった。詳細仕様を設計段階で確定するとしても、それは要求仕様として本来確定すべきものであるとの認識がなかったように思います。
そのプロジェクトリーダーは結合試験前に、このプロジェクトから離脱しました。

【結論】

  • 不明点は不明点として顕在化させる。(報告する)
  • 短納期のプレッシャーに負けずに、本質的な問題を、把握して顕在化させる。(報告する)
  • 品質と納期に重点をおいて実現すべき機能に優先順位をつける。
  • それを踏まえて計画をたて、スケジューリングする。
  • その計画達成のための適切な開発手法を採用する。
  • 問題点の解決方法を検討する。