---
# System prepended metadata

title: 2020萬年系統升級
tags: [系統升級, 成長歷程, big5 轉 UTF-8]

---

# 2020萬年系統升級

###### tags: `系統升級` `成長歷程` `big5 轉 UTF-8`

## 架構調整

### 原系統架構簡介

#### AP環境
**OS** : windowsSever 2003

**web Sever**: IBM websphere

**JDK version**: 1.4

#### DB環境
**OS: windowsSever** 2003

**DB version**: IBM DB2 8.2

**資料庫編碼**： big5

### 升級後系統架構

#### AP環境
**OS**: CentOS 6

**web Sever**: SUN Glassfish 2.1.1

**JDK version**: 1.5

#### DB環境
**OS**: CentOS 7

**DB version**: IBM DB2 9.7

**資料庫編碼**：UTF-8

## 升級主要原因
1. 因應2020的資安需求，舊的作業系統windowsSever 2003已經日件不符合資安需求，因此需要進行升級。

## 評估限制因素
1. 客戶預算限制，無法升級至windowsSever 2019
2. 人力時間因素，需要在一年內完成升級作業
3. big5 難字來源已不再提供更新

剩下的我就不清楚，因為我只負責AP程式處理

## 評估結果
1. DB 資料轉UTF-8
2. AP 程式原碼全轉
3. 有關路徑相關程式片斷需做調整，因為OS類型不同

## 升級過程

### 準備相似的開發環境
1. OS: Linux

### AP
1. 轉程式編碼
2. 更改路徑
3. 更改換行符號

## 升級過程的技術障礙

### 尋找適合的開發環境

我覺得負責一個系統，不管是開發也好、維運也好，自己的開發環境要能愈相近生產境愈好。因為可以事先預防生產環境與開發環境不同所造成的問題(雖然可以透過container解決，如：docker；但是升級前沒有引入)，也能在生產環境出現問題時容易找出問題的癥結點。

本來想說用CentOS7，問題卡在Netbeans 6.7 一直無法正常執行，所以最後挑了Ubuntu20.04。過程中嘗試了相近的OpenSUSE、RedHat都無法。但是又不想用CentOS 6，因為yum不支援了。

### 10000個java、JSP檔案要如何進行轉碼？

知道要執行這個任務時，時間是發生在2020年3月，人力上只有我一個人，時間上剩下半年多。一個人要如何將10000個java、JSP程式碼檔案全部轉完，即使有現成的工具轉，但是JSP的特殊限制必須更改檔案文本內容，細數JSP檔案就有6854個，總部可能全部手動用notepad++打開、取代、打開、取代......循環至改完。另一個問題點是，有需求變更就得更改這些檔案內容，在完成系統升級之前我都得不停做轉碼的動作。於是我嘗試去研究如何判定原始檔案編碼、如何轉碼、如何用我最熟悉的語言工具JAVA處理，開始自己開發工具解決轉碼問題。後來這部份我花了三天的時間解決。

### 報表換行問題

調整完AP後境行測試，測試回報發現產出的文字檔通通不能換行了，但是我卻可以。我的電腦是Ubuntu但是測試人的電腦是windows10。發現產出檔案的換行字元跟以前不一樣。所以我在批次的處理過程中將下列的程式碼做處理：

```java
BufferedWriter fout = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path + filename), charset));
fout.write("檔案內容");
fout.newLine();  //-----> 會自動依OS寫入換行
fout.write("\r\n"); //-------> 強迫寫入 CR LF
```

#### jsp利用system.out 產檔

##### 症狀

windows 使用者打開檔案長長的一串文字

##### 原因

```java=
out.println("檔案內容"); //-----> 會依系統預設換行
out.print("\r\n"); //-------> 強迫寫入 CR LF
```

#### jsp腳本換行 產檔也會有換行問題

##### 症狀1

windows 使用者打開檔案長長的一串文字

##### 原因

因為jsp會先在webSever 依 jsp腳本產出檔案(html or any File Type)
如果腳本中有換行字元會依系統預設換行，例如

```jsp=
  //----> 魔鬼藏在換行的細節裡

```

##### 症狀2

windows 使用者打開檔案長長的一串文字

##### 原因

因為jsp會先在webSever 依 jsp腳本產出檔案(html or any File Type)
如果腳本中有換行字元會依系統預設換行，例如下列程式碼

```jsp=
<%
//[1],重複案件僅查出一筆 2012/02/01 #Jimmy
%>  //----> 魔鬼藏在換行的細節裡
<%! 
```
##### 解決方式

通通**刪掉**換行字元

### 亂碼

#### java 壓縮zip後檔名亂碼

##### 症狀

windows 使用者解壓縮檔案後檔名是亂碼，但是linux使用者正常

##### 原因

```java=
org.apache.tools.zip.ZipOutputStream zos
....其中省略....
zos.putNextEntry(zipEntry);
zos.setEncoding(encoding); //------> 如果沒有設定會抓系統預設編碼
zos.closeEntry();

```

#### 程式功能：轉碼之後亂碼

##### 症狀

有些純文字檔在業務需求上，會需要指定編碼。但是開發者的系統作業環境是windows，生產環境卻是Linux。再java有些String API是以系統預設編碼做處理。

##### 原因

```java
String s = "中文字";
byte[] buf = null;
buf = s.getBytes(); //-------> 會使用系統預設編碼 

```

##### 解決方式

```java
String s = "中文字";
byte[] buf = null;
try {
    buf = s.getBytes("Ms950"); //-------> 指定編碼

    if ((start + n) > buf.length)
            n = buf.length - start;
    } catch (UnsupportedEncodingException ex) {
    ex.printStackTrace();
}
```

#### java 壓縮zip後檔名亂碼
##### 症狀
windows 使用者解壓縮檔案後檔名是亂碼，但是linux使用者正常

##### 原因
```java
/*如果是文件目錄*/
ZipEntry zipEntry=new ZipEntry(basePath + System.getProperties().getProperty("file.separator"));
zipEntry.setUnixMode(755);//解决linux亂碼

/*如果是文件目錄*/
ZipEntry zipEntry=new ZipEntry(base);
zipEntry.setUnixMode(644);//解决linux亂碼

/*如果是文件，則*/
org.apache.tools.zip.ZipOutputStream zos
....其中省略....
zos.putNextEntry(zipEntry);
zos.setEncoding(encoding); //------> 如果沒有設定會抓系統預設編碼
zos.closeEntry();


### DB2 UTF-8 版本，SQL腳本有全形空格需要處理

以下SQL看是可以執行，實際上是不行的

```SQL
SELECT
*
FROM TEST　T ---> 有全形空格
```

需要改成

```SQL
SELECT
*
FROM TEST T
```

### 嘗試升級JDK11(非本次主要任務)

為什麼要升級JDK，主要是開發效率可以有效提生。以JAVA語法層面來說：像是在遺留程式碼當中有很多迴圈加判斷的多層巢狀，其實很適合用管線(stream)重構，一方面效能可以提升以外，另一方面外來在讀程式碼也比較容易理解程式鎖鑰描述的意圖。JVM的層面來說：JDK11 記憶體資源回收的效能肯定是比JDK1.4 來的好，未來有可能AP比較不容易發生不可預期的錯誤。

但是常升級的過程當中，發現J2EE與JEE是有很大的差異的。像是javaMail的套件在JEE已經被移除，需要另外下載jar引入......等，這些，問題都是好解決。真正障礙點是該專案產品的前公司遺留下來的jar檔阻礙了升級這件事。不知道升級到JDK6 以後就會出現google查不到的錯誤，礙於時間因素只好先升級到JDK1.5。
