how do i call jsf template from different xhtml (another bundle) in OSGi

634 views
Skip to first unread message

Ömer Emir Garipağaoğlu

unread,
Apr 21, 2015, 4:45:58 AM4/21/15
to op...@googlegroups.com

I want to call xhtml template from another xhtml but this xhtml is in different project(different jar). I'm using OSGi with karaf.

This is my master.xhtml ;

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui"
    xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
    <title>JSF 2.0 Hello World</title>
</h:head>
<h:body>
    <ui:include src="/test/template.xhtml"></ui:include>
    <h:form>
        <h:panelGrid columns="2" cellpadding="5">
            <h:commandButton value="Welcome Me" action="welcome"></h:commandButton>
        </h:panelGrid>
    </h:form>
</h:body>
</html>

This jar hasn't test package. This package is in my another jar. Master jar's folder structure is ;

-src
    -main
        -webapp
              -WEB-INF
              -master.xhtml

And template jar's folder structure is ;

-src
    -main
         -resources
                  -test
                       -template.xhtml
                       -subtemplate.xhtml
         -webapp
               -WEB-INF

And the last one my template.xhtml is ;

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
    <h:outputStylesheet name="common-style.css" library="css" />
</h:head>

<h:body>

    <div id="page">

        <div id="header">
            <ui:insert name="header">
                <ui:include src="subtemplate.xhtml" />
            </ui:insert>
        </div>

    </div>

</h:body>
</html>

And of course i add to template jar's pom.xml;

<Export-Package>
               test;version="1.0",
               *
</Export-Package>

And master jar's pom.xml ;

<Import-Package>
                .
                .
                .
                .
              test;version="[1.0.0,2.1)",
              *
</Import-Package>

But i run the project, i got this error ;

/test/template.xhtml Not Found in ExternalContext as a Resource

viewId=/master.xhtml
phaseId=RENDER_RESPONSE(6)

Caused by:
java.io.FileNotFoundException - /test/template.xhtml Not Found in ExternalContext as a Resource
at org.apache.myfaces.view.facelets.impl.DefaultFaceletFactory.resolveURL(DefaultFaceletFactory.java:280)

Achim Nierbeck

unread,
Apr 21, 2015, 4:49:45 AM4/21/15
to op...@googlegroups.com
Hi, 

never tried that scenario and my first assumption would have been that you'll need to make sure that you have the right import/export-packages configured. 
From what you have given, that part looks ok. Now, does the manifest also contain this information? 

regards, Achim 


--
--
------------------
OPS4J - http://www.ops4j.org - op...@googlegroups.com

---
You received this message because you are subscribed to the Google Groups "OPS4J" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ops4j+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Apache Member
Apache Karaf <http://karaf.apache.org/> Committer & PMC
OPS4J Pax Web <http://wiki.ops4j.org/display/paxweb/Pax+Web/> Committer & Project Lead
blog <http://notizblog.nierbeck.de/>
Co-Author of Apache Karaf Cookbook <http://bit.ly/1ps9rkS>

Software Architect / Project Manager / Scrum Master 

Achim Nierbeck

unread,
Apr 21, 2015, 4:52:49 AM4/21/15
to op...@googlegroups.com
One more, pax web makes sure all bundles which are relevant to each other are scanned for TLDs etc. maybe this needs to be expanded. 
Take a look at the sources and set a breakpoint at the right place. Maybe we'll need to add this as an additional feature to pax-web. 

regards, Achim 

Marc Schlegel

unread,
Apr 21, 2015, 9:13:33 AM4/21/15
to op...@googlegroups.com
I havent used this approach but I will probably need it in the near future. It looks like you are want to use Servlet 3.0 resource-fragments [1]. 

JSF by default will scann for resources in Jar-files under META-INF/resources (not WEB-INF, or root).

Maybe it is enough to change your file-structure accordingly. Otherwise I guess pax-web needs to do some scanning...

regards

Achim Nierbeck

unread,
Apr 21, 2015, 9:35:28 AM4/21/15
to op...@googlegroups.com
Well it's already possible since Pax Web 3.x to use web-fragments. Might be good to create the second bundle as a web-fragment. 
Never the less, it might also be another feature to add to pax-web. 

regards, Achim 

Ömer Emir Garipağaoğlu

unread,
Apr 21, 2015, 9:37:22 AM4/21/15
to op...@googlegroups.com
Thanks for all replies,

I created a folder structure shown in the link for my template bundle. There is META-INF under WEB-INF/lib directory and under META-INF/resources/common,
I have my template .xhtml pages. I export META-INF/resources/common in manifest (META-INF.resources.common;version="1.0.0") and import it
in manifest of another bundle in same way. I still can not reach .xhtml of templates file: FileNotFoundException.



21 Nisan 2015 Salı 16:13:33 UTC+3 tarihinde Marc Schlegel yazdı:

Achim Nierbeck

unread,
Apr 21, 2015, 9:40:37 AM4/21/15
to op...@googlegroups.com
Just to remind you guys :-)

within OSGi the scanning of the META-INF folder only works within the same bundle, but not within bundles which are loosely coupled to the bundle in question and certainly not from un-linked bundles. 

regards, Achim 

Marc Schlegel

unread,
Apr 21, 2015, 10:23:14 AM4/21/15
to op...@googlegroups.com
Well, I was hoping there is an easy fix to use the standard Servlet 3.0 way.

I guess you need to write a custom JSF-ResourceHandler [1].

After having a quick look at the Interface it seems there might also be a nice OSGI-way to solve this. Someone please correct me if I am wrong with the following...not an OSGI-expert.

The important method in ResourceHandler is this
Resource createResource( String resourceName, String libraryName )

I think it should be easy to use the library name as lookup-property for an OSGI-service, which then serves the resource via the given name. There can be many services, each with a dedicated library-property.
The custom-ResourceHandler just delegates the actuall resource-lookup to the service, which has full access to its own classloader.

regards
Marc






Achim Nierbeck

unread,
Apr 21, 2015, 10:26:01 AM4/21/15
to op...@googlegroups.com
The easy Servlet 3 way would be to create a web-fragment bundle. 
This'll make sure it's within the same classloader and therefore should work. 

The JSF-ResourceHandler ... I'm not so sure about it. It's worth a try. A quick sample project will show how good this'll work :-)

regards, Achim 

Achim Nierbeck

unread,
Apr 22, 2015, 2:57:15 AM4/22/15
to op...@googlegroups.com
One more, if you think something is missing. Open a Jira Feature Request for it, 
add a sample which shows how it's supposed to work and we can work on an solution. 
But since this project as all of the other OPS4j Projects are only worked on in Private time (no one funds us for doing it)
it: 
a) might take a bit longer for a solution, cause there are also other things in Life that are important (family, sleep, work-to-pay-the-bills, etc...) :-)
b) requires a "let's work together on this" mentality

Thanks, Achim 


Marc Schlegel

unread,
Apr 22, 2015, 3:57:15 AM4/22/15
to op...@googlegroups.com
Already working on the OSGI-JSF-ResourceHandler, since I need something like Ömer requested as well. Not sure if it will work but I might be able to say more about it after the weekend.

Ömer Emir Garipağaoğlu

unread,
Apr 22, 2015, 4:01:28 AM4/22/15
to op...@googlegroups.com
OK, thanks for all replies. I will continue to try.




22 Nisan 2015 Çarşamba 10:57:15 UTC+3 tarihinde Marc Schlegel yazdı:
...

Achim Nierbeck

unread,
Apr 22, 2015, 4:01:30 AM4/22/15
to op...@googlegroups.com
hi Marc, 

great thanks. If you got something would be great if you have a github link for it. 

regards, Achim 

Marc Schlegel

unread,
Apr 28, 2015, 9:46:05 AM4/28/15
to op...@googlegroups.com
I've just managed to get a working example, though I had to change some parts of the initial design.
The extender-pattern is much more usefull in this use-case since we want to provide additional resources, not execute code. Also, the "client" doesnt need to implement any interface this way.



In order to make use of this, the jsf-application needs to change the default ResourceHandler in its faces-config.xml

<application>
<resource-handler>jsf.resourcehandler.JsfOsgiResourceHandler</resource-handler>
</application>

A resource-bundle has to specify the manifest-header "Jsf-Resource". The value curently has no effect (the extender just checks the for the header). I was initially thinking about specifying jsf-libraries in the header but I decided to conform to the jsf-spec: the actuall lookup will start at "/META-INF/resources". I am hoping that the IDEs will pick up the resources without even knowing that it is actually an osgi-bundle.

This is still not even beta, and I would recommend using the web-fragments-approach recommended by Achim. The challenge is that the JSF-API has no means to set Classloaders: instead one has to implement custom Classes with tons of JSF-specific things (see JsfOsgiResource).

I will try to improve this example, but I probably wont make it before my vacation...my girlfriend will kill me when I code in the hotel ;-)

Feedback is appreciated.

regards
Marc

Achim Nierbeck

unread,
Apr 28, 2015, 9:48:21 AM4/28/15
to op...@googlegroups.com
Hi Marc, 

thanks for sharing, I'll look at it ASAP ... 
I fully understand your vacation constraint ;)

regards, Achim 

Marc Schlegel

unread,
Apr 28, 2015, 9:57:27 AM4/28/15
to op...@googlegroups.com
I forgot to mention: this project uses Java 8 because I was to lazy to write all those loops for lookup and I like the new functional collections in Java 8 :-)
...

Ömer Emir Garipağaoğlu

unread,
Apr 30, 2015, 8:11:00 AM4/30/15
to op...@googlegroups.com
Thank you very much Marc, I examine your working. 



28 Nisan 2015 Salı 16:57:27 UTC+3 tarihinde Marc Schlegel yazdı:

Ömer Emir Garipağaoğlu

unread,
May 4, 2015, 10:08:12 AM5/4/15
to op...@googlegroups.com
Hi again,

When i run the project in Apache Karaf 3.0.3 with servlet 3.0 (not 3.1) i got null pointer exception when creating resources in JsfOsgiResourceHandler.java class.

javax.servlet.ServletException
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:230)[126:org.apache.myfaces.core.bundle:2.2.7]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1496)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.ops4j.pax.web.service.internal.WelcomeFilesFilter.doFilter(WelcomeFilesFilter.java:185)[79:org.ops4j.pax.web.pax-web-runtime:3.1.4]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1467)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:501)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:69)[80:org.ops4j.pax.web.pax-web-jetty:3.1.4]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:240)[80:org.ops4j.pax.web.pax-web-jetty:3.1.4]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:75)[80:org.ops4j.pax.web.pax-web-jetty:3.1.4]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.server.Server.handle(Server.java:370)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:971)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1033)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:53)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)[71:org.eclipse.jetty.aggregate.jetty-all-server:8.1.15.v20140411]
at java.lang.Thread.run(Thread.java:745)[:1.8.0_45]
Caused by: java.lang.NullPointerException
at jsf.resourcehandler.JsfOsgiResourceHandler.createViewResource(JsfOsgiResourceHandler.java:33)[105:jsf-resourcehandler:1.0.0.201505041146]

As seen at the top of the error i actually got servlet exception. I guess this is because the version of servlet i use. I couldn't work servlet 3.1 with Apache Karaf 3.0.3.
 
Is there a way to use servlet 3.1 or am i missing something else ?






28 Nisan 2015 Salı 16:57:27 UTC+3 tarihinde Marc Schlegel yazdı:
...

Achim Nierbeck

unread,
May 4, 2015, 10:27:00 AM5/4/15
to op...@googlegroups.com
Hi, 

Karaf 3.x line comes with Pax Web 3.x line and therefore Jetty8 + Servlet 3.0 
Karaf 4.x line comes with Pax Web 4.x line and therefore Jetty9 + Servlet 3.1

So right now you'll need to use Karaf 4 M2, or if you wait till the end of the week a Karaf M3 will be available. 
The first release of Karaf 4 should be around shortly after. 

regards, Achim 

Ömer Emir Garipağaoğlu

unread,
May 5, 2015, 3:00:25 AM5/5/15
to op...@googlegroups.com
Hi,

Thank you for the answer. Now i'm using Apache Karaf 4.0.0 M2 , but i got another problem. 

Despite i saw "org.ops4j.pax.web.pax-web-jetty - 4.1.0 | Pax Web available at [0.0.0.0]:[8181]" in the log, i can not reach server from the browser. I already installed "http" and "war" features. 

Thanks.


4 Mayıs 2015 Pazartesi 17:27:00 UTC+3 tarihinde Achim Nierbeck yazdı:

Achim Nierbeck

unread,
May 5, 2015, 3:04:10 AM5/5/15
to op...@googlegroups.com
Hi Ömer, 

there has been a behavioral change to pax-web, unless you have an application running, the server is stopped. 
So just install your own application and you'll see that jetty is answering again. 

regards, Achim 

Ömer Emir Garipağaoğlu

unread,
May 7, 2015, 2:23:04 AM5/7/15
to op...@googlegroups.com
Hi All,

Thanks for replies.

I am a little bit confused about Marc's code. 

When i run the project with maven, everything looks ok. I mean i can print out the resource name which is registered and get the service successfully
in the createViewResource method in JsfOsgiResourceHandler class. 

But when i try to run the project in Apache Karaf 4.0.0.M2, i can not register the service. So, i got null pointer exception when i try to call createResource method
of SimpleJsfResourcesRegistry service. 

The reason is difference of jar versions in karaf and jsf-itest bundle? or am i missing something else?


5 Mayıs 2015 Salı 10:04:10 UTC+3 tarihinde Achim Nierbeck yazdı:
...

Marc Schlegel

unread,
May 14, 2015, 4:31:39 PM5/14/15
to op...@googlegroups.com
Hello from Crete :-)

Just a little disclaimer: the code I provided was just a proof of concept to see if it is possible to use the JSF-API to load resources from bundles in a OSGi-way. I have only tested the environment which is used in the included itest and there I also get some exceptions but it is working to the point I needed it.
When I am back I will try to find some more time.

regards
Marc
...

Marc Schlegel

unread,
Jul 24, 2015, 9:15:46 PM7/24/15
to OPS4J, masch...@gmail.com
Hello again.

Due to some time constraints I havent had any time to work on this little project in last two months.

The last two evenings I spent some time again on the following issues:
  • test-case
    • template using composition
    • added a second "resource-bundle" with another footer for the template
    • using template in application-bundle and added a graphicImage which is located in resource-bundle
  • fixes
    • resources can now be loaded (prior only view-resources worked). Tested with the graphicsImage.

Know Problems:

  • Myfaces is still raising exception claiming that no Factory is configured though everything works, which is pretty anoying but I couldn´t find a fix yet.
  • Mojarra currently not working!
    • It seems Mojarra-API is dependent on Mojarra-Impl which causes ClassNotFoundExceptions
  • Extended library-resolution with versions not yet implemented (its already 3 AM, I will have a look at it in the next days)


BTW: If anyone can help me out with the Myfaces-Exception and Mojarra I´d be happy :-)


regards

Marc


Project-Location: https://github.com/lostiniceland/osgi/tree/master/jsf-resourcehandler




Achim Nierbeck

unread,
Jul 25, 2015, 4:59:34 PM7/25/15
to op...@googlegroups.com, Marc Schlegel
Hi Marc, 

I looked into it a bit. 

the issue with myfaces is actually only when stopping. Needs to be fixed with pax-web I guess. 
The Mojarra ClassNotFound Exception is rather strange as the bundle doesn't really seem to import it. 
it could be due to the way ServletContextListeners are initialized. 

regards, Achim 


--
--
------------------
OPS4J - http://www.ops4j.org - op...@googlegroups.com

---
You received this message because you are subscribed to the Google Groups "OPS4J" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ops4j+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages