Friday, April 24, 2015

Manifest Dependencies (Arquillian ShrinkWrap) in Wildfly using Infinispan

Troubled almost half a day by this issue. Should be helpful for all using Arquillian, ShrinkWrap, Infinispan on Wildlfly.

Caused by: javax.ejb.EJBException: java.lang.IllegalArgumentException: 
Can not set org.infinispan.manager.CacheContainer 
field com.psl.radia.gw.cache.manager.CacheManager.cacheContainer 
to org.jboss.as.clustering.infinispan.DefaultCacheContainer

Caused by: java.lang.IllegalArgumentException: 
Can not set org.infinispan.manager.CacheContainer 
field com.psl.radia.gw.cache.manager.CacheManager.cacheContainer 
to org.jboss.as.clustering.infinispan.DefaultCacheContainer


These are the list of steps to be followed to resolve this:

1. Add the MANIFEST.MF to src/test/resources with this content [MANIFEST.MF]
Dependencies: org.infinispan export 

2. Modify the standalone.xml or standalone-full.xml [WILDFLY/INFINISPAN]
Your standalone-full.xml will already have the following entry
<subsystem xmlns="urn:jboss:domain:ee:2.0">
...
</subsystem>

Add the following within the <subsystem> tags:
<global-modules> 
    <module name="org.infinispan" slot="main"/>
</global-modules>

3. To the Test Case/Deployment, Add the following  [ARQUILLIAN]
WebArchive res = ShrinkWrap.create(WebArchive.class, "test.war");        
...
res.addAsManifestResource("MANIFEST.MF");


This is the ONLY way to achieve this, though you may find suggestions all over that require you to change the pom.xml (maven-jar-plugin, maven-ejb-plugin,maven-war-plugin) or that suggest the use of adding the string (Dependencies: org.infinispan export) directly to the MANIFEST.MF created by Arquillian Test Case. 

Saturday, April 18, 2015

JAR File Dependencies (Internal References/Class-Path)

Most often, you end up in the following issue - where you want to refer to a JAR inside another JAR. Many developers would assume that by adding it to the Class-Path within MANIFEST.MF, it should be included in the classpath. But this does not work.

test.jar
|  /META-INF
|  |     MANIFEST.MF
|  |        Main-Class: com.persistent.accelerite.main.AppLauncher

|  |        Class-Path: commons-logging.jar
|  /com/persistent/accelerite/main
|  |     AppLauncher.class
|  commons-logging.jar


This may be very surprising or something that will be away from your strongest belief/intuition - But this will not work! You have to extract the required JARs and put them at the same level or same directory as the directory where test.jar is located. In the above class, trying to use jar:file:jarname.jar!/commons-logging.jar in the Class-Path will also not work. The only other way to achieve this is to write Custom Class Loaders.

This is as per the Java Archive Specification.  From the official Oracle Documentation is as follows:

Class-Path:
The value of this attribute specifies the relative URLs of the extensions or libraries that this application or extension needs. URLs are separated by one or more spaces. The application or extension class loader uses the value of this attribute to construct its internal search path.

Wednesday, April 15, 2015

Debugging using Wildfly and Arquillian

This should be most useful for those starting out with Arquillian! I spent quite some time before finding out the solution.

The arquillian.xml should include the following contents:
 <engine>  
     <property name="deploymentExportPath">target/</property>  
   </engine>  
   <container qualifier="jbossas-managed-wildfly-8" default="true">  
        <protocol type="jmx-as7">  
       <property name="executionType">REMOTE</property>  
     </protocol>  
     <configuration>  
          <property name="allowConnectingToRunningServer">true</property>  
       <property name="jbossHome">C:\Program Files (x86)\PSL\RCA\ApplicationServer</property>  
       <property name="modulePath">C:\Program Files (x86)\PSL\RCA\ApplicationServer\modules</property>  
       <property name="javaVmArguments">-Xrunjdwp=transport=dt_socket,address=8000,server=y,suspend=n -Djava.util.logging.manager=org.jboss.logmanager.LogManager</property>  
     </configuration>  
   </container>  


Include the following profile in your Maven pom.xml,
  <profile>  
   <id>arquillian-wildfly-managed</id>  
   <activation>  
        <activeByDefault>true</activeByDefault>  
        </activation>    
   <dependencies>  
      <dependency>  
        <groupId>org.jboss.spec</groupId>  
        <artifactId>jboss-javaee-6.0</artifactId>  
        <version>3.0.1.Final</version>  
        <type>pom</type>  
        <scope>test</scope>  
      </dependency>  
      <!-- Required by jboss-javaee-6.0:3.0.2.Final (https://issues.jboss.org/browse/JBBUILD-708) -->  
      <dependency>  
        <groupId>xalan</groupId>  
        <artifactId>xalan</artifactId>  
        <version>2.7.1</version>  
        <scope>test</scope>  
      </dependency>  
      <dependency>  
        <groupId>org.wildfly</groupId>  
        <artifactId>wildfly-arquillian-container-managed</artifactId>  
        <version>8.1.0.Final</version>  
        <scope>test</scope>  
      </dependency>  
      </dependencies>  
   </profile>  

When we use Arquillian, there are three VM's that are involved:
1. Arquillian (Source) > Remote/Managed Server
Start the Remote/Managed Server with the following line added to standalone.conf.bat
 set "JAVA_OPTS=%JAVA_OPTS% -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n"  

In Eclipse, Right Click on your project and Click on "Debug" and under "Connect" - Select your "Host" and "Port". Click on "Apply" and "Debug". This will connect the Debugger to the Remote VM inside Wildfly. 

2. Test > Remote/Managed Server
Now, Right Click on your Arquillian Test and Click on "Debug As.." or "Debug Configurations". Then select either "TestNG" or "JUnit". 

Now, you will be able to hit the breakpoint. Happy Debugging!