<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    JunXiu

    如何在WebSphere中解決jar包沖突

    Jar包沖突問題是在大型Java軟件開發中經常遇到的問題,系統開發人員經常會為解決類似的問題耗費大量的時間進行調試和測試,本文根據各種際情況,結合WebSphere中類加載器,討論了幾種解決jar包沖突問題的辦法,并給出了具體實現的步驟及源代碼。
    讀者定位為具有Java和WebSphere開發經驗的開發人員。
    讀者可以學習到在WebSphere中類加載器的定義以及解決jar包沖突問題的幾種辦法,并可以直接使用文章中提供的Java代碼,從而節省他們的開發和調試時間,提高效率。


            大型的基于WebSphere的項目開發中,同一個WebSphereApplicationServer(以下簡稱WAS)上會部署多個應用程序,而這多個應用程序必然會共用一些jar包,包括第三方提供的工具和項目內部的公共jar等。把這些共用的jar包提取出來在多個應用程序之間共享,不僅可以統一對這些jar包進行維護,同時也提高了WAS的性能。但是隨著應用的不斷擴大,新的應用程序的不斷增加,新的應用程序會希望使用一些更高版本的共享jar包,而由于系統運行維護的需要,老的應用程序仍然希望用老版本的共享jar包,這樣就必然造成了共享jar包的版本沖突。jar包版本沖突問題是在大型應用項目的開發中經常遇到的問題,本文試圖從WebSphere的類加載器入手,討論幾種在不同情況下解決jar包沖突問題的辦法。
    WebSphere中類加載器介紹
    Jar包沖突實際上是應用程序運行時不能找到真正所需要的類,而影響類的查找和加載的是JVM以及WebSphere中的類加載器(class loader),為此,我們首先介紹一下WebSphere中的類加載器以及一些相關的概念。
    WebSphere中類加載器層次結構
    Java應用程序運行時,在class執行和被訪問之前,它必須通過類加載器加載使之有效,類加載器是JVM代碼的一部分,負責在JVM虛擬機中查找和加載所有的Java 類和本地的lib庫。類加載器的不同配置影響到應用程序部署到應用程序服務器上運行時的行為。JVM和WebSphere應用程序服務器提供了多種不同的類加載器配置, 形成一個具有父子關系的分層結構。WebSphere中類加載器的層次結構圖1所示:

    圖1:WebSphere中類加載器的層次結構


    如上圖所示,WebSphere中類加載器被組織成一個自上而下的層次結構,最上層是系統的運行環境JVM,最下層是具體的應用程序,上下層之間形成父子關系。
    • JVM Class loader:位于整個層次結構的最上層,它是整個類加載器層次結構的根,因此它沒有父類加載器。這個類加載器負責加載JVM類, JVM 擴展類,以及定義在classpath 環境變量上的所有的Java類。
    • WebSphere Extensions Class loader:WebSphere 擴展類加載器, 它將加載WebSphere的一些runtime 類,資源適配器類等。
    • WebSphere lib/app Class loader:WebSphere服務器類加載器,它將加載WebSphere安裝目錄下$(WAS_HOME)/lib/app路徑上的類。 在WAS v4版本中,WAS使用這個路徑在所有的應用程序之間共享jar包。從WAS v5開始, 共享庫功能提供了一種更好的方式,因此,這個類加載器主要用于一些原有的系統的兼容。
    • WebSphere "server" Class loader:WebSphere應用服務器類加載器。 它定義在這個服務器上的所有的應用程序之間共享的類。WAS v5中有了共享庫的概念之后,可以為應用服務器定義多個與共享庫相關聯的類加載器,他們按照定義的先后順序形成父子關系。
    • Application Module Class Loader:應用程序類加載器,位于層次結構的最后一層,用于加載J2EE應用程序。根據應用程序的類加載策略的不同,還可以為Web模塊定義自己的類加載器。
    關于WebSphere的類加載器的層次結構,以下的幾點說明可能更有助于進一步的理解類的查找和加載過程:
    • 每個類加載器負責在自身定義的類路徑上進行查找和加載類。
    • 一個子類加載器能夠委托它的父類加載器查找和加載類,一個加載類的請求會從子類加載器發送到父類加載器,但是從來不會從父類加載器發送到子類加載器。
    • 一旦一個類被成功加載,JVM 會緩存這個類直至其生命周期結束,并把它和相應的類加載器關聯在一起,這意味著不同的類加載器可以加載相同名字的類。
    • 如果一個加載的類依賴于另一個或一些類,那么這些被依賴的類必須存在于這個類的類加載器查找路徑上,或者父類加載器查找路徑上。
    • 如果一個類加載器以及它所有的父類加載器都無法找到所需的類,系統就會拋出ClassNotFoundExecption異常或者NoClassDefFoundError的錯誤。
    類加載器的委托模式
    類加載器有一個重要的屬性:委托模式(Delegation Mode,有時也稱為加載方式:Classloader mode)。委托模式決定了類加載器在查找一個類的時候, 是先查找類加載器自身指定的類路徑還是先查找父類加載器上的類路徑。
    類加載器的委托模式有兩個取值:
    • Parent_First:在加載類的時候,在從類加載器自身的類路徑上查找加載類之前,首先嘗試在父類加載器的類路徑上查找和加載類。
    • Parent_Last:在加載類的時候,首先嘗試從自己的類路徑上查找加載類,在找不到的情況下,再嘗試父類加載器類路徑。
    有了委托模式的概念,我們可以更加靈活的配置在類加載器的層次結構中類的加載和查找方式。表1中給出了在WebSphere的類加載器層次結構中各個類加載器的委托模式的定義,并給出了不同的類加載器內類的生命周期。


    注意:在上表中,"JVM Class loader" 因為在類加載器的最頂層,它沒有父類加載器,因此其委托模式為N/A,"WebSphere Extensions Class loader"和"WebSphere lib/app Class loader"的委托模式固定為表中的取值,不可配置,其它的類加載器的委托模式都是可以配置的。
    WebSphere中的類加載器策略
    WebSphere中對類加載器有一些相關的配置,稱為類加載器策略(class loader policy)。類加載器策略指類加載器的獨立策略(class loader isolation policy),通過類加載器策略設置,我們可以為WAS和應用程序的類加載器進行獨立定義。
    每個WAS可以配置自己的應用程序類加載器策略,WAS中的每個應用程序也可以配置自己的Web模塊類加載器策略,下面我們對這兩種策略分別介紹。
    1.應用服務器(WAS)配置:應用程序類加載器策略
    應用服務器對應用程序類加載器策略有兩種配置:
    • Single:整個應用服務器上的所有應用程序使用同一個類加載器。在這種配置下,每個應用程序不再有自己的類加載器。
    • Multiple:應用服務器上的每個應用程序使用自己的類加載器。
    2.應用程序配置:Web模塊類加載器策略
    應用程序中對Web模塊類加載器有兩種配置:
    • Application:整個應用程序內的所有的實用程序jar包和Web模塊使用同一個類加載器。
    • Module:應用程序內的每個Web模塊使用自己的類加載器。應用程序的類加載器仍然存在,負責加載應用程序中Web模塊以外的其它類,包括所有的實用程序jar包。
    從上面的定義可以看出,不同的類加載器策略的配置下,類加載器的層次結構上的某些類加載器可能不存在。比如在應用程序服務器的應用程序類加載器策略定義為single的情況下,應用程序的類加載器將不存在,同一個應用服務器上的所有應用程序將共用同一個類加載器,這也就意味著不同的應用程序之間的類是共享的,應用程序間不能存在同名的類在WebSphere中解決jar包沖突
    Jar包沖突問題實際上就是應用程序希望用某一個確定版本的jar包中的類,但是類加載器卻找到并加載了另外一個版本的jar包中的類。在上一部分介紹了WebSphere中類加載器的基本概念和相關配置之后,我們來看如何在WebSphere中解決jar包沖突。
    在WAS v5版本之前,使用共享jar包的方式是將jar包放在$(WAS_HOME)/lib/app路徑下,從上一部分中,我們可以看到,這個路徑正是"WebSphere lib/app Class loader" 類加載器的類查找路徑,WebSphere會查找這個路徑以取得相應得jar包中的Java類,從而做到在WebSphere ND上的多個應用程序之間共享jar包的目的。但是這樣做的一個缺點就是這些共享jar包暴露給WebSphere ND上所有的應用程序,對于那些希望使用jar包其它版本的應用程序,這些jar包也同樣存在在了它們的類加載器類路徑上,因此,就不可避免的會造成版本的沖突。在WAS v5版本及之后,增加了共享庫(shared library)的概念,推薦的在多個應用程序間共享jar包并避免jar包沖突的方式是使用共享庫。
    具體分析引起jar包沖突的情況,主要有三種:
    • 多個應用程序間jar包沖突:多個應用程序間由于使用了共享jar包的不同版本而造成jar包版本沖突。
    • 應用程序中多個Web模塊間jar包沖突:同一個應用程序內部,不同的Web模塊間同時使用一個jar包的不同版本而造成jar包版本沖突。
    • 應用程序中同一個Web模塊內jar包沖突:同一個應用程序內部,同一個Web模塊內,由于需要同時使用同一個jar包的兩個版本而造成的jar包沖突
    本部分根據這三種jar包沖突的情況,討論三種解決jar包沖突的辦法,并具體討論三種解決辦法的實現步驟和適用情況:
    • 共享庫方式解決jar包沖突:主要解決應用程序間的jar包沖突問題
    • 打包到Web模塊中解決jar包沖突:主要解決應用程序中多個Web模塊間jar包沖突問題
    • 命令行運行方式解決jar包沖突:主要解決應用程序中同一個Web模塊內jar包沖突問題
    共享庫方式解決jar包沖突
    在WAS v5中,提供了一種很好的機制,使得jar包只存在于需要這個jar包的應用程序的類加載器的路徑上,而其它的應用程序不受它的任何影響,這就是共享庫(Shared library)。共享庫可以用在應用服務器級別和應用程序級別,使用應用程序級別的共享庫,其好處就是在不同的應用程序之間使用共享jar包的不同版本。我們可以為一些通用jar包的每個不同版本定義成不同的共享庫,應用程序希望使用哪個版本,就把這個版本的共享庫放到應用程序的類加載器的類路徑上,這種方式有效的解決了應用程序之間jar包沖突的問題。
    下面舉例介紹定義和使用共享庫的具體方法,本例中,假設存在xerces.jar包版本沖突。
    1. 定義共享庫
    系統管理員可以在WebSphere的Admin console中定義共享庫,可以分別在Cell、Node以及server的級別上定義。
    • 步驟一: 進入Admin console,選擇Environment > Shared Library > new。如圖2所示:



    圖2:WebSphere Admin Console中進入共享庫頁面

  • 步驟二: 給出共享庫的名字,并指定共享的文件和目錄。多個不同的文件/目錄之間通過"Enter"鍵分隔,且不能有路徑分隔符,如":"和";"等。如圖3所示:

    圖3:WebSphere Admin Console中添加共享庫
  • 步驟三:點擊Apply或者OK之后,就添加了一個名字為Xerces V2.0的共享庫。記住添加完成后一定要在admin console保存配置。如圖4所示:

    圖4:WebSphere Admin Console中共享庫列表
  • 2.安裝應用程序
    進入Admin console,選擇Applications > Install New Application 安裝應用程序。請參照IBMWebSphere的Admin console使用手冊進行安裝新的應用程序,此處不再詳細介紹。
    3.將共享庫關聯到應用程序

    • 步驟一:進入Admin console,選擇Applications >Enterpriseapplications ,并選擇需要使用共享庫的應用程序。注意:因為要改變應用程序的設置,所以如果應用程序已經運行,需要先停掉應用程序。如圖5所示:

      圖5:WebSphere Admin Console中選擇需要配置的應用程序
    • 步驟二: 點擊應用程序,進入后,選擇Libraries。如圖6所示:

      圖6:WebSphere Admin Console中選擇應用程序庫屬性
    • 步驟三: 點擊Add,為應用程序添加共享庫。如圖7所示:

      圖7:WebSphere Admin Console中應用程序添加庫
    • 步驟四: 從下拉列表中選擇所需要的共享庫,點擊OK。如圖8所示:

      圖8:WebSphere Admin Console中應用程序添加庫頁面指定所用的共享庫

    這樣,Xerces V2.0共享庫定義的xerces版本就存在于了應用程序類加載器的類加載路徑上。注意,在添加完成后要保存服務器的設置。
    4.設置應用程序的類加載器的委托模式為Parent_Last
    為了進一步防止共享庫定義的jar包的其它版本已經存在于JVM或者WebSphere的類加載器路徑上,還需要設置應用程序的類加載器的委托方式為Parent_Last。

    • 步驟一:進入Admin console,選擇Applications > Enterprise applications > ,選擇需要配置的應用程序。如圖9所示:

      圖9:WebSphere Admin Console中選擇需要配置的應用程序
    • 步驟二:點擊進入應用程序,設置類加載器的委托模式為Parent_Last。注意:在配置完成后,要保存配置,最后啟動應用程序。如圖10所示:

      圖10:WebSphere Admin Console中為應用程序設置類加載器委托模式

    通過上面的配置,即使xerces的其它版本已經存在于系統中,應用程序在運行時,其類加載器也會首先查找并加載指定的共享庫中的xerces版本。這樣我們就通過使用共享庫的方式,解決了jar包版本沖突問題。
    打包到Web模塊中解決jar包沖突
    共享庫的方式,只是在應用程序的層次上,在多個應用程序之間解決了共享jar包造成的版本沖突問題,如果一個應用程序的內部,其中一個Web模塊使用了一個jar包的A版本,而另一個Web模塊使用這個jar包的B版本,在這種情況下造成的jar包沖突,共享庫的方式是無法解決的,我們可以考慮將其中一個在多個應用程序間共享的jar包版本,比如A版本,定義成共享庫,或者放在"WebSphere lib/app Class loader"類加載器路徑上供多個應用程序使用,而將B版本的jar包打包到使用它的Web模塊中的方式來解決沖突。
    其次,目前很多在線的系統是WAS v4的遺留系統,其上運行的應用程序已經使用了"WebSphere lib/app Class loader"類加載器,將jar包放在$(WAS_HOME)/lib/app目錄下進行共享。如果由于其中某個應用程序的升級或者新增加某個應用程序,需要使用某個共享jar包的其它版本,在這種情況下,為了減少對系統的影響,也可以考慮將這個共享jar包的新版本打包到升級(或新增)的應用程序中的方式來解決jar包沖突。
    由于Web模塊的WebContent/WEB-INFO/lib目錄在應用程序Web模塊的類加載器查找路徑上,因此,我們可以把jar包放在這個目錄下,Web模塊的類加載器將自動查找并加載這個jar包中的類。

    • 步驟一:在WSAD IE集成開發環境中,將沖突jar包放在Web模塊的WebContent/WEB-INFO/lib目錄下。如圖11所示:


    • 圖11:WSAD IE中為Web模塊添加庫
    • 步驟二:在Admin console中,將應用程序部署到WebSphere server上之后,進入Applications > Enterprise Applications,選擇相應的應用程序,并確認應用程序不在運行狀態(參見前面章節中選擇應用程序的步驟)。點擊進入應用程序,確認應用程序的類加載器的委托模式為Parent_First,應用程序的類加載器策略為Module。如圖12所示:

      圖12:WebSphere Admin Console中應用程序屬性配置頁面
    • 步驟三:在同一個頁面上,選擇 Web Modules,點擊進入。如圖13所示:

      圖13:WebSphere Admin Console中選擇應用程序Web模塊屬性
    • 步驟四:點擊相應的包含沖突jar包的Web模塊,設置Web模塊的類加載器的委托模式為Parent_Last。注意:在設置完成后要保存服務器配置,并啟動應用程序。如圖14所示:
      圖14:WebSphere Admin Console中為Web模塊指定類加載器委托模式
    • 將沖突jar包打包到Web模塊中,并設置相應Web模塊的類加載器的委托模式為Parent_Last,應用程序在運行過程中加載類的時候,這個Web模塊的類加載器會首先查找 WebContent/WEB-INFO/lib目錄下的jar包進行類的加載;而對于其它的Web模塊,由于其類加載器的委托模式仍然為缺省的Parent_First,它們的類加載器仍然首先從應用程序的共享庫或者WebSphere的共享路徑上加載jar包中的類,從而解決了jar包沖突的問題。
      命令行運行方式解決jar包沖突
      不論是設置共享庫,還是將沖突jar包打包到應用程序中,其解決的問題都是在應用程序的一個Web模塊中只使用了沖突jar包的一個版本的情況。我們在開發中曾經遇到過這樣的情況:應用程序的Web模塊中已經使用了1.4版本的xerces.jar,由于Web功能的擴展,在這個模塊中又引入一個新的第三方工具,而這個第三方工具需要使用2.0版本的xerces.jar才能正常工作,這種情況下的jar包沖突如何解決呢?
      在前面類加載器的部分已經介紹過,每個應用程序的一個Web模塊最多只能有一個類加載器,而Web模塊的類加載器中加載的類的生命周期為整個應用程序的運行期,也就是說,Web模塊加載器不可能同時加載一個類的兩個版本,同時,Web模塊的類加載器的委托模式也是在應用程序運行前設置的,在應用程序運行期內無法改變的,因此,上面描述的在一個Web模塊中同時使用兩個版本的jar包的問題,象前兩種方法那樣配置運行在一個JVM內的類加載器的設置的方法是無法解決的。
      唯一的解決辦法就是在應用程序運行的JVM外,啟動另外一個JVM來運行調用沖突jar包的代碼,因為兩個不同的JVM可以加載各自的類,從而解決jar包沖突問題。
      這種情況下,原來使用jar包的老版本的方式(包括jar包放置路徑,共享庫設置方式,類加載器的委托模式等)不變,將對jar包新版本的調用通過命令行運行方式實現。具體做法是:將對jar包新版本內功能的調用,封裝到一個可以單獨運行的類中,在Web模塊中以命令行方式運行這個類。同時把這個類以及jar包的新版本放在任意一個was可訪問的路徑上(比如/usr/WebSphere),在命令行的classpath參數中包含這個路徑(比如/usr/WebSphere)。
      下面通過舉例說明命令行運行方式的編程過程,在本例中,假設TestEar應用程序的Web模塊TestWar中,已經使用了conflict_v1.jar,由于新添功能需要使用conflict_v2.jar中的exampleCall()功能。
      沖突jar包conflict_v2.jar提供的功能:

      代碼1:沖突jar包conflict_v2.jar功能
      Package com.ibm.conflict public class ConflictClass{    …….Public static String exampleCall(string param){    String rs;    ……;    Return rs;}……}

      不存在沖突問題時的編碼舉例:
      如果沒有jar包沖突問題,則對這個功能的調用是簡單的,只需要將conflict_v2.jar放在應用程序自身或者其父類加載器的查找路徑上,然后在Web模塊中直接調用即可,如下:

      代碼2:不存在沖突時的調用方式
      Public String methodA(String param){   ……   String rs = ConflictClass.exampleCall(param);   ……   Return rs;}

      存在沖突后的命令行運行方式編碼舉例
      針對jar包沖突問題,我們需要在Web模塊中做如下的修改:
      • 步驟一:將沖突jar包放在was可訪問的路徑上,比如/usr/WebSphere/conflict_v2.jar。
      • 步驟二:將對包含沖突代碼的調用封裝到一組可單獨運行的類中,它們將調用沖突jar包的功能,并將結果以系統輸出的方式打印到系統標準輸出上。 將這些類封裝到一個單獨的jar文件中,比如workAroundConflict.jar,并將其放在was可訪問的路徑上,比如/usr/WebSphere/workAroundConflict.jar。
        Package com.ibm.test;Import com.ibm.ConflictClassublic class WorkAround{Public static void main(String[] args){    String param1=args[0];    String returnStr=ConflictClass.exampleCall ();    System.out.println("<RTStr>"+returnStr+"</RTStr>");    Return;}}


        代碼3:將對沖突代碼的調用寫入一個單獨的類WorkAround
      • 步驟三:在Web模塊中通過命令行方式調用封裝的類,通過classpath指定所有依賴的jar包和類路徑。運行封裝類,從系統標準輸出中取得運行結果。
        Public static String methodA (String param){    ……    String rtStr = "";    String lStr="<RTStr>";    String rStr="<RTStr>";    //put all the dependency jar here    String classPath="/usr/WebSphere/conflict_v2.jar; /usr/WebSphere/workaroundConflict.jar;……";    String className="com.ibm.test.WorkAround";    String cmdLine="java -classpath " +classPath +" " +className + " "+ param;    Try{        Processprocess = Runtime.getRuntime().exec(cmdLine,null);        process.waitFor();        BufferedReader br= new BufferedReader(                  new InputStreamReader(process.getInputStream()));        while ((s = br.readLine())!=null) {            if (null == out)                ut=s;            else                out+=s;}//get result from outif (null != out){    int lIndex = out.lastIndexOf(lStr);    int rIndex = out.lastIndexOf(rStr);    rsStr = out.substring(lIndex+lStr.length, rIndex);}    } catch (Exception e){        e.printStackTrace();}…….return rsStr;}


        代碼4:在應用程序中通過命令行方式運行WorkAround
      命令行運行方式通過啟動另外一個JVM的方式運行沖突代碼,在一個不同的JVM中加載沖突的類,從而解決了jar包沖突問題。
      但是命令行運行方式畢竟不是一個很好的方式,它存在以下的弊端:
      • 命令行運行方式只適用于對沖突jar包的使用只是運行一段代碼,或者只要求返回簡單的字符串結果的情況。對于復雜的交互,命令行方式無法做到。但是如果在別無他法的情況下,可以適當地劃分封裝對沖突代碼調用的jar包的包含范圍,盡量將命令行運行的代碼接口簡單化。
      • 命令行運行方式因為啟動了另外一個JVM來運行,降低了WebSphere的性能。
      因此,命令行方式只適用于一些極為特殊的情況下解決jar包沖突問題。
      結論
      本文對基于WebSphere的大型項目開發中遇到的jar包沖突問題,結合WebSphere中類加載器的概念,給出了三種解決辦法以及相應的操作步驟和實現代碼,并分析了各種方式所適用的具體情況。
      項目開發過程中的jar包沖突,主要存在以下三種情況:
      • 多個應用程序間的jar包沖突
      • 應用程序內多個Web模塊間的jar包沖突
      • 應用程序內同一個Web模塊內部jar包沖突
      通過對類加載器的分析我們知道,解決jar包沖突問題的根本在于合理配置類加載器。在深入理解WebSphere中類加載器的層次結構的基礎上,我們給出了"共享庫解決jar包沖突"以及"打包到Web模塊中解決jar包沖突"的辦法,通過合理地配置WebSphere中類加載器及其委托模式,可以解決大多數的jar包沖突問題。但是由于這個層次結構中類加載器只配置到Web模塊,因此,對于Web模塊內部的jar包沖突問題,類加載器的配置是無法解決的,為此我們給出了"命令行運行方式解決jar包沖突"的辦法。
      表2中列出了在不同的WAS版本下,三種解決jar包沖突問題的辦法所適用的jar包沖突情況。

      表2:Jar包沖突解決辦法適用的jar包沖突情況總結

    posted on 2010-08-19 16:42 junlin 閱讀(1363) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     

    導航

    <2010年8月>
    25262728293031
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    統計

    常用鏈接

    留言簿

    隨筆分類

    隨筆檔案

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 国产成人在线免费观看| 久久青草免费91观看| 久久夜色精品国产噜噜亚洲a| 亚洲另类古典武侠| 亚洲日本VA午夜在线电影| 黄色毛片免费观看| 国产情侣久久久久aⅴ免费| 免费涩涩在线视频网| 亚洲国产一区二区三区| 亚洲日韩一页精品发布| 亚洲综合色区中文字幕| 两个人看的www免费视频中文| 中文毛片无遮挡高潮免费| 免费无遮挡无码永久在线观看视频| 国产免费无遮挡精品视频| 亚洲乱理伦片在线观看中字 | 日韩免费观看一区| 亚洲大片在线观看| 亚洲熟妇无码一区二区三区| 成人A毛片免费观看网站| 69堂人成无码免费视频果冻传媒| 亚洲国产情侣一区二区三区| 免费观看黄网站在线播放| 亚洲永久无码3D动漫一区| 免费网站看av片| 亚洲人成电影在线观看青青| 免费无码不卡视频在线观看| 一级特黄特色的免费大片视频| 中文字幕无码视频手机免费看| 亚洲AV无码一区二区二三区软件| 特a级免费高清黄色片| 中字幕视频在线永久在线观看免费| 亚洲中文字幕久久精品无码A| 亚洲国产主播精品极品网红 | 91久久亚洲国产成人精品性色 | 亚洲永久网址在线观看| 伊在人亚洲香蕉精品区麻豆| 亚洲人成网站在线观看播放青青| 国产精品自在自线免费观看| 三级黄色片免费看| 亚洲国产精品网站在线播放|