How does "data" attribute work in java_war and appengine_war
In an exploratory project I'm trying to run an Java application that serves some static resource. I tried to add static resources to the war file using the data attribute.
https://github.com/jiaqi/angular-on-java/blob/seattle/java/org/cyclopsgroup/aoj/server/BUILD
It seems the setting is effective and after some work files do end up in the war file as expected.
$ bazel build java/org/cyclopsgroup/aoj/server
INFO: Analyzed target //java/org/cyclopsgroup/aoj/server:server (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //java/org/cyclopsgroup/aoj/server:server up-to-date:
bazel-bin/java/org/cyclopsgroup/aoj/server/server.war
bazel-bin/java/org/cyclopsgroup/aoj/server/server_deploy.sh
bazel-bin/java/org/cyclopsgroup/aoj/server/server
...
$ jar -tvf bazel-bin/java/org/cyclopsgroup/aoj/server/server.war
94 Fri Jan 01 00:00:00 PST 2010 ./webapp/aoj/styles.css
5628103 Fri Jan 01 00:00:00 PST 2010 ./webapp/aoj/js_bundle.js
141 Fri Jan 01 00:00:00 PST 2010 ./webapp/aoj/styles.css.map
11413 Fri Jan 01 00:00:00 PST 2010 ./favicon.png
...
Then I ran the war target with bazel run and found that only favicon.png is served and none of the others is.
After reading appengine_runner.sh.template I realized the root directory of web application at runtime has nothing to do with the files in the war file.
bazel-out/darwin-fastbuild/bin/java/org/cyclopsgroup/aoj/server/server.runfiles/angular_on_java/java/org/cyclopsgroup/aoj/server
├── WEB-INF
│ ├── appengine-generated
│ │ └── local_db.bin
│ ├── appengine-web.xml -> /Users/jguo/github/jiaqi/angular-on-java/java/org/cyclopsgroup/aoj/server/WEB-INF/appengine-web.xml
│ ├── jsp
│ │ └── index.jsp -> /Users/jguo/github/jiaqi/angular-on-java/java/org/cyclopsgroup/aoj/server/WEB-INF/jsp/index.jsp
│ └── lib
│ ├── appengine-api.jar -> /private/var/tmp/_bazel_jguo/239a5101fa986e10f8c504b3e6b8e624/execroot/angular_on_java/bazel-out/darwin-fastbuild/bin/java/org/cyclopsgroup/aoj/server/server.runfiles/angular_on_java/../com_google_appengine_java/lib/impl/appengine-api.jar
...
├── server -> /private/var/tmp/_bazel_jguo/239a5101fa986e10f8c504b3e6b8e624/execroot/angular_on_java/bazel-out/darwin-fastbuild/bin/java/org/cyclopsgroup/aoj/server/server
└── server.war -> /private/var/tmp/_bazel_jguo/239a5101fa986e10f8c504b3e6b8e624/execroot/angular_on_java/bazel-out/darwin-fastbuild/bin/java/org/cyclopsgroup/aoj/server/server.war
4 directories, 31 files
None of the webapp/aoj/* files we saw in the war file exists under runfiles. With file structure like this in runfiles, the running application actually serves server.war by mistake.
Unless I miss anything, this doesn't make sense to me at all. What the data attribute specifies is correctly honored when creating a war file, but completely ignored when running it. Is it by design? What's the right way to specify data attribute so it matters at runtime?
Looks like the referenced data files are under the working directory(.../server.runfiles), but not under the webapp root directory, which is the directory that matters at runtime. To fix it I think there are 2 options
- Link data files to webapp root directory in appengine_runner.sh.template similar to how it links jar files to WEB-INF/lib
- Use working directory(.../server.runfiles) as webapp root directory and link jars and other resources accordingly.
Does it make sense?