|
The classloader correct resolves the jar resources, the problem are ocuring when spring try to get the resouce as a File object and can't do that cause the protocol used is "vfszip". class: ResourceUtils There is one workaround for it? Except the xml one... When exactly is that ResourceUtils.getFile method called during component scanning in your case? I suppose during PathMatchingResourcePatternResolver.findPathMatchingResources? The actual problem is then probably the preceding isJarURL check that doesn't detect "vfszip" as jar files yet... I've added "vfszip" for 2.5.6; this will be available in tonight's 2.5.6 snapshot (http://static.springframework.org/downloads/nightly/snapshot-download.php?project=SPR Juergen Exactly: org.springframework.core.io.support.PathMatchingResourcePatternResolver.findPathMatchingResources(PathMatchingResourcePatternResolver.java:336) ok, i will test this on 2.5.6 version. I return the result... the incompatibility still remains, I'm geting this error now: Caused by: java.io.FileNotFoundException: C:\jboss\server\default\deploy\VO-ejbEAR.ear\VO-ejb.jar\com (the system can't find de specified path) I was looking at the problem... the "vfszip" url protocol is not recognized as a JarURLConnection. I search this protocol on internet and find no documentation for it... this kind of improvment can to be made? I'm not aware of any such protocol documentation either... You could try to debug the doFindPathMatchingJarResources method and see what it encounters there: in particular, what kind of URLConnection it gets that isn't a JarURLConnection. Unfortunately, if we are not getting a URLConnection that allows us to introspect the contents of the affected archive, then all we can do is to try to locate the archive file in the file system (the code path where the exception above comes from) . The latter doesn't work properly if the jar is nested in another archive, such as in an EAR file. Juergen I'm afraid we can't do anything about this for the moment. To be reopened once there is way to perform such scanning on JBoss - if there is enough demand for Spring component scanning in a JBoss EJB jar to begin with. Juergen It's unfortunate that ResourceUtils.isJarURL(URL) was modified to account for JBoss 5's new VFS URLs, but PathMatchingResourcePatternResolver.doFindPathMatchingJarResources(Resource, String) was not updated to account for these URLs. As per the code comments in doFindPathMatchingJarResources, this method assumes a JAR URL format of "jar:path!/entry"; however, VFS apparently doesn't include the exclamation character(ie, "jar:path/entry" instead of "jar:path!/entry"). It should be sufficient to look for ".jar/" (or any of the other JAR variants: EAR, WAR, etc) instead of "!/", with appropriate modifications to the path split indices. The resolution to this bug is "deferred"; are you planning on fixing this for 3.0.0? Do you plan on releasing a 2.5.7? Thanks for any info! I'm getting the same problem. And just to clarify, it's not just EJB jars. It's any jar at the EAR level, referenced from the WAR manifest classpath. You can use my VFS based impl of ResourcePatternResolver. Juergen, what would be the best place for this code? Perhaps you can also update the VFS usage in JBoss5 Attaching a jboss-as-spring-int.jar which includes this VFS bridge. This really is a very big problem, it occurs indeed in any jar or war inside an ear. Justin, I'm sorry if this is a stupid question, but I don't understand how I have to use your provided jar file. Where do I place it, and how do I make spring use it ? And you need to place the jar somewhere in app's classpath. Juergen, I re-opened the issue, since there currently is an implementation that is capable to treat the VFS URLs correctly. As Ales has mentioned before, the Spring Deployer in JBoss already uses a ResourcePatternResolver that solves this problem. The implementation is here: However, what lacks at this point, is a proper way to easily integrate this with the mainstream Spring code. The only way for an ApplicationContext to customize its ResourcePatternResolver is by overriding getResourcePatternResolver(). In practice, this means that for being able to use Spring in JBoss AS5, one needs to create its own ApplicationContext subtypes for being able to deal with such scenarios as classpath scanning for bean definitions, or using pattern-based context configuration locations. Otherwise, regular applications (including simple wars) won't work out of the box, when it comes to dealing with pattern-based resource paths. Typical failure scenarios and user-provided solutions are listed here: http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4213444 (The main cause being that the bootstrapped XmlWebApplicationContext uses a ServletContextResourcePatternResolver, which in turn delegates to its base PathMatchingResourcePatternResolver, which cannot treat the resource path correctly, nor be easily replaced with the extended VFSResourcePatternResolver, unless the user modifies the code or extends the base class). So, what seems to be needed here is a pluggable mechanism, so that a specific protocol, such as vfszip, could be resolved (resource loaded, path scanned, etc) through a specific strategy (like, for example, VFSResourcePatternResolver), that could be picked up from the classpath (and provided as part of the JBoss support libraries). Regards, I refactored our Spring integration into separate project: This VFS support is now a module in this new integration project At Alfresco we also struggled getting our Spring-based framework working on JBoss 5. We have lots of bean definition files using classpath-based pattern matching. E.g.: Code: FYI I eventually created a subclass of XmlWebApplicationContext that used a generalized version of Ales's VFSResourcePatternResolver that subclassed ServletContextResourcePatternResolver. I had to fix the logic to deal with relative path matching and matching of directories. I also made the resolver behave as normal on other app servers when not dealing with vfs URLs. See http://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/HEAD/root/projects/core/source/java/org/alfresco/config/JBossEnabledWebApplicationContext.java So I just want to make sure I get this correct, before I decide how to approach it.. The Alfresco guys and the JBoss guys both seem to have (very similar) resolutions to this issue, which seem to indicate fixing it by handling VFS a bit nicer. so if I check out and compile the source here: http://anonsvn.jboss.org/repos/jbossas/projects/spring-int/trunk/vfs/src/main/java/org/jboss/spring/vfs/ Afaik, Marius just finished porting/matching Alfresco's fixes to our codebase. The whole project is mavenized, hence it's trivial to build the artifacts. It's not meant to be a "real" project atm (at least not yet). Ok, so making this change did in fact fix my issue. However, there seems to be some compatibility issues w/ loading Hibernate resources. Currently, we're calling getResources("classpath*:*/.hbm.xml") against the app context. Any ideas for a work around? If it helps I'm currently running this against JB-AS 5.1 Thanks! John, Can you provide some details on the issues you're encountering? Error messages, etc? Thanks, We have a chunk of code public static Resource[] getResources(String path) { Which is invoked in the following manner: CoreInit.getResources("classpath*:*/.hbm.xml") And ac is now a VFSXmlWebApplicationContext. The exception gets thrown. This works fine on a tomcat install w/o the VFSXmlWebApplicationContext, so I assume something similar has to get fixed to make this work. The relevant part of the exception: Caused by: java.io.IOException: Child not found opt/jboss/jboss-5.1.0.CR1/server/default/deployers/jbossweb.deployer/ for MemoryContextHandler@1682498437[path= context=vfsmemory://4sg3s5y-u98501-fuba1p5t-1-fuba29fj-28 real=vfsmemory://4sg3s5y-u98501-fuba1p5t-1-fuba29fj-28], available children: [] Not sure why it's trying to go all the way down there. I embedded the JAR files in the war file (which is in an ear file). OK, thanks, I'll look into it. John, The issue you were encountering was due to https://jira.jboss.org/jira/browse/JBVFS-109 Regards, Marius, Ales, It would be great if we could extract the minimum that's needed to make classpath scanning work on JBoss 5, and include it in Spring 3.0 proper. However, I'm a bit unclear on what it actually takes there. Does the situation change on JBoss 5.1? Do we really need full-fledged VFS API usage in order to sort this out? We could bake reflective checks into PathMatchingResourcePatternResolver itself, I suppose... Concrete patches against PathMatchingResourcePatternResolver would be very welcome - possibly using VFS API internally only, guarded by some VFS API presence checks. Compiling PathMatchingResourcePatternResolver against a VFS API jar wouldn't be a problem, as long as that optional API usage does not impose runtime requirements on non-JBoss users. Compare PathMatchingResourcePatternResolver's existing optional use of Equinox OSGi API, if present. Juergen Juergen, Thanks for the reply. Good to see this being sorted out before the release of 3.0 I'll upload a patch shortly, tomorrow at latest. Is there any way to backport this to 2.5.x? Case in which I could provide a similar patch for that, too. Noted your comments - it's pretty much what I had in mind for this, too. The VFS API we are working against does not change in 5.1, but there is a strict VFS issue (JBVFS-109) mentioned above, which affects JBoss AS 5.0 (now fixed), and which makes using "classpath*:**/<something>" resources problematic. Marius Juergen, I added a patch for this issue, which overrides the default behaviour of PathMatchingResourcePatternResolver in the case of JBoss 5.x. This compiles against JBoss-vfs 2.1.0.GA which can be acquired from here (and it can run against newer versions, like 2.1.2 GA and higher). Thanks, Please provide a 2.5.X backport. This is a heay weight problem at the moment. Thanks for the acknowledgement on the source. Note that I also had to change RECURSE_LEAVES_ONLY to RECURSE to get equivalent behaviour to base Spring (which would return directories as well as files matching a pattern). I also think it would be worthwhile if VFSResource extended AbstractResource (as in the Alfresco implementation) so that hashCode, equals, etc. are implemented. Without this, I'm surprised you can add a VFSResource to a HashSet! Also, do we still need VFS support in ResourceLoader (as in the Alfresco implementation)? Would getResource("mypath/myresource").getFile() throw an exception where otherwise it wouldn't have on JBoss 4 or Tomcat? David, Thanks for pointing these things out - you can add a VFSResource to a HashSet - but, yes - the main problem is that if you have overlapping patterns your Resources will be added twice, not quite something you want to see. Actually, there is an issue with treating "classpath:<resource-path>" correctly and I will upload another patch shortly. Marius So, here's the new patch: vfs-fixes-2.patch. It incorporates the additions to VfsResource indicated by David, as well as some further changes. Juergen, I think that isolating delegation in ResourceUtil was the right decision in this case, even if making ResourceUtil know about the delegates expands its scope for a bit. Having to choose between addressing the issue by modifying the ResourceLoader (as we have done in jboss-spring-int) to return a different Resource implementation and trying to make the existing Resource implementations work correctly, I went for the latter. So this makes sure that on a JBoss Application Server, URLs and URIs starting with "vfszip:" are processed correctly by ResourceUtils.getFile(), as well as making sure that resources having URLs starting with vfs* are navigated correctly. Cheers, and thanks the feedback, vfs-fixes-3.patch: A small fix adding equals() and hashCode() implementations to VFSResource (the default is based on getDescription() which delegates to VirtualFileHandler). Related to http://jira.springsource.org/browse/SPR-5784 P.s. http://jira.springsource.org/browse/SPR-5784 Are the changes in the "vfs-fixes-3.patch" patch going to be incorporated into Spring 3.0 RC1? In our Roo 1.0.0.RC1 testing of the petclinic.roo script against JBoss 5.10.GA we encounter an exception which appears to be related to this issue: Context initialization failed Juergen, I'd be happy to test any new Spring Framework snapshot you produce against Roo and JBoss 5 and see if it is resolves the above. Please just let me know. -Stefan The component scanning is not working even for .class files inside WEB-INF/classes, not just jar files. For that JBoss uses the vfsfile protocol, which is also not supported by Spring. This is a big blocker for us since we're trying to migrate our applications from JBoss 4.2.3 to JBoss 5.1. Attached "jboss-spring-int-vfs.jar" that contains utilities for handling classpath scanning in JBoss AS5. For web applications, use org.jboss.spring.vfs.context.VFSXmlWebApplicationContext throught the 'contextClass' parameter in either ContextLoaderListener, or DispatcherServlet. Andre, See my comment above. You can also take a look at the whole http://anonsvn.jboss.org/repos/jbossas/projects/spring-int/branches/1_0/ Hope that helps, I have committed a revised patch for this issue. Moved methods from ResourceUtils to a separate ResourceHandlingUtils in the core.io.support package to avoid dependency cycles between packages. -Thomas At Alfresco we found that the VFSResource implementation still didn't work with some of our webapps that would work in Tomcat. For example this context file that uses ".." in a relative URL <?xml version='1.0' encoding='UTF-8'?> <beans> We fixed our own VFSResource implementation as follows public Resource createRelative(String relativePath) throws IOException { return new VFSResource(VFS.getRoot(new URL(getURL(), relativePath))); }Please consider reopening this issue and fixing as above. Thomas, FIrst, thanks for comitting the patch. Also, David is right - and I made the changes in our code as per https://jira.jboss.org/jira/browse/JBSPRING-4 Thanks, modified createRelative according to David Ward's suggestion for JBSPRING-4 Hi All I had posted something on the forum a while back (http://forum.springsource.org/showthread.php?t=71541 Thanks |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Well, I suppose that the JBoss EJB container does not properly resolve your "com" package in the classpath there. This is what Spring's component scanner relies on.
You could give the following a try:
myEjb.getClass().getClassLoader().getResources("com")
and see what gets returned there. If that unexpectedly correctly resolves all roots of the "com" package in the classpath, try the following:
appContext.setClassLoader(myEjb.getClass().getClassLoader());
before calling the component scanner. In general, always make sure that the ApplicationContext is configured with the correct target ClassLoader.
Juergen