How to exclude specific class files from WAR without breaking providedCompile?


(Dave Sperry) #1

Hi, I’m new to Gradle and am trying to port an existing ant build system to Gradle. In a few of our sub projects we need to use JNI to access legacy code. In our ant build system we would put pure java code in the WAR and the JNI code in a separate jar that would be deployed to the lib folder of our application server (Jboss 6.10). I am trying to do the same thing with Gradle, but I am running into some trouble. When I do the standard exclude:

// This project depends on 2 without JNI and one that has JNI
dependencies {
  compile project(':project1')
  compile project(':project2')
  // This jar contains JNI and must not be in the WAR
  providedCompile (project(path: ':projectWithNative', configuration: 'nativeJar')){ transitive = false }
  compile 'org.jboss.spec.javax.jms:jboss-jms-api_1.1_spec:1.0.0.Final'
}
    // Attempt to exclude class files that must not be in WEB-INF/classes
// This seems to break providedCompile functionality in the war plugin
war {
 classpath = configurations.runtime
   webInf {
  into('classes') {
   from sourceSets.main.output
   exclude('**/*Jni.class')
   exclude('**/LoadLibrary.class')
  }
 }
}

The classes are removed from the war file BUT unfortunately, the JAR file from the providedCompile is included in the WAR file.

If I remove the classpath statement, then the providedCompile properly excludes its JAR, but the offending classes return.

In the end I need all the JNI related classes and JARs excluded from the WAR. How do I exclude both from the WAR file?

I am using gradle 1.1 on both win64 and Linux -Thanks


(Peter Niederwieser) #2

I can’t tell offhand what’s going on here, but what’s the purpose of the JNI-related classes in the War project? Can you get rid of them? If they need to stay, I’d exclude them from the source set, unless they serve a purpose I’m not aware of.


(Dave Sperry) #3

Hi, This as a combination Java and War project. We have multiple services on JBOSS that access the same shared native libraries. In order to avoid class loader conflicts, our source in src/main/java needs to produce 2 outputs. 1) A WAR file with just pure java classes that do not interact directly with JNI/native shared libraries. The classes and jars in this war file are loaded by a JBOSS class loader at deploy time and are scoped to just the individual service. 2) A JAR file with just the classes that interact with the JNI/shared libraries. The classes in this JAR must be loaded by the JBOSS classloader that loads classes into memory before WARs are deployed.

Our services fail to deploy if any JNI class is loaded via the WAR deployment class loader.

If I manually remove the offending class files or JARs from the WAR files, the services work fine.

Thanks


(Peter Niederwieser) #4

Maybe you could declare a separate source set for the native classes and add them only to the Jar. It’s always easier to selectively add things than to add everything and then remove parts of it.

Regarding your solution, I wonder how adding another ‘into(classes)’ (in addition to what’s added by the War plugin) will help to remove some classes. Have you tried with a global ‘war.exclude’?