Setting Maven for scripting languages?

1.3k views Asked by At

Maven is for building and managing any Java-based project. But what happens if a project is in a scripting language?

All maven can do now with TCL is copy the files around and put them in the right place in the target directory.

My problems are as follows:

  1. Code is in TCL-> need of an interpreter not of a compiler.
  2. It doesn't see any Java code, so it doesn't compile anything.
  3. It doesn't see any Java tests, so it doesn't run them.
  4. There's no java to run coverage against, so the jococo won't have anything to do.

Is there any way to set up maven for supporting a TCL project?

I've searched a lot in the internet and I found only 'jacl', but I don't really know how I can use it for setting up Maven.

3

There are 3 answers

3
Donal Fellows On BEST ANSWER

Tcl isn't closely integrated with Maven (unlike Java) so you'll have to do more work. To run a Tcl script from Maven, the simplest way is to use the Exec Maven Plugin, but you have to bind the executions to explicit lifecycle phases yourself instead of relying on defaults. For example, to run a script during the test phase (i.e., to do tclsh testscript.tcl anotherArgument), you use:

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <executions>
                <execution>
                    <id>run-tcl-tests</id>
                    <phase>test</phase>
                    <goals>
                        <goal>exec</goal>
                    </goals>
                    <configuration>
                        <executable>tclsh</executable>
                        <arguments>
                            <argument>testscript.tcl</argument>
                            <argument>anotherArgument</argument>
                        </arguments>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Maven's long-winded! Don't forget that you can probably put much of the complexity in a parent POM, and you can use properties and profiles to do interesting things.

You can also use the java goal to run Jacl or jTcl interpreters (in a sub-process). It depends on what exactly you want to do.

1
Mark O'Connor On

Unless you're using jTcl I don't see what Maven will do, apart from complicate your build process. Unless you understand Maven well and can develop some supporting plugins. As you've pointed out TCL is a scripting language, meaning your real challenge is a run-time deployment problem.

So, how would a TCL build process make deployment simpler? I would propose building RPM, Debian or MSI package for each targeted environment. These native installers can use dependency management to ensure the TCL interprertor is also installed. Another useful build option are starkits, which would bundle the TCL interpretor in a single file.

Once built, these binaries can be stored in your Maven repository (like jar files) and used as part of your deployment process. And finally don't forget you are not forced to use Maven as your build tool.

Disclaimer: Been a while since I've programmed with TCL, so hope this helps.

0
Jared On

It is very much "not the maven way" to make dependencies on external build tools outside the maven ecosystem. Linking to tclsh will break your builds if tclsh isn't available. Not saying I haven't done worse (sometimes you just have to get it done and forget "the maven way"). Fortunately, there is an alternative - jacl.

First download the latest (probably 1.4.1) prebuilt jacl binary zip file from sourceforge.

Next, unzip and go into the lib/tcljava1.4.1 subdirectory. There are four jar files here you need to publish to your local repository (or another repo you use):

mvn install:install-file -Dfile=tjc.jar -DgroupId=jacl -DartifactId=tjc -Dversion=1.4.1 -Dpackaging=jar
mvn install:install-file -Dfile=tcljava.jar -DgroupId=jacl -DartifactId=tcljava -Dversion=1.4.1 -Dpackaging=jar
mvn install:install-file -Dfile=jacl.jar -DgroupId=jacl -DartifactId=jacl -Dversion=1.4.1 -Dpackaging=jar
mvn install:install-file -Dfile=itcl.jar -DgroupId=jacl -DartifactId=itcl -Dversion=1.4.1 -Dpackaging=jar

You'll also need to add these as dependencies to the project where you're calling the tcl script:

<dependency>
    <groupId>jacl</groupId>
    <artifactId>itcl</artifactId>
    <version>1.4.1</version>
</dependency>
<dependency>
    <groupId>jacl</groupId>
    <artifactId>jacl</artifactId>
    <version>1.4.1</version>
</dependency>
<dependency>
    <groupId>jacl</groupId>
    <artifactId>tcljava</artifactId>
    <version>1.4.1</version>
</dependency>
<dependency>
    <groupId>jacl</groupId>
    <artifactId>tjc</artifactId>
    <version>1.4.1</version>
</dependency>

Then just call the tcl (or really jacl) script using the exec goal of the exec-maven-plugin, passing in the script file path as the first argument (customize the execution as necessary to bind to the proper phase, etc.):

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.3</version>
    <executions>
        <execution>
            <id>runTcl</id>
            <phase>process-resources</phase>
            <goals><goal>exec</goal></goals>
            <configuration>
                <executable>java</executable>
                <arguments>
                    <argument>-Dbasedir=${basedir}</argument>
                    <argument>-classpath</argument>
                    <classpath/>
                    <argument>tcl.lang.Shell</argument>
                    <argument>${basedir}/src/main/scripts/myScript.tcl</argument>
                </arguments>
            </configuration>
        </execution>
    </executions>
</plugin>

Update: Note that I had to use the "exec" goal above instead of the java goal. That's because jacl calls System.exit() in it's main function, so it kills the jvm. With this config, you can fail the build by using:

package require java
java::call System exit 1

From within your tcl code (or any exit value other than zero or other successCodes configured in the plugin). Hope that helps.