[
https://issues.apache.org/jira/browse/MYFACES-3051?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12998712#comment-12998712
]
Leonardo Uribe commented on MYFACES-3051:
-----------------------------------------
Unfortunately, the patch has some problems. I see some code already committed,
but fortunately it does not contains too much changes.
Let's start with the idea of MyFacesClassLoader. Look this code:
@Override
public URL getResource(String s)
{
// context classloader
URL url = super.getResource(s);
if (url == null)
{
// try api
url = apiClassLoader.getResource(s);
if (url == null)
{
// try impl
url = implClassLoader.getResource(s);
}
It is ok, but note if we are using myfaces-bundle, we'll scan on the same
classloader twice (because api and impl are the same bundle classloader)
This code will not work correctly:
@Override
public Enumeration<URL> getResources(String s) throws IOException
{
// use all 3 classloaders and merge without duplicates
Set<URL> urls = new HashSet<URL>(); // no duplicates
// context classloader
urls.addAll(Collections.list(super.getResources(s)));
// api classlaoder
urls.addAll(Collections.list(apiClassLoader.getResources(s)));
// impl classlaoder
urls.addAll(Collections.list(implClassLoader.getResources(s)));
return Collections.enumeration(urls);
Why? the class loader IS NOT unique per class. Really it depends on the
environment. In some scenarios, the same classloader is returned from different
classes. In OSGi case, since it is expected myfaces-bundle is used we are
adding the same resources 2 times, and if the TCCL can locate resources of
myfaces bundle jar, the final result is have 3 times the same files.
Look this issue: MYFACES-3055 META-INF/faces-config.xml files in JARs are
loaded twice . The problem is caused because somebody decide to do the same the
patch here is proposing.
Unfortunately, by the previous reason it is not possible to use a
MyFacesClassLoader. The best we can do here is let the code as we had before,
so we can differentiate between use TCCL and class ClassLoader. Instead, it is
better to have utility methods that handle the case we require (retrieve
resource from TCCL and myfaces-bundle CL). There is no need to worry about
myfaces-api/myfaces-impl, because that's one reason to have just one jar file
in OSGi case (myfaces-bundle).
Really there is one problem about MyFaces and OSGi. Sometimes, MyFaces requires
to instantiate/load resources or classes inside/outside MyFaces. For example, I
have one JSF component library that has some resources under
META-INF/resources/my.custom.library and MyFaces requires to serve this
resource on a page. First MyFaces should scans on its bundle classloader and it
does not found the files required. Then, it uses the TCCL to locate the files,
and that one "contacts" the custom JSF component library jar to see if this
bundle has the files and if that so it serves the required resources.
Right now, MyFaces REQUIRES the TCCL to work as expected. That was one lesson
learned trying to close MYFACES-2290. The problem in that time was
FactoryFinder imposes that restriction. Note right now, it is probably we'll
commit soon a solution to override FactoryFinder behavior. But the problem we
need to think is if there is other way in OSGi to make MyFaces load some
resource files in a web context or app context. For now, it is supposed the
TCCL do the job (and it does fine), but we don't have any report indicating it
is necessary to suppose the opposite.
> Use multiple ClassLoaders to find resources (not only ContextClassLoader)
> -------------------------------------------------------------------------
>
> Key: MYFACES-3051
> URL: https://issues.apache.org/jira/browse/MYFACES-3051
> Project: MyFaces Core
> Issue Type: Bug
> Affects Versions: 2.0.4
> Environment: OSGi
> Reporter: Jakob Korherr
> Assignee: Jakob Korherr
> Attachments: MYFACES-3051-first-draft.patch,
> MYFACES-3051-impl-and-shared.patch
>
>
> In most parts of the code we only use the ContextClassLoader to find Classes
> and Resources. However, in some parts we also use the ClassLoader of the
> current Class or of a specific Class (e.g. to use myfaces-api and/or
> myfaces-impl ClassLoader, see ApplicationImpl.getResourceBundle(),
> BeanValidator.postSetValidationGroups(), ResourceHandlerImpl.getBundle() or
> FactoryFinder for example).
> IMO we should unify this code and maybe provide a custom ClassLoader that
> encapsulates three ClassLoaders (ContextClassLoader, myfaces-api and
> myfaces-impl). This most certainly would solve a lot of OSGi related problems.
> WDYT?
--
This message is automatically generated by JIRA.
-
For more information on JIRA, see: http://www.atlassian.com/software/jira