title: Certificate not found in test with EjbContainer and GlassFish
body: <p>I have an EJB that communicates with a site over https. The logic is to send a xml file in request and receive another in response. This works fine in development environment after adding the site certificate to cacerts inside GlassFish domain. The problem appears when the communication happens in test environment with EJBContainer. Even with <strong>org.glassfish.ejb.embedded.glassfish.installation.root</strong> and <strong>org.glassfish.ejb.embedded.glassfish.instance.root</strong> properties defined and certificate added to cacerts, the test execution ends with: </p>
  
  <pre><code>sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
  </code></pre>
  
  <p>My EJB is implemented as follows:</p>
  
  <pre><code>@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;
          }
      }
  }
  </code></pre>
  
  <p>My test configuration uses TestNG 6.8.5, GlassFish 3.1.2.2 and EJBContainer. The configuration starts creating another domain in GlassFish to avoid port conflicts with the default domain if it running. To do that, I've run the command:</p>
  
  <pre><code>asadmin create-domain --portbase 9100 domain-test
  </code></pre>
  
  <p>I've defined a super class with an annotated method with <code>@BeforeSuite</code> that starts the embedded container with the following content:</p>
  
  <pre><code>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();
      }
  }
  </code></pre>
  
  <p>In the test class, I've did a look up for my EJB and calls the logic that communicates with the site over https:</p>
  
  <pre><code>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);
      }
  }
  </code></pre>
  
  <p>I found a bug related to this problem in GlassFish Jira:
  <a href="https://java.net/jira/browse/GLASSFISH-17179" rel="nofollow">https://java.net/jira/browse/GLASSFISH-17179</a>, and as the EJBContainer is based on domain-test and the certified is installed in cacerts from this domain, I think that can be a problem of copy the cacerts defined on instance root property to the temporary directory created on embedded container start time.</p>
  
  <p>How can I lead with that?</p>