2
votes

I want to update content inside all script tags in jsp files present under src/main/webapp/jsp. How to do this during maven build phase?

I am using java+spring+maven stack.

Ok here is example of what I want to achieve:

Source code:

<%@ page contentType="text/html; charset=utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"  %>
<script type="text/javascript" src="js/core/validator.js"></script>
<script type="text/javascript" src="js/app/util/core-util.js"></script>
<div id="dataContainer">
</div>

After maven build, this should be present in target folder

<%@ page contentType="text/html; charset=utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"  %>
<script type="text/javascript" src="js/core/validator.js?version='<MD5SUM-of-js/core/validator.js>'"></script>
<script type="text/javascript" src="js/app/util/core-util.js?version='<MD5SUM-of-js/app/util/core-util.js>'"></script>
<div id="dataContainer">
</div>

Please note the version parameter at the end of src="".

Update: Finally, I was able to make it work following way. Feel free to suggest alternative if any.

  1. Prepared shell script to generate properties file something like this

    js/core/validator.js=js/core/validator.js?version\=MD5SUM-of-js/core/validator.js
    js/app/util/core-util.js=js/app/util/core-util.js?version\=MD5SUM-of-js/app/util/core-util.js

  2. Configured maven-replacer-plugin to use this properties file as token value map and filter all the jsp files present under target/app/jsp folder.

3
voting to reopen - even if the question was originally asking for "tool or plugin", plugins are maven core features as is the filtering of resources. basically OP seems to be asking "how to do this in maven", which is on-topic for SO. - eis
so can you manually write the md5sum of those files into pom.xml, or do you expect it to be counted on every build? if the latter, the main task is counting it first and getting that into a maven property. that might be tricky. - eis
I want the latter. I already have one shell script to count md5 of all js and css files in my project. - TechnoCrat
maven has plugins to do the same, which would not be environment specific like shell scripts are. but main problem with both plugin and shell script approach is getting the result into a maven property. But thanks for the clarification, I'll update my answer then... - eis
well, it's your choice, I personally would've used filtering - but you can add your own solution as an answer and accept that. - eis

3 Answers

4
votes

You didn't tell what kind of replacement you need, but...

For lot of the cases, you can just use regular maven resources plugin and turn filtering on. That way it will replace any ${values} with maven runtime properties.

Documentation about the plugin

For .jsps, you are possibly already using war plugin. With war plugin it is something like

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.2</version>
        <configuration>
            <webResources>
                <resource>
                    <filtering>true</filtering>
                    <targetPath>WEB-INF</targetPath>
                    <directory>src/main/resources/WEB-INF</directory>
                    <includes>
                        <include>*.jsp</include>
                    </includes>
                </resource>
            </webResources>
        </configuration>
    </plugin>

Then you'd have something like this in your JSPs:

<script src="${mypath}/test.js"></script>

And in maven pom:

<properties>
   <mypath>testpath</mypath>
</properties>

Depending on your project configuration. (src/main/webapp is often used as well, for example)


Edit: you have added in the comments that you have a shell script counting md5 and you want to use that. I don't know an elegant way of doing that, so suggesting a less elegant way: use groovy plugin to execute the script and get the value to a property.

<plugin>
    <groupId>org.codehaus.gmaven</groupId>
    <artifactId>gmaven-plugin</artifactId>
    <version>1.5</version>
    <executions>
        <execution>
            <phase>validate</phase>
            <goals>
                <goal>execute</goal>
            </goals>
            <configuration>
                <providerSelection>2.0</providerSelection>
                <properties>
                    <script>path/to/your/shell-script.sh</script>
                </properties>
                <!-- if the script prints its result to stdout -->
                <source>
                    def command = project.properties.script
                    def process = command.execute()
                    process.waitFor()

                    def result = process.in.text.trim()
                    project.properties.md5Value = result
                </source>
                <!-- if the script prints the result to a file -->
                <!-- note that you have to define this result file name somewhere -->
                <source>
                    def command = project.properties.script
                    def process = command.execute()
                    process.waitFor()

                    def resultfile = new File(project.properties.result_file)
                    project.properties.md5Value = resultfile.getText()
                </source>
                <!-- only use one or the other script block! -->
            </configuration>
        </execution>
    </executions>
</plugin>
1
votes

if the only thing you want is to add a checksum to your ?version=xxx and it does not need to be a result of your custom shell script, you can use maven-antrun-plugin and its checksum target in conjunction with resource filtering.

The JSP snippet:

<!-- WEB-INF/jsp/template/thePage.jsp -->
<script type="text/javascript" src="${jsDir}/awesomeScript.js?version=${md5.awesomeScript}"></script>

Antrun plugin snippet:

<!-- pom.xml -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
  <execution>
    <phase>validate</phase>
    <goals>
      <goal>run</goal>
    </goals>
    <configuration>
      <target>
        <checksum file="${jsDir}/awesomeScript.js" property="md5.awsomeScript"/>
      </target>
      <exportAntProperties>true</exportAntProperties>
    </configuration>
  </execution>
</executions>

And finally the resources plugin snippet:

<!-- pom.xml -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
  <execution>
    <goals>
      <goal>copy-resources</goal>
    </goals>
    <phase>generate-sources</phase>
    <configuration>
      <resources>
        <resource>
          <directory>${project.basedir}/war/WEB-INF/jsp/template</directory>
          <targetPath>${project.basedir}/war/WEB-INF/jsp</targetPath>
          <includes>
            <include>*.jsp</include>
          </includes>
          <filtering>true</filtering>
        </resource>
      </resources>
    </configuration>
  </execution>
</executions>

The checksum target of the antrun plugin should calculate the checksum and expose it in the ${md5.awesomeScript} property.

The resources plugin comes in a later phase and copies all the .jsp files from the WEB-INF/jsp/template folder to the /jsp root, filtering the maven properties.

So, you should end up with a jsp file where the ?version=${md5.awesomeScript} is enhanced with the formerly generated checksum.

The snippets I included are just, well, snippets. You might need to provide some further configuration in order for the code to work.


In case you HAVE to calculate the MD5 in your custom shell script, I'd suggest extending the script so it does the find-replace-copy for you and using the maven exec plugin to run it.


Hope this helps a little! :-)

1
votes

can i ask you how you did it at last? can i did it without "?version=''" like this

source:
<script type="text/javascript" src="js/core/validator.js"></script>
after build:
<script type="text/javascript" src="js/core/validator.js?version=xxxx"></script>