2013-08-19 59 views
1

我有一個通過https與站點通信的EJB。邏輯是在請求中發送一個xml文件並接收另一個響應。在向GlassFish域內的cacerts添加站點證書後,這在開發環境中可以正常工作。使用EJBContainer在測試環境中進行通信時會出現問題。在EjbContainer和GlassFish測試中找不到證書

:即使 org.glassfish.ejb.embedded.glassfish.installation.rootorg.glassfish.ejb.embedded.glassfish.instance.root屬性中定義和證書添加到cacerts中,測試執行結尾
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 

我的EJB實現如下:

@Stateless 
@LocalBean 
public class CommunicationService { 
    public String communicate() { 
     try { 
      URL url = new URL("https://www.comprasnet.gov.br/XML/treinamento/consultamatserv.asp"); 
      HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 

      conn.setDoOutput(true); 
      conn.setRequestMethod("POST"); 

      OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream()); 

      writer.flush(); 

      String line; 
      BufferedReader reader = new BufferedReader(new InputStreamReader(
     conn.getInputStream())); 

      StringBuilder resposta = new StringBuilder(); 
      while ((line = reader.readLine()) != null) { 
       resposta.append(line); 
      } 

      writer.close(); 
      reader.close(); 

      return resposta.toString(); 
     } catch (Exception e) { 
      return null; 
     } 
    } 
} 

我的測試配置使用TestNG的6.8.5,GlassFish的3.1.2.2和的EJBContainer。配置開始在GlassFish中創建另一個域,以避免在運行時與默認域發生端口衝突。爲了做到這一點,我已經運行以下命令:

asadmin create-domain --portbase 9100 domain-test 

我定義與註釋的方法的超類@BeforeSuite以下列內容開始嵌入容器:

public abstract class GlassfishEmbeddedBaseTest { 

    protected Context ic; 

    protected UserTransaction tx; 

    private static EJBContainer ejbContainer; 

    @BeforeSuite 
    protected void beforeSuite() throws Exception { 
     String glassfishHome = System.getenv("GLASSFISH_HOME"); 

     Properties properties = new Properties(); 
     properties.put(EJBContainer.MODULES, new File[] { new File(
      "target/classes") }); 

     properties.put("org.glassfish.ejb.embedded.glassfish.installation.root", 
      glassfishHome + "/glassfish"); 
     properties.put("org.glassfish.ejb.embedded.glassfish.instance.root", 
      glassfishHome + "/glassfish/domains/domain-test"); 

     properties.put(EJBContainer.APP_NAME, "app-name"); 

     ejbContainer = EJBContainer.createEJBContainer(properties); 
    } 

    @BeforeClass 
    protected void load() throws Exception { 
     ic = ejbContainer.getContext(); 
    } 

    @BeforeMethod 
    protected void beforeMethod() throws Exception { 
     tx = (UserTransaction) ic.lookup("java:comp/UserTransaction"); 
     tx.begin(); 
    } 

    @AfterMethod 
    protected void rollBack() throws Exception { 
     tx.rollback(); 
    } 
} 

在測試類,我已經做了一個查找我的EJB,並調用與該網站通過HTTPS通信的邏輯:

public class CommunicationServiceTest extends GlassfishEmbeddedBaseTest { 

    private CommunicationService communicationService; 

    @BeforeClass 
    public void init() throws NamingException { 
     communicationService = (CommunicationService) ic 
      .lookup("java:global/app-name/classes/CommunicationService"); 
    } 

    @Test 
    public void testCommunicate() { 
     String response = communicationService.communicate(); 

     Assert.assertNotNull(response); 
    } 
} 

我發現有關GlassFish中吉拉這個問題的錯誤: https://java.net/jira/browse/GLASSFISH-17179,並且由於EJBContainer基於域測試並且認證安裝在來自此域的cacerts中,我認爲這可能是將實例root屬性上定義的cacerts複製到在嵌入容器啓動時創建的臨時目錄的問題。

我該如何領導呢?

回答

1

提供的EJBContainer一個屬性命名org.glassfish.ejb.embedded.glassfish.instance.reuse決定:

如果爲true,不更改現有的配置文件進行,暫時的服務器 實例不是爲嵌入式運行創建的。相反,執行是針對現有的服務器實例進行的。如果正在運行的GlassFish服務器可能正在使用重用的服務器實例,請勿使用此選項。

添加這個屬性值爲true,之前創建的EJBContainer,解決了這個問題,因爲該證書已添加到cacerts中域域測試,並沒有被複制到臨時文件夾了。