Code Review中文應該譯作“代碼審查”或是“代碼評審”,這是一個流程,當開發人員寫好代碼后,需要讓別人來review一下他的代碼,這是一種有效發現BUG的方法。由此,我們可以審查代碼的風格、邏輯、思路……,找出問題,以及改進代碼。因為這是代碼剛剛出爐的時候,所以,這也是代碼重構,代碼調整,代碼修改的最佳時候。所以,Code Review是編碼實現中最最重要的一個環節。長時間以來,Code Review需要有一些有效的工具來支持,這樣我們就可以更容易,更有效率地來進行代碼審查工作。下面是5個開源的代碼審查工具,他們可以幫助你更容易地進行這項活動。1. Review board: Review board 是一個 基于web 的工具,主要設計給 django 和python的用戶。 Review board 可以幫助我們追蹤待決代碼的改動,并可以讓Code-Review更為容易和簡練。盡管Review board 最初被設計在VMware項目中使用,但現在其足夠地通用。當前,其支持這些代碼版本管理軟件: SVN, CVS, Perforce, Git, Bazaar, 和Mercurial.Yahoo 是review-board的其中一個用戶。“Review board 已經改變了代碼評審的方式,其可以強迫高質量的代碼標準和風格,并可以成為程序員編程的指導者。每一次,當你訪問search.yahoo.com 時,其代碼都是使用 Review board工具Review過的。 We’re great fans of your work!”– Yahoo! Web Search 2. Codestriker: Codestriker 也是一個基于Web的應用,其主要使用 GCI-Perl 腳本支持在線的代碼審查。Codestriker 可以集成于CVS, Subversion, ClearCase, Perforce 和Visual SourceSafe。并有一些插件可以提供支持其它的源碼管理工具。David Sitsky 是 Codestriker 的作者,并也是最活躍的開發人員之一。 Jason Remillard 是另一個活路的開發者,并給這個項目提供了最深遠最有意義的貢獻。大量的程序員貢獻他們的代碼給 Codestriker 項目,導致了這個項目空前的繁榮。 3. Groogle: Groogle 是一個基于WEB的代碼評審工具。 Groogle 支持和 Subversion 集成。它主要提供如下的功能:各式各樣語言的語法高亮。 支持整個版本樹的比較。 支持當個文件不同版本的diff功能,并有一個圖形的版本樹。 郵件通知所有的Reivew的人當前的狀態。 認證機制。 4. Rietveld: Rietveld 由Guido van Rossum 開發(他是Python的創造者,現在是Google的員工),這個工具是基于Mondrian 工具,作者一開始是為了Google 開發的,并且,它在很多方面和Review board 很像。它也是一個基于Web的應用,并可以Google App Engine 當主機。它使用了目前最流行的Web開發框架 django 并支持 Subversion 。當前,任何一個使用 Google Code 的項目都可以使用 Rietveld 并且使用 python Subversion 服務器。當然,它同樣支持其它的Subversion服務器。 5. JCR JCR 或者叫做 JCodeReview 也是一個基于WEB界面的最初設計給Reivew Java 語言的一個工具。當然,現在,它可以被用于其它的非Java的代碼。JCR 主要想協助:審查者。所有的代碼更改都會被高亮,以及大多數語言的語法高亮。Code extracts 可以顯示代碼評審意見。如果你正在Review Java的代碼,你可以點擊代碼中的類名來查看相關的類的聲明。 項目所有者。可以 輕松創建并配置需要Review的項目,并不需要集成任何的軟件配置管理系統(SCM)。 流程信仰者。 所有的評語都會被記錄在數據庫中,并且會有狀態報告,以及各種各樣的統計。 架構師和開發者。 這個系統也可以讓我們查看屬于單個文件的評語,這樣有利于我們重構代碼。
十載的宜川網站建設經驗,針對設計、前端、開發、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。全網整合營銷推廣的優勢是能夠根據用戶設備顯示端的尺寸不同,自動調整宜川建站的顯示方式,使網站能夠適用不同顯示終端,在瀏覽器中調整網站的寬度,無論在任何一種瀏覽器上瀏覽網站,都能展現優雅布局與設計,從而大程度地提升瀏覽體驗。成都創新互聯從事“宜川網站設計”,“宜川網站推廣”以來,每個客戶項目都認真落實執行。
1、首先把編譯好的可運行無錯的所有和這個程序相關的class文件全部存到一個文件夾里。
2、新建一個文本文件名字隨意取后綴必須是.mf 假如為main.mf
3、這個main.mf文件的內容如下:
Main-Class: 可執行主類全名(如果打包了的話包含包名)
如果你的類名為Hello,在包abc中的話
應該是Main-Class:abc.Hello
4、保存這個main.mf
5、把這個main.mf文件存放在你先前建好的裝有那些class文件的文件夾里。
6、這時候,用dos命令行需要到這個文件夾目錄中去使用 jar 命令來創建 JAR 文件包。使用如下命令:
jar cvfm test.jar main.mf *.* (其中test為你自己去取的jar包名稱)
7、這樣就可以把生成的該jar包考走放到任何具有jre運行環境的任何機器上雙擊運行了。用你的在命令行下java -jar XX.jar也可以運行看到結果。
在本文中,我們討論了對付 13 種不同靜態暴露的技巧。對于每種暴露,我們解釋了不處理這些安全性問題所造成的影響。我們還為您推薦了一些準則,要開發不受這些靜態安全性暴露威脅的、健壯且安全的 Java 應用程序,您應該遵循這些準則。一有合適的時機,我們就提供代碼樣本(既有暴露的代碼也有無暴露的代碼)。
對付高嚴重性暴露的技巧
請遵循下列建議以避免高嚴重性靜態安全性暴露:
限制對變量的訪問
讓每個類和方法都成為 final,除非有足夠的理由不這樣做
不要依賴包作用域
使類不可克隆
使類不可序列化
使類不可逆序列化
避免硬編碼敏感數據
查找惡意代碼
限制對變量的訪問
如果將變量聲明為 public,那么外部代碼就可以操作該變量。這可能會導致安全性暴露。
影響
如果實例變量為 public,那么就可以在類實例上直接訪問和操作該實例變量。將實例變量聲明為 protected 并不一定能解決這一問題:雖然不可能直接在類實例基礎上訪問這樣的變量,但仍然可以從派生類訪問這個變量。
清單 1 演示了帶有 public 變量的代碼,因為變量為 public 的,所以它暴露了。
清單 1. 帶有 public 變量的代碼
class Test {
public int id;
protected String name;
Test(){
id = 1;
name = "hello world";
}
//code
}
public class MyClass extends Test{
public void methodIllegalSet(String name){
this.name = name; // this should not be allowed
}
public static void main(String[] args){
Test obj = new Test();
obj.id = 123; // this should not be allowed
MyClass mc = new MyClass();
mc.methodIllegalSet("Illegal Set Value");
}
}
建議
一般來說,應該使用取值方法而不是 public 變量。按照具體問題具體對待的原則,在確定哪些變量特別重要因而應該聲明為 private 時,請將編碼的方便程度及成本同安全性需要加以比較。清單 2 演示了以下列方式來使之安全的代碼:
清單 2. 不帶有 public 變量的代碼
class Test {
private int id;
private String name;
Test(){
id = 1;
name = "hello world";
}
public void setId(int id){
this.id = id;
}
public void setName(String name){
this.name = name;
}
public int getId(){
return id;
}
public String getName(){
return name;
}
}
讓每個類和方法都為 final
不允許擴展的類和方法應該聲明為 final。這樣做防止了系統外的代碼擴展類并修改類的行為。
影響
僅僅將類聲明為非 public 并不能防止攻擊者擴展類,因為仍然可以從它自己的包內訪問該類。
建議
讓每個類和方法都成為 final,除非有足夠的理由不這樣做。按此建議,我們要求您放棄可擴展性,雖然它是使用諸如 Java 語言之類的面向對象語言的主要優點之一。在試圖提供安全性時,可擴展性卻成了您的敵人;可擴展性只會為攻擊者提供更多給您帶來麻煩的方法。
不要依賴包作用域
沒有顯式地標注為 public、private 或 protected 的類、方法和變量在它們自己的包內是可訪問的。
影響
如果 Java 包不是封閉的,那么攻擊者就可以向包內引入新類并使用該新類來訪問您想保護的內容。諸如 java.lang 之類的一些包缺省是封閉的,一些 JVM 也讓您封閉自己的包。然而,您最好假定包是不封閉的。
建議
從軟件工程觀點來看,包作用域具有重要意義,因為它可以阻止對您想隱藏的內容進行偶然的、無意中的訪問。但不要依靠它來獲取安全性。應該將類、方法和變量顯式標注為 public、private 或 protected 中適合您特定需求的那種。
使類不可克隆
克隆允許繞過構造器而輕易地復制類實例。
影響
即使您沒有有意使類可克隆,外部源仍然可以定義您的類的子類,并使該子類實現 java.lang.Cloneable。這就讓攻擊者創建了您的類的新實例。拷貝現有對象的內存映象生成了新的實例;雖然這樣做有時候是生成新對象的可接受方法,但是大多數時候是不可接受的。清單 3 說明了因為可克隆而暴露的代碼:
清單 3. 可克隆代碼
class MyClass{
private int id;
private String name;
public MyClass(){
id=1;
name="HaryPorter";
}
public MyClass(int id,String name){
this.id=id;
this.name=name;
}
public void display(){
System.out.println("Id ="+id+"
"+"Name="+name);
}
}
// hackers code to clone the user class
public class Hacker extends MyClass implements Cloneable {
public static void main(String[] args){
Hacker hack=new Hacker();
try{
MyClass o=(MyClass)hack.clone();
o.display();
}
catch(CloneNotSupportedException e){
e.printStackTrace();
}
}
}
建議
要防止類被克隆,可以將清單 4 中所示的方法添加到您的類中:
清單 4. 使您的代碼不可克隆
public final Object clone()
throws java.lang.CloneNotSupportedException{
throw new java.lang.CloneNotSupportedException();
}
如果想讓您的類可克隆并且您已經考慮了這一選擇的后果,那么您仍然可以保護您的類。要做到這一點,請在您的類中定義一個為 final 的克隆方法,并讓它依賴于您的一個超類中的一個非 final 克隆方法,如清單 5 中所示:
清單 5. 以安全的方式使您的代碼可克隆
public final Object clone()
throws java.lang.CloneNotSupportedException {
super.clone();
}
類中出現 clone() 方法防止攻擊者重新定義您的 clone 方法。
使類不可序列化
序列化允許將類實例中的數據保存在外部文件中。闖入代碼可以克隆或復制實例,然后對它進行序列化。
影響
序列化是令人擔憂的,因為它允許外部源獲取對您的對象的內部狀態的控制。這一外部源可以將您的對象之一序列化成攻擊者隨后可以讀取的字節數組,這使得攻擊者可以完全審查您的對象的內部狀態,包括您標記為 private 的任何字段。它也允許攻擊者訪問您引用的任何對象的內部狀態。
建議
要防止類中的對象被序列化,請在類中定義清單 6 中的 writeObject() 方法:
清單 6. 防止對象序列化
private final void writeObject(ObjectOutputStream out)
throws java.io.NotSerializableException {
throw new java.io.NotSerializableException("This object cannot
be serialized");
}
通過將 writeObject() 方法聲明為 final,防止了攻擊者覆蓋該方法。
使類不可逆序列化
通過使用逆序列化,攻擊者可以用外部數據或字節流來實例化類。
影響
不管類是否可以序列化,都可以對它進行逆序列化。外部源可以創建逆序列化成類實例的字節序列。這種可能為您帶來了大量風險,因為您不能控制逆序列化對象的狀態。請將逆序列化作為您的對象的另一種公共構造器 — 一種您無法控制的構造器。
建議
要防止對對象的逆序列化,應該在您的類中定義清單 7 中的 readObject() 方法:
清單 7. 防止對象逆序列化
private final void readObject(ObjectInputStream in)
throws java.io.NotSerializableException {
throw new java.io.NotSerializableException("This object cannot
be deserialized");
}
通過將該方法聲明為 final,防止了攻擊者覆蓋該方法。
避免硬編碼敏感數據
您可能會嘗試將諸如加密密鑰之類的秘密存放在您的應用程序或庫的代碼。對于你們開發人員來說,這樣做通常會把事情變得更簡單。
影響
任何運行您的代碼的人都可以完全訪問以這種方法存儲的秘密。沒有什么東西可以防止心懷叵測的程序員或虛擬機窺探您的代碼并了解其秘密。
建議
可以以一種只可被您解密的方式將秘密存儲在您代碼中。在這種情形下,秘密只在于您的代碼所使用的算法。這樣做沒有多大壞處,但不要洋洋得意,認為這樣做提供了牢固的保護。您可以遮掩您的源代碼或字節碼 — 也就是,以一種為了解密必須知道加密格式的方法對源代碼或字節碼進行加密 — 但攻擊者極有可能能夠推斷出加密格式,對遮掩的代碼進行逆向工程從而揭露其秘密。
這一問題的一種可能解決方案是:將敏感數據保存在屬性文件中,無論什么時候需要這些數據,都可以從該文件讀取。如果數據極其敏感,那么在訪問屬性文件時,您的應用程序應該使用一些加密/解密技術。
查找惡意代碼
從事某個項目的某個心懷叵測的開發人員可能故意引入易受攻擊的代碼,打算日后利用它。這樣的代碼在初始化時可能會啟動一個后臺進程,該進程可以為闖入者開后門。它也可以更改一些敏感數據。
這樣的惡意代碼有三類:
類中的 main 方法
定義過且未使用的方法
注釋中的死代碼
影響
入口點程序可能很危險而且有惡意。通常,Java 開發人員往往在其類中編寫 main() 方法,這有助于測試單個類的功能。當類從測試轉移到生產環境時,帶有 main() 方法的類就成為了對應用程序的潛在威脅,因為闖入者將它們用作入口點。
請檢查代碼中是否有未使用的方法出現。這些方法在測試期間將會通過所有的安全檢查,因為在代碼中不調用它們 — 但它們可能含有硬編碼在它們內部的敏感數據(雖然是測試數據)。引入一小段代碼的攻擊者隨后可能調用這樣的方法。
避免最終應用程序中的死代碼(注釋內的代碼)。如果闖入者去掉了對這樣的代碼的注釋,那么代碼可能會影響系統的功能性。
可以在清單 8 中看到所有三種類型的惡意代碼的示例:
清單 8. 潛在惡意的 Java 代碼
public void unusedMethod(){
// code written to harm the system
}
public void usedMethod(){
//unusedMethod(); //code in comment put with bad intentions,
//might affect the system if uncommented
// int x = 100;
// x=x+10; //Code in comment, might affect the
//functionality of the system if uncommented
}
建議
應該將(除啟動應用程序的 main() 方法之外的)main() 方法、未使用的方法以及死代碼從應用程序代碼中除去。在軟件交付使用之前,主要開發人員應該對敏感應用程序進行一次全面的代碼評審。應該使用“Stub”或“dummy”類代替 main() 方法以測試應用程序的功能。
對付中等嚴重性暴露的技巧
請遵循下列建議以避免中等嚴重性靜態安全性暴露:
不要依賴初始化
不要通過名稱來比較類
不要使用內部類
不要依賴初始化
您可以不運行構造器而分配對象。這些對象使用起來不安全,因為它們不是通過構造器初始化的。
影響
在初始化時驗證對象確保了數據的完整性。
例如,請想象為客戶創建新帳戶的 Account 對象。只有在 Account 期初余額大于 0 時,才可以開設新帳戶。可以在構造器里執行這樣的驗證。有些人未執行構造器而創建 Account 對象,他可能創建了一個具有一些負值的新帳戶,這樣會使系統不一致,容易受到進一步的干預。
建議
在使用對象之前,請檢查對象的初始化過程。要做到這一點,每個類都應該有一個在構造器中設置的私有布爾標志,如清單 9 中的類所示。在每個非 static 方法中,代碼在任何進一步執行之前都應該檢查該標志的值。如果該標志的值為 true,那么控制應該進一步繼續;否則,控制應該拋出一個例外并停止執行。那些從構造器調用的方法將不會檢查初始化的變量,因為在調用方法時沒有設置標志。因為這些方法并不檢查標志,所以應該將它們聲明為 private 以防止用戶直接訪問它們。
清單 9. 使用布爾標志以檢查初始化過程
public class MyClass{
private boolean initialized = false;
//Other variables
public MyClass (){
//variable initialization
method1();
initialized = true;
}
private void method1(){ //no need to check for initialization variable
//code
}
public void method2(){
try{
if(initialized==true){
//proceed with the business logic
}
else{
throw new Exception("Illegal State Of the object");
}
}catch(Exception e){
e.printStackTrace();
}
}
}
如果對象由逆序列化進行初始化,那么上面討論的驗證機制將難以奏效,因為在該過程中并不調用構造器。在這種情況下,類應該實現 ObjectInputValidation 接口:
清單 10. 實現 ObjectInputValidation
interface java.io.ObjectInputValidation {
public void validateObject() throws InvalidObjectException;
}
所有驗證都應該在 validateObject() 方法中執行。對象還必須調用 ObjectInputStream.RegisterValidation() 方法以為逆序列化對象之后的驗證進行注冊。 RegisterValidation() 的第一個參數是實現 validateObject() 的對象,通常是對對象自身的引用。注:任何實現 validateObject() 的對象都可能充當對象驗證器,但對象通常驗證它自己對其它對象的引用。RegisterValidation() 的第二個參數是一個確定回調順序的整數優先級,優先級數字大的比優先級數字小的先回調。同一優先級內的回調順序則不確定。
當對象已逆序列化時,ObjectInputStream 按照從高到低的優先級順序調用每個已注冊對象上的 validateObject()。
不要通過名稱來比較類
有時候,您可能需要比較兩個對象的類,以確定它們是否相同;或者,您可能想看看某個對象是否是某個特定類的實例。因為 JVM 可能包括多個具有相同名稱的類(具有相同名稱但卻在不同包內的類),所以您不應該根據名稱來比較類。
影響
如果根據名稱來比較類,您可能無意中將您不希望授予別人的權利授予了闖入者的類,因為闖入者可以定義與您的類同名的類。
例如,請假設您想確定某個對象是否是類 com.bar.Foo 的實例。清單 11 演示了完成這一任務的錯誤方法:
清單 11. 比較類的錯誤方法
if(obj.getClass().getName().equals("Foo")) // Wrong!
// objects class is named Foo
}else{
// object's class has some other name
}
建議
在那些非得根據名稱來比較類的情況下,您必須格外小心,必須確保使用了當前類的 ClassLoader 的當前名稱空間,如清單 12 中所示:
清單 12. 比較類的更好方法
if(obj.getClass() == this.getClassLoader().loadClass("com.bar.Foo")){
// object's class is equal to
//the class that this class calls "com.bar.Foo"
}else{
// object's class is not equal to the class that
// this class calls "com.bar.Foo"
}
然而,比較類的更好方法是直接比較類對象看它們是否相等。例如,如果您想確定兩個對象 a 和 b 是否屬同一個類,那么您就應該使用清單 13 中的代碼:
清單 13. 直接比較對象來看它們是否相等
if(a.getClass() == b.getClass()){
// objects have the same class
}else{
// objects have different classes
}
盡可能少用直接名稱比較。
不要使用內部類
Java 字節碼沒有內部類的概念,因為編譯器將內部類轉換成了普通類,而如果沒有將內部類聲明為 private,則同一個包內的任何代碼恰好能訪問該普通類。
影響
因為有這一特性,所以包內的惡意代碼可以訪問這些內部類。如果內部類能夠訪問括起外部類的字段,那么情況會變得更糟。可能已經將這些字段聲明為 private,這樣內部類就被轉換成了獨立類,但當內部類訪問外部類的字段時,編譯器就將這些字段從專用(private)的變為在包(package)的作用域內有效的。內部類暴露了已經夠糟糕的了,但更糟糕的是編譯器使您將某些字段成為 private 的舉動成為徒勞。
建議 如果能夠不使用內部類就不要使用內部類。
對付低嚴重性暴露的技巧
請遵循下列建議以避免低嚴重性靜態安全性暴露:
避免返回可變對象
檢查本機方法
避免返回可變對象
Java 方法返回對象引用的副本。如果實際對象是可改變的,那么使用這樣一個引用調用程序可能會改變它的內容,通常這是我們所不希望見到的。
影響
請考慮這個示例:某個方法返回一個對敏感對象的內部數組的引用,假定該方法的調用程序不改變這些對象。即使數組對象本身是不可改變的,也可以在數組對象以外操作數組的內容,這種操作將反映在返回該數組的對象中。如果該方法返回可改變的對象,那么事情會變得更糟;外部實體可以改變在那個類中聲明的 public 變量,這種改變將反映在實際對象中。
清單 14 演示了脆弱性。getExposedObj() 方法返回了 Exposed 對象的引用副本,該對象是可變的:
清單 14. 返回可變對象的引用副本
class Exposed{
private int id;
private String name;
public Exposed(){
}
public Exposed(int id, String name){
this.id = id;
this.name = name;
}
public int getId(){
return id;
}
public String getName(){
return name;
}
public void setId(int id){
this.id=id;
}
public void setName(String name){
this.name = name;
}
public void display(){
System.out.println("Id = "+ id + " Name = "+ name);
}
}
public class Exp12{
private Exposed exposedObj = new Exposed(1,"Harry Porter");
public Exposed getExposedObj(){
return exposedObj; //returns a reference to the object.
}
public static void main(String[] args){
Exp12 exp12 = new Exp12();
exp12.getExposedObj().display();
Exposed exposed = exp12.getExposedObj();
exposed.setId(10);
exposed.setName("Hacker");
exp12.getExposedObj().display();
}
}
建議
如果方法返回可改變的對象,但又不希望調用程序改變該對象,請修改該方法使之不返回實際對象而是返回它的副本或克隆。要改正清單 14 中的代碼,請讓它返回 Exposed 對象的副本,如清單 15 中所示:
清單 15. 返回可變對象的副本
public Exposed getExposedObj(){
return new Exposed(exposedObj.getId(),exposedObj.getName());
}
或者,您的代碼也可以返回 Exposed 對象的克隆。
檢查本機方法
本機方法是一種 Java 方法,其實現是用另一種編程語言編寫的,如 C 或 C++。有些開發人員實現本機方法,這是因為 Java 語言即使使用即時(just-in-time)編譯器也比許多編譯過的語言要慢。其它人需要使用本機代碼是為了在 JVM 以外實現特定于平臺的功能。
影響
使用本機代碼時,請小心,因為對這些代碼進行驗證是不可能的,而且本機代碼可能潛在地允許 applet 繞過通常的安全性管理器(Security Manager)和 Java 對設備訪問的控制。
建議
如果非得使用本機方法,那么請檢查這些方法以確定:
它們返回什么
它們獲取什么作為參數
它們是否繞過安全性檢查
它們是否是 public、private 等等
它們是否含有繞過包邊界從而繞過包保護的方法調用
結束語
編寫安全 Java 代碼是十分困難的,但本文描述了一些可行的實踐來幫您編寫安全 Java 代碼。這些建議并不能解決您的所有安全性問題,但它們將減少暴露數目。最佳軟件安全性實踐可以幫助確保軟件正常運行。安全至關重要和高可靠系統設計者總是花費大量精力來分析和跟蹤軟件行為。只有通過將安全性作為至關緊要的系統特性來對待 — 并且從一開始就將它構建到應用程序中,我們才可以避免亡羊補牢似的、修修補補的安全性方法。
參考資料
請通過單擊文章頂部或底部的討論來參加本文的論壇。
了解關于 Java 安全性 API 的更多知識。
developerWorks 安全專題上通常含有有關計算機安全性的優秀資源。
Larry Koved、 Anthony J. Nadalin、Don Neal 和 Tim Lawson 合作編寫的 “The evolution of Java security”(developerWorks,1998 年)對 Java 語言的安全性模型早期開發進行了深入探討。
Sing Li 在他的 Java 安全性系列文章(由兩部分組成的)(developerWorks, 2001 年 2 月)中向開發人員顯示:盡管社區可能不得不重新考慮 Java 2 中的安全性設計,還是出現了只對開發人員有幫助,可以滿足他們的需求的一致的進展:
第一部分
第二部分
John Viega、Tom Mutdosch、 Gary McGraw 和 Ed Felten 合著的 “Statically scanning Java code for security vulnerabilities” (IEEE Software,2000 年 9 月)介紹了一種 Java 工具,可以使用該工具來檢查您的 Java 代碼中的安全性漏洞。
G. McGraw 和 E. Felten 合作編寫的 Securing Java: Getting Down to Business with Mobile Code(John Wiley 和 Sons,1998 年)深入涵蓋了 Java 安全性。(文檔是 PDF 格式的。)
定期檢查 IBM 研究 Java 安全頁面以便 IBM 在安全性領域的創新有重要發展時能夠跟蹤這一創新。
如果您的 Java 代碼運行在 S/390 系統上,那么您將需要查閱 S/390 Java 安全頁面以獲取額外的信息。
關于作者
Bijaya Nanda Sahu 是就職于印度 IBM Global Services 的軟件工程師。他從事過各種因特網技術和框架(J2EE、WSBCC、JADE)、 WebSphere 相關技術、UML 和 OOAD 方面的工作。目前,他從事因特網銀行安全性問題方面的工作,重點在 WebSphere Application Server 和 Portal Server 上。可以通過 bijaya.sahu@in.ibm.com 和他聯系
新聞名稱:java代碼審查清單 java代碼檢查
分享地址:http://m.kartarina.com/article34/dogeipe.html
成都網站建設公司_創新互聯,為您提供云服務器、網站策劃、小程序開發、外貿網站建設、移動網站建設、關鍵詞優化
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯