Search code examples
deploymentclojurewaramazon-elastic-beanstalkring

Clojure/Ring: How can I integrate my clojure app with a java build process that is out of my control?


I have a unique build situation. I am using lein uberwar to build a war out of my ring application and deploy to beanstalk. This is all working great. Now it comes up as a requirement that we need to push code to an svn repo where they will manage the build, which knows nothing about clojure (only java). It is a huge bureaucratic organization and their build process is already in place, so having them install lein on their servers is currently out of the question. I know that lein uses maven underneath the hood so I know this could work in theory, yet I am still in doubt on a couple steps of this process.

I went through the war-building process in lein-ring and the main hangups I see are that the servlet and listener classes are generated, along with the web.xml. I feel like I could provide java files that do this task, but am unclear on what those java files would contain and where they would ultimately live inside the structure of the project. Looking at the servlet.clj and listener.clj files that get generated in the ultimate war they seem very simple, possibly examples already exist for this?

The other big hurdle I see is that the war process calls clojure.core/compile on the project namespace, which generates all the class files from the clojure source. Is there some way to trigger this compilation during the build from maven? I am almost imagining a java class that farms out compilation to clojure.core/compile, but I am not sure of the ins and outs of calling clojure from java, rather than vice versa (the usual direction of flow), or how to insert this step into a basic maven build process.

Any insights into where to start on any of this would be most welcome! Thanks all.


Solution

  • Check out the Zi maven plugin. you specify it as a plugin in your sub-project's pom.xml and then it fills the same roll that the javac plugin does in the rest of the project. nobody outside of your project need even know that Clojure exists.

    check out the readme for details

     <build>
      <plugins>
        <plugin>
          <groupId>org.cloudhoist.plugin</groupId>
          <artifactId>zi</artifactId>
          <version>0.5.5</version>
          <executions>
            <execution>
              <id>default-compile</id>
              <goals>
                <goal>compile</goal>
              </goals>
            </execution>
          </executions>
          <configuration>
            <excludes>
              <exclude>**/test.clj</exclude>
            </excludes>
          </configuration>
        </plugin>
      </plugins>
    </build>