Search code examples
warbazel

Bazel war file has invalid './' directory


I am able to export to .war file from eclipse and run it on Tomcat. However, when I build it using Bazel, the .war file generated doesn't run on Tomcat.

Project structure

project
|_src
|   |_main/java/*.java
|
|_WebContent
       |_META-INF
            |_Manifest.mf
       |_WEB-INF
            |_lib/*.jar
            |_web.xml

War file exported from eclipse (and working) looks like this:

 inflated: META-INF/MANIFEST.MF
 inflated: .DS_Store
  created: META-INF/
  created: WEB-INF/
  created: WEB-INF/classes/
  created: WEB-INF/classes/main/
  created: WEB-INF/classes/main/java/
 inflated: WEB-INF/classes/main/java/.DS_Store
 inflated: WEB-INF/classes/main/java/foo.class
 inflated: WEB-INF/classes/main/.DS_Store
 inflated: WEB-INF/classes/.DS_Store
 inflated: WEB-INF/.DS_Store
  created: WEB-INF/lib/
 inflated: WEB-INF/lib/.DS_Store
 inflated: WEB-INF/lib/jersey-bundle-1.19.jar
 inflated: WEB-INF/web.xml

When I create a .war with Bazel, I get this:

 created: ./
  created: ./WEB-INF/
  created: ./WEB-INF/classes/
  created: ./WEB-INF/classes/main/
  created: ./WEB-INF/classes/main/java/
 inflated: ./WEB-INF/classes/main/java/.DS_Store
 inflated: ./WEB-INF/classes/main/java/foo.class
  created: ./WEB-INF/lib/
 inflated: ./WEB-INF/lib/jersey-bundle-1.19.jar
 inflated: ./WEB-INF/web.xml

I am customizing .bzl file to get the war file with the below code:

def _war_impl(ctxt):
  zipper = ctxt.file._zipper 
  data_path = ctxt.attr.data_path

  war = ctxt.outputs.war
  build_output = war.path + ".WEB-INF"
  print("build_output = %s" % (build_output))
  cmd = [
      "set -e;rm -rf " + build_output,
      "mkdir -p %s" % build_output
      ]

  inputs = ctxt.files.jars + [zipper]
  cmd += ["mkdir -p %s/WEB-INF/lib" % build_output]
  cmd += ["mkdir -p %s/WEB-INF/classes/main/java" % build_output]

Could anyone point out how to build using 'mkdir' so that it doesn't create './' directory in the war file?


Solution

  • Turns out the issue was in the command that Bazel file (I created a custom .bzl rule similar to the appengine bazel rule) uses to zip up the files with:

    def _make_war(zipper, input_dir, output):
      return [
          "(root=$(pwd);" +
          ("cd %s &&" % input_dir) +
          ("${root}/%s Cc ${root}/%s $(find .))" % (zipper.path, output.path))
          ]
    

    The $(find .) was returning ./WEB-INF, so when I changed it to $(find WEB-INF) it returned a .war file without './' directory, which then ran on Tomcat.