3

I've been having some problems with a WAR module and its difficulty in loading a taglib. I kept getting this exception:

JSPG0047E: Unable to locate tag library for uri http://www.springframework.org/tags/form 
    at com.ibm.ws.jsp.translator.visitor.tagfiledep.TagFileDependencyVisitor.visitCustomTagStart(TagFileDependencyVisitor.java:76)
    at com.ibm.ws.jsp.translator.visitor.JspVisitor.processJspElement(JspVisitor.java:366)
    at com.ibm.ws.jsp.translator.visitor.JspVisitor.processChildren(JspVisitor.java:419)
    at com.ibm.ws.jsp.translator.visitor.JspVisitor.processJspElement(JspVisitor.java:369)
...

After a bit of searching, I found a lot of suggestions that the spring jars need to be on the application's classpath. I checked in my EAR's lib folder and sure enough, spring-web and spring-webmvc were there.

It should be noted that the EAR is built with skinny WARs - since they use most of the same libraries, all library files are in MyAppEAR/lib instead of MyAppEAR/MyWAR1/WEB-INF/lib, MyAppEAR/MyWAR2/WEB-INF/lib, MyAppEAR/MyWAR3/WEB-INF/lib, etc...

I did finally manage to resolve this missing taglib error, but I had to move spring-web and spring-webmvc to MyAppEAR/MyWAR1/WEB-INF/lib.

So I have a couple of questions:

  1. Is this the only way to fix this problem?
  2. If so, how can I build a sort-of skinny WAR using maven? Currently, the EAR part of the POM looks like this:

    <plugin>
      <artifactId>maven-ear-plugin</artifactId>
      <version>2.8</version>
      <configuration>
        <applicationName>MyAppEAR</applicationName>
        <defaultLibBundleDir>lib</defaultLibBundleDir>
        <skinnyWars>true</skinnyWars>
    

I guess I could turn off skinny WARs and then have some other step remove all libraries from the WAR files and copy them to MyAppEAR/lib except for the spring web jars, but I am hoping there's a better solution.

Martin Höller
  • 2,714
  • 26
  • 44
FrustratedWithFormsDesigner
  • 26,726
  • 31
  • 139
  • 202
  • 1
    Great question. I have the same problem when running a Selenium test against Jetty (instantiated programmatically) from within JUnit. I feed Jetty 'src/main/webapp', where it expects to find these libraries. Just being on the classpath (these libraries are put on the classpath by Maven) seems not enough. – Sander Verhagen Nov 06 '13 at 06:38
  • @SanderVerhagen: Maybe this relates to your problem with Jetty: http://stackoverflow.com/questions/6020495/embedded-jetty-fails-to-load-jsp-taglibs-when-classpath-specified-in-jar – FrustratedWithFormsDesigner Nov 06 '13 at 15:00
  • This is a very good question. I'm asking myself if skinny WARs are still a good solution as they tend to make problems. See [this question/answer](http://stackoverflow.com/questions/2987266/why-doesnt-jsf-2-0-ri-mojarra-scan-my-class-annotations) for the reason why some JARs have to live in `WEB-INF/lib`. – Martin Höller Feb 27 '14 at 07:50

2 Answers2

1

I had the same issues myself - I just couldn't access Spring or Sitemesh's TLDs when my spring JAR files were in my ear/lib folder!

Including the classpath in the MANIFEST was causing my app server go haywire (since all dependencies were being loaded twice).

(Yes, I also have skinnyWars set to true in my maven-ear-plugin).

The only way I could have gone round the issue was by including Spring and sitemesh by including them in maven-war-plugin's configuration:

<packagingExcludes>%regex[WEB-INF/lib/(?!spring|sitemesh).*.jar]</packagingExcludes>

Not the most elegant solution, but the least damaging I could find.

This is my full configuration:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.1.1</version>
            <configuration>

                <!--
                Q. Why is this set?
                A. maven-ear-plugin in our EAR modules have `skinnyWars` enabled to that WAR files 
                   would not include any third-party libraries in the WAR's WEB-INF/lib folder, however 
                   this does not work for ejbs (like our own EJB modules).

                   We'll need to exclude them from here anyway (except for a few select JARS)...
                -->                 
                <packagingExcludes>%regex[WEB-INF/lib/(?!spring|sitemesh).*.jar]</packagingExcludes>

                <archive>
                    <manifest>
                        <addClasspath>false</addClasspath>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

PS. My setup is JBoss EAP 6.x and an ear file with several EJBs, WARs and third-party JARs.

Matthew Cachia
  • 4,474
  • 1
  • 13
  • 17
0

I think I got it working.

In the WAR's POM file:

<plugin>
  <artifactId>maven-war-plugin</artifactId>
    <version>2.2</version>
    <configuration>
      <warSourceDirectory>src/main/webapp</warSourceDirectory>
      <packagingExcludes>WEB-INF/lib/*.jar,WEB-INF/*.xmi</packagingExcludes>
      <archive>
        <manifest>
             <addClasspath>true</addClasspath>
             <classpathPrefix>../../WEB-INF/lib/</classpathPrefix>
       </manifest>
      </archive>
    </configuration>
</plugin>

This causes the generated WAR file to have a META-INF/MANIFEST.MF file with classpath entries that look like ../WEB-INF/lib/$someJarFile - that is the relative path from the WAR to the EAR's library folder. I guess the WAR needs to have the classpath specified, having the libraries in the EAR just isn't enough.

FrustratedWithFormsDesigner
  • 26,726
  • 31
  • 139
  • 202
  • 1
    While your suggestion migth work, I would consider it a hack. The war won't deploy anymore if it is outside the EAR. That's why [the maven wiki](http://docs.codehaus.org/display/MAVENUSER/Solving+the+Skinny+Wars+problem) suggests fixing this in the EAR plugin and that's why the EAR plugin got the [`skinnyWars` parameter](https://maven.apache.org/plugins/maven-ear-plugin/ear-mojo.html#skinnyWars). So IMHO the problem should be fixed on the EAR side rather than on the WAR side. Unfortunately I can't provide a better solution for now :( – Martin Höller Feb 27 '14 at 07:53
  • @MartinHöller: I agree, I don't really like it much. We've had better luck with new EAR projects on newer versions of WebSphere. It was mostly just this one legacy project which has been giving problems. – FrustratedWithFormsDesigner Feb 27 '14 at 14:48