When building a war file using the War task and the <lib> element, the files specified by the <lib> should be automatically flattened as they are added to the WAR file. There is no reason to put a jar under WEB-INF/lib except to have it included in the servlet classpath, but only files exactly inside WEB-INF/lib will be added. In my build environment, I'm collecting a number of jar files spread over a few different directories; the names of the JARs will be unique, but they are buried one level deep (a structure based on the maven group id of the JAR). Currenlty, I have to copy and flatten the files to a single directory and include that. This is somewhat haphazard I think and should be rolled directly into the task.
Can't you use a mapper to flatten things if that is what you want?
Unless I'm missing something (entirely possible), the <mapper> functionality is part of the Copy task, not the FileSet type. The <lib> element of the War task is a FileSet.
Right, no mapper, and no obvious/intuitive way to include one. It's been a while since I've done webapps, WARs and so on, but I can't find any evidence that files stored in subdirectories of WEB-INF/lib would be used for anything. I think this may end up an entry in WHATSNEW under "Changes that could break older environments:" i.e. a bug for which our correct response is to break BC (highly unlikely in this case but theoretically so).
<mapper> is a generic concept. If <war/> does not support mappers in the different locations it should. I suggest you ask for them to be added. But to request that <war/> be changed to start flattening is unreasonable. There is no reason why my libraries cannot beorganized in several directories. Even after deployment. Having a mapper will allow user to do whatever they may want. Actually, maybe the functionality should be added to <zipfileset/> It will make a lot of sense. And you can always do the same as <lib/> using a <zipfileset/>.
"but I can't find any evidence that files stored in subdirectories of WEB- INF/lib would be used for anything" Well, assuming it's expanded on disk and uses a "normal" URLClassLoader, yes, they would if any JARs in WEB-INF/lib had a Class-Path manifest entry pointing to them. --DD
I validated with Jetty (4.2.8) that the .jar files must be directly contained in WEB-INF/lib. I strongly doubt other servlet containers are more flexible and I wouldn't doubt that the spec indicates that they should be directly contained.
Thanks for the pointer; the zipfileset is a good workaround for me that wasn't obvious (to me).
Oh I see ... no that's not a workaround. No place to add a <mapper> to a <zipfileset> (you were suggesting it). I'm thiking that, in general, FileSets should support a nested Mapper. Is this feasible?
I agree with that. It would make my life easier too (for example with <sync> and multiple source filesets with different mappers).
Actually, on viewing the source you can see that <lib> actually IS a ZipFileSet; however its prefix attribute is explicitly set in War. I can accept DD's argument here... albeit grudgingly. ;) Anyway, it really doesn't make a whole lot of sense add a <mapper> to <fileset>; it might make sense to add a <mapper> to <zipfileset>. I haven't had enough sleep to think about the proper behavior for it right now though. Also, if anyone can suggest a sane behavior for a <mapper> with regard to a plain <fileset> I'm all ears. Howard: I assume your <lib> entry has a dir attribute pointing to some directory, and you're including either the whole directory or "**/*.jar" or something. Just checking, you do NOT know the names of the subdirectories ahead of time or you would just include multiple <lib> entries, correct?
<mapper>s talk about destinations. Since <filesets> are use for things that only read but do not write, this is not the right place for them. On the other hand, <zipfileset>s are always written (into the Zipfile) hence it makes much more sense to have a mapper here.
It is a right place for them - they would create a virtual file system (view) with file in correct places, so <copy>, <sync>, <war> would just copy files from one file system into another.
What do you mean, that the files returned by the <fileset> will say they are in one place but they are actually comming from a different place? So when I find an error in some file, the class will write the wrong location because it thinks it is in a place where it is not? Such thing will break 90% of the tasks that use <fileset>s. Most tasks do their own mapping given by its own rules (like javac). You cannt just change them any way you want and not expect concequences. But I could agreed that we should have a more centralized concept for things that do read/write. Today read is expressed by <fileset> and write by <mapper>. Much more tasks should support these two.
You are right. That would mean that some tasks will accept FileSet and some other tasks will accept VirtualFileSet and most ANT internal tasks (<copy>, <sync>, ...) will work just fine with virtual file sets. Plus it would also solve fileset/filelist differences.
when I start remembering to add newlines.... You are right. That would mean that some tasks will accept FileSet and some other tasks will accept VirtualFileSet and most ANT internal tasks (<copy>, <sync>, ...) will work just fine with virtual file sets. Plus it would also solve fileset/filelist differences.
Oh, no! Not the virtual file debate again! :) Believe me, I was always PRO- virtual files long before I became a committer... but I was forced to come to grips with the fact that Ant 1.x internals are just not what they would need to be to make this work. :(
Is there ANT 2.0 in plans?
This bug just needs flatten="true" attribute for <lib> node.
Indeed that would solve this issue, but adding a <mapper> to <zipfileset> is potentially a more useful solution--i.e. it may prevent some other bugrep down the line. Remains to be seen whether implementation is practical, however. :)
It is dangerous, because it will be difficult to associate a mapper to a particular fileset. There are other filesets there, so unless you put a mapper within <lib> (a fileset!), it will create a confusion.
As stated above, the <lib> IS a <zipfileset>. So adding the <mapper> to one adds it to the other.
*** Bug 34830 has been marked as a duplicate of this bug. ***
Working on Maven Ant Tasks, flattening a fileset resolved by Maven would be a great enhancement: see http://jira.codehaus.org/browse/MANTTASKS-39 I looked at o.a.t.a.tasks.War class: public void addLib(ZipFileSet fs) { // We just set the prefix for this fileset, and pass it up. fs.setPrefix("WEB-INF/lib/"); super.addFileset(fs); } Instead of // We just set the prefix for this fileset, and pass it up. fs.setPrefix("WEB-INF/lib/"); I think // We just set the full path for this fileset, and pass it up. fs.setFullpath("WEB-INF/lib/"); would do what we are expecting. WDYT?
we havent been working on this as Ivy works differently...personally I think the way to do it would be a new resource collection that includes mapping rules; this could be reused more broadly than an inconsistent patch to one or two tasks..
I can see that this is marked for "target milestone 1.8.0". What exactly is going to be done? I think adding a "flatten" attribute with default value "false" will have minimum impact on existing users, while providing an easy way out for those of us who have hierarchies that we don't really want in our "WEB-INF/lib"s. I am not (by far) an ANT code contributor, so I don't know how hard this would be to implement - is the implementation of this feature already planned or would I increase the chances of it happening by diving into the ANT code and providing a fix? Please note that not everybody use Ivy with ANT, it would be great to have a "pure" ANT solution for this problem.
I can't say why Kev changed the target from unspecified to 1.8.0. Sure it would help if a patch including tests was contributed, otherwise all people waiting for this feature simply have to wait until any committer feels like working on it, which doesn't seem to be too likely given the history of this report.
svn trunk now contains a <mappedresources> collection that does the job. From the manual <war destfile="${output}"> <mappedresources> <restrict> <path path="${java.class.path}"/> <type type="file"/> </restrict> <chainedmapper> <flattenmapper/> <globmapper from="*" to="WEB-INF/lib/*"/> </chainedmapper> </mappedresources> </war> this flattens all files from CLASSPATH and puts them into WEB-INF/lib *** This bug has been marked as a duplicate of bug 4240 ***