# Deliver Fuseki as a WAR file.

## Details

• Type: Improvement
• Status: Closed
• Priority: Minor
• Resolution: Done
• Affects Version/s: None
• Fix Version/s:
• Component/s:
• Labels:
None

## Attachments

1. GruppoImola_fuseki_war_src.rar
11 kB
Francesco Panico
2. fuseki-war-proto.zip
9 kB
Andy Seaborne

## Activity

Andy Seaborne created issue -
Hide
Rob Vesse added a comment -

So here are my notes on progress so far.

Generating a war with maven is trivial by using the war:war goal once you've created a web.xml file in the appropriate place.

The tricky part looks to be configuration, usually Fuseki would pick up config from command line but this is not doable in WAR packaging

Unless anyone has objections my intention is to try using <context-param> elements to set up the defaults and then somehow get those to be used to configure the server at first run. Problem is I can't see any obvious way to do this (but that may just be my lack of familiarity with the servlet specs), we actually don't really want to explicitly register servlets because we want to still to configure based on a config file.

The other option is to have a WAR which just has a default config for a single dataset with that dataset being defined by a config file so users can customize that. I assume that this second option is not the preferred option

If anyone has ideas/input/opinions on this please chime in

Show
Rob Vesse added a comment - So here are my notes on progress so far. Generating a war with maven is trivial by using the war:war goal once you've created a web.xml file in the appropriate place. The tricky part looks to be configuration, usually Fuseki would pick up config from command line but this is not doable in WAR packaging Unless anyone has objections my intention is to try using <context-param> elements to set up the defaults and then somehow get those to be used to configure the server at first run. Problem is I can't see any obvious way to do this (but that may just be my lack of familiarity with the servlet specs), we actually don't really want to explicitly register servlets because we want to still to configure based on a config file. The other option is to have a WAR which just has a default config for a single dataset with that dataset being defined by a config file so users can customize that. I assume that this second option is not the preferred option If anyone has ideas/input/opinions on this please chime in
Hide
Rob Vesse added a comment -

With regards to the first option one suggestion is that we add overrides of the init(ServletConfig config) method to the servlets in Fuseki, we then use a static flag to distinguish between the case where servlets have been created by command line invoke and by web.xml loading. In the former case we would skip any init() initialization while in the latter case it would be essential

Show
Rob Vesse added a comment - With regards to the first option one suggestion is that we add overrides of the init(ServletConfig config) method to the servlets in Fuseki, we then use a static flag to distinguish between the case where servlets have been created by command line invoke and by web.xml loading. In the former case we would skip any init() initialization while in the latter case it would be essential
Hide
Rob Vesse added a comment -

Another notion is that you could have the base servlets declared but not mapped to paths and then use filters to remap requests to the relevant servlet based on URL patterns. You'd need to integrate some on the fly config loading and caching but this might be the best way of actually achieving this

Show
Rob Vesse added a comment - Another notion is that you could have the base servlets declared but not mapped to paths and then use filters to remap requests to the relevant servlet based on URL patterns. You'd need to integrate some on the fly config loading and caching but this might be the best way of actually achieving this
Hide
Andy Seaborne added a comment -

Joseki has a more comprehensive way to find a config. The code for Joseki is in the Scratch area.

org.joseki.http.Servlet is the main servlet. init(ServletConfig) plays "hunt the config". It looks in:

• ServletContext
• A Java system property.

The command line sets the system property. The command line also forces early initialization otherwise the initialization process does not happen until the servlet is first used. That can be confusing because config file errors don't show up until first request when inside a larger system but we probably just have to live with that.

The init code has to be aware it can be called multiple times. A simple boolean to check and simply return is sufficient.

One user support issue that comes up is that Tomcat blocks access to files outside the webapp area by default.

The war file could be just the server or server+the web pages. I'm inclined to focus on just the server.

Show
Andy Seaborne added a comment - Joseki has a more comprehensive way to find a config. The code for Joseki is in the Scratch area. org.joseki.http.Servlet is the main servlet. init(ServletConfig) plays "hunt the config". It looks in: ServletContext A Java system property. The command line sets the system property. The command line also forces early initialization otherwise the initialization process does not happen until the servlet is first used. That can be confusing because config file errors don't show up until first request when inside a larger system but we probably just have to live with that. The init code has to be aware it can be called multiple times. A simple boolean to check and simply return is sufficient. One user support issue that comes up is that Tomcat blocks access to files outside the webapp area by default. The war file could be just the server or server+the web pages. I'm inclined to focus on just the server.
Hide
Andy Seaborne added a comment -

One issue for web.xml ...

The URIs for routing the requests include the dataset name before the service name.

Standalone, a relevant servlet is mounted at each service point declared in the config file, including no servlet if that service isn't offered. This is more than JAX-RS like dispatch by pattern. A single dispatcher to work on URI patterns, with the dispatch built with info from the config file may be necessary. web.xml is merely routing everything to this dispatcher servlet. This style could be rolled back to the standalone server so as not to have duplication.

Or maybe put the "configuration" almost entirely in web.xml, leaving only the dataset declaration part for each service in the config file and let the webapp container manage it i.e have two configuration mechanisms. As some config file for assemblers is going to be needed, I'm inclined currently to have one place to configure and have the generic dispatch servlet.

Show
Andy Seaborne added a comment - One issue for web.xml ... The URIs for routing the requests include the dataset name before the service name. Standalone, a relevant servlet is mounted at each service point declared in the config file, including no servlet if that service isn't offered. This is more than JAX-RS like dispatch by pattern. A single dispatcher to work on URI patterns, with the dispatch built with info from the config file may be necessary. web.xml is merely routing everything to this dispatcher servlet. This style could be rolled back to the standalone server so as not to have duplication. Or maybe put the "configuration" almost entirely in web.xml, leaving only the dataset declaration part for each service in the config file and let the webapp container manage it i.e have two configuration mechanisms. As some config file for assemblers is going to be needed, I'm inclined currently to have one place to configure and have the generic dispatch servlet.
Hide
Rob Vesse added a comment -

I think the generic dispatch pattern would be ideal but I don't really have the expertise in the relevant area of Java to implement that myself. I was hoping that repackaging as a WAR would be relatively simple but I keep running into stumbling blocks.

The latest hiccup I've uncovered in my experimentation is that Fuseki includes servlet-api in its dependencies, if you try and run as a WAR within Tomcat it will complain because the spec says a WAR shouldn't include a copy of the servlet-api.

One possible workaround here would be to have a separate project for the WAR packing and declare the servlet-api as an optional dependency (http://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html) of the main Fuseki project so it doesn't get packaged by the WAR project, since optional dependencies of dependencies are not included. The downside to this is that those using Fuseki as a library for a standalone server may have to explicitly add servlet-api back as a dependency

Show
Rob Vesse added a comment - I think the generic dispatch pattern would be ideal but I don't really have the expertise in the relevant area of Java to implement that myself. I was hoping that repackaging as a WAR would be relatively simple but I keep running into stumbling blocks. The latest hiccup I've uncovered in my experimentation is that Fuseki includes servlet-api in its dependencies, if you try and run as a WAR within Tomcat it will complain because the spec says a WAR shouldn't include a copy of the servlet-api. One possible workaround here would be to have a separate project for the WAR packing and declare the servlet-api as an optional dependency ( http://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html ) of the main Fuseki project so it doesn't get packaged by the WAR project, since optional dependencies of dependencies are not included. The downside to this is that those using Fuseki as a library for a standalone server may have to explicitly add servlet-api back as a dependency
Hide
Jacobus Geluk added a comment - - edited

Andy, I have created a fork of jena-fuseki on github (https://github.com/jgeluk/jena-fuseki), where I used your main Joseki servlet as the basis for a similar Fuseki servlet. Called it ConfigServlet (https://github.com/jgeluk/jena-fuseki/blob/trunk/src/main/java/org/apache/jena/fuseki/server/ConfigServlet.java) and put it next to the SPARQLServer class since it's kind of the Servlet-equivalent of that class. It loads the config.ttl but in order to dynamically create the other Servlets, like is done for Jetty in SPARQLServer, such as SPARQL_QueryGeneral and SPARQL_REST, I need to implement the Tomcat specific interface ContainerServlet, which makes it a privileged Servlet. Not really an elegant solution since it would require an additional parameter in Context.xml (and make it Tomcat specific).
So I guess the only proper way to do this is to make that dispatcher as you suggested. I guess it would be similar to what Joseki does then? Any hints?

Show
Jacobus Geluk added a comment - - edited Andy, I have created a fork of jena-fuseki on github ( https://github.com/jgeluk/jena-fuseki ), where I used your main Joseki servlet as the basis for a similar Fuseki servlet. Called it ConfigServlet ( https://github.com/jgeluk/jena-fuseki/blob/trunk/src/main/java/org/apache/jena/fuseki/server/ConfigServlet.java ) and put it next to the SPARQLServer class since it's kind of the Servlet-equivalent of that class. It loads the config.ttl but in order to dynamically create the other Servlets, like is done for Jetty in SPARQLServer, such as SPARQL_QueryGeneral and SPARQL_REST, I need to implement the Tomcat specific interface ContainerServlet, which makes it a privileged Servlet. Not really an elegant solution since it would require an additional parameter in Context.xml (and make it Tomcat specific). So I guess the only proper way to do this is to make that dispatcher as you suggested. I guess it would be similar to what Joseki does then? Any hints?
Field Original Value New Value
Link This issue is related to JENA-214 [ JENA-214 ]
Hide
Rob Vesse added a comment -

So while I have not made further progress on this I think I now see how to proceed with this though I don't think I have time to work on this currently.

The main problem as previously discussed is keeping dynamic configuration while moving to a container agnostic WAR which on the face of it seems rather awkward but I believe this is doable. I now believe that the way to this is by utilizing a ServletContextListener (http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html) - this is a part of the Java Servlets API and is easily registered in a web.xml file like so:

<listener>
<listener-class>org.apache.jena.fuseki.FusekiContextListener</listener-class>
</listener>

Then the contextInitialized() method can be used to read the configuration file (which will have to be located at a path within the web app i.e. people will need to deploy the WAR and then go in and edit the config appropriately prior to running it) and wire up servlets and filters appropriately since it has access to the servlet context and can call all the addServlet(), addFilter() methods etc. as necessary

Show
Rob Vesse added a comment - So while I have not made further progress on this I think I now see how to proceed with this though I don't think I have time to work on this currently. The main problem as previously discussed is keeping dynamic configuration while moving to a container agnostic WAR which on the face of it seems rather awkward but I believe this is doable. I now believe that the way to this is by utilizing a ServletContextListener ( http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html ) - this is a part of the Java Servlets API and is easily registered in a web.xml file like so: <listener> <listener-class>org.apache.jena.fuseki.FusekiContextListener</listener-class> </listener> Then the contextInitialized() method can be used to read the configuration file (which will have to be located at a path within the web app i.e. people will need to deploy the WAR and then go in and edit the config appropriately prior to running it) and wire up servlets and filters appropriately since it has access to the servlet context and can call all the addServlet(), addFilter() methods etc. as necessary
Hide
Rob Vesse added a comment -

To add to the previous discussion probably the most sensible way of WARifying Fuseki would be to split the project into two:

• fuseki-core - This would be a WAR project that incorporates all the servlets and refactors the existing configuration mechanism into a ServletContextListener. Configurations would be managed by assembler files in the conf/ directory defaulting to fuseki.ttl - we'd provide a selection of sample files with different configs that people could easily wire up.
• fuseki-server - This would be a JAR project that would basically embed Jetty/Tomcat and depend on the fuseki-core project in order to provide a runnable JAR version of the server as with the existing project

Structuring this way allows for us to continue to provide a runnable JAR to get people started quickly while allowing for a working WAR that advanced users can drop into the application server of their choice

Show
Rob Vesse added a comment - To add to the previous discussion probably the most sensible way of WARifying Fuseki would be to split the project into two: fuseki-core - This would be a WAR project that incorporates all the servlets and refactors the existing configuration mechanism into a ServletContextListener. Configurations would be managed by assembler files in the conf/ directory defaulting to fuseki.ttl - we'd provide a selection of sample files with different configs that people could easily wire up. fuseki-server - This would be a JAR project that would basically embed Jetty/Tomcat and depend on the fuseki-core project in order to provide a runnable JAR version of the server as with the existing project Structuring this way allows for us to continue to provide a runnable JAR to get people started quickly while allowing for a working WAR that advanced users can drop into the application server of their choice
Hide
Claude Warren added a comment -

I began working with Fuseki but found that it's interface and session requirements did not work well with the REST web services we were trying to implement. I ended up using Fuseki as a guide and reworking it into a JAX-RS based web service. This made it easy to plug Jena into specific parts of a web service URI structure.

My implementation still uses the embedded Jetty server but now uses Jersey instead of Fuseki to route requests as SPARQL queries and the like.

If there is interest I would be willing to contribute what I have, though I will have to check with my employer first.

Claude

Show
Claude Warren added a comment - I began working with Fuseki but found that it's interface and session requirements did not work well with the REST web services we were trying to implement. I ended up using Fuseki as a guide and reworking it into a JAX-RS based web service. This made it easy to plug Jena into specific parts of a web service URI structure. My implementation still uses the embedded Jetty server but now uses Jersey instead of Fuseki to route requests as SPARQL queries and the like. If there is interest I would be willing to contribute what I have, though I will have to check with my employer first. Claude
Hide
Francesco Panico added a comment -

Hi,
Gruppo Imola (http://www.imolinfo.it/)
has developed a solution to deploy fuseki as a webApp in an application server J2EE.
We used jena-2.7.3.
Fuseki initialize Date Set servlet with own API Jetty. The idea is to remove Jetty dependencies and create application server indipendent classes for the initialization.

A ServletContextListener (Servlet 3.0 specification) is used to inizialize Data Set servlets.
We have created a maven project to package Fuseki as a WAR file. WAR file contains all "jena-2.7.3 jars and some customized classes.

An other problem is that the base URL used by Jetty is "/" (context path). Often it is not possible to use that convention in enterprise environmet so we replaced it
adding the context path (request.getContextPath()). In this way you can set fuseki WebApp with any URL (ES: http://myCompanyname/fuseki)

src\main\java\org\apache\jena\fuseki\servlets\SimpleVelocityServlet.java add new velocity servlet contructor and init method. They are used by ServletContextListener (J2EE compliant)
src\main\java\it\imolinfo\fuseki\FusekiConfigurator.java initialize data set servlet
src\main\webapp\WEB-INF\web.xml define listener, servlets and servlets url mapping

We tested Fuseki war on tomcat 7 and JBoss 7.1.1 with JDK 7
I attached "GruppoImola_fuseki_war_src.rar" file that contain all customized classes

Show
Francesco Panico added a comment - Hi, Gruppo Imola ( http://www.imolinfo.it/ ) has developed a solution to deploy fuseki as a webApp in an application server J2EE. We used jena-2.7.3. Fuseki initialize Date Set servlet with own API Jetty. The idea is to remove Jetty dependencies and create application server indipendent classes for the initialization. A ServletContextListener (Servlet 3.0 specification) is used to inizialize Data Set servlets. We have created a maven project to package Fuseki as a WAR file. WAR file contains all "jena-2.7.3 jars and some customized classes. An other problem is that the base URL used by Jetty is "/" (context path). Often it is not possible to use that convention in enterprise environmet so we replaced it adding the context path (request.getContextPath()). In this way you can set fuseki WebApp with any URL (ES: http://myCompanyname/fuseki ) src\main\java\org\apache\jena\fuseki\mgt\ActionDataset.java add use of ContextPath src\main\java\org\apache\jena\fuseki\servlets\SimpleVelocityServlet.java add new velocity servlet contructor and init method. They are used by ServletContextListener (J2EE compliant) src\main\java\org\apache\jena\fuseki\servlets\SPARQL_ServletBase.java add use of ContextPath src\main\java\org\apache\jena\fuseki\mgt\ActionDataset.java add use of ContextPath src\main\java\it\imolinfo\fuseki\FusekiConfigurator.java initialize data set servlet src\main\webapp\WEB-INF\web.xml define listener, servlets and servlets url mapping We tested Fuseki war on tomcat 7 and JBoss 7.1.1 with JDK 7 I attached "GruppoImola_fuseki_war_src.rar" file that contain all customized classes
Hide
Francesco Panico added a comment -

file contains all customized classes used by GruppoImola to deploy Fuseki as a Web App

Show
Francesco Panico added a comment - file contains all customized classes used by GruppoImola to deploy Fuseki as a Web App
 Attachment GruppoImola_fuseki_war_src.rar [ 12543279 ]
Hide
Andy Seaborne added a comment -

This looks excellent.

One thing I want to check - do you use this with TDB? If so, do you put the absolute file path to the database in fuseki-config.ttl (or at least point to outside webapps/) or put the database inside the WAR file?

Show
Andy Seaborne added a comment - This looks excellent. One thing I want to check - do you use this with TDB? If so, do you put the absolute file path to the database in fuseki-config.ttl (or at least point to outside webapps/) or put the database inside the WAR file?
Hide
Andy Seaborne added a comment -

This patch is really useful to have and it has helped me think about where we can go with this.

A possible design is to have the config file outside the WAR file, in a well-known standard place (or series of places and play the game of "hunt the config"). If the config is in the WAR file, the user has to edit or make the WAR file in some way so from an easy of use point of view, a single war and a well known place for the config might be easier for users who then do not need to have detaled knowledge of WAR file builing.

This works with having TDB databases in a common place as well, which will be needed when adding the ability to create/delete databases in a running server, also control security. Then there is a usage where there is no user written config file (many people seem to run from command currrentyl anyway) - and everything is UI controlled.

The config file does not go away - the other use case of a planned, automated depolyment means a config file to easily set up a server remotely is needed.

Security - Apache Shiro looks good for this but we don't want to just assume use of that. We'll need to design so Fuseki can work within any reasonable security fremwork from container provided to enterprise stuff.

fuseki-core
servelts, config parsing,

fuseki-control
turn the control panel into a proper system admin console.
(no need to make separate but depending on technology used it might be easier)

fuseki-standalone
current distribution: adds Jetty, packaging as a zip, scripts

fuseki-war
packaging in war format

(I am not a fan of too many maven modules but in practice its going to be easier to have several rather than build variations by classifier out of a common code pool).

Show
Andy Seaborne added a comment - This patch is really useful to have and it has helped me think about where we can go with this. A possible design is to have the config file outside the WAR file, in a well-known standard place (or series of places and play the game of "hunt the config"). If the config is in the WAR file, the user has to edit or make the WAR file in some way so from an easy of use point of view, a single war and a well known place for the config might be easier for users who then do not need to have detaled knowledge of WAR file builing. This works with having TDB databases in a common place as well, which will be needed when adding the ability to create/delete databases in a running server, also control security. Then there is a usage where there is no user written config file (many people seem to run from command currrentyl anyway) - and everything is UI controlled. The config file does not go away - the other use case of a planned, automated depolyment means a config file to easily set up a server remotely is needed. Security - Apache Shiro looks good for this but we don't want to just assume use of that. We'll need to design so Fuseki can work within any reasonable security fremwork from container provided to enterprise stuff. fuseki-core servelts, config parsing, fuseki-control turn the control panel into a proper system admin console. (no need to make separate but depending on technology used it might be easier) fuseki-standalone current distribution: adds Jetty, packaging as a zip, scripts fuseki-war packaging in war format (I am not a fan of too many maven modules but in practice its going to be easier to have several rather than build variations by classifier out of a common code pool).
Hide
Francesco Panico added a comment -

FusekiConfigurator.java class loads "fuseki-config.ttl" config file. In that file you choose to use SDB or TDB.
This file is in "webapp\WEB-INF"
We tested SDB for the reason I explained in mailng list.

Loading config file that is outside the War is not so easy.
It's easier to have a default config file inside the War file and the istruction to modify it in order to cheose SDB or TDB and DB locations.

In "fuseki-config.ttl" we set DB connection parameters, it would be great to be able to define only JNDI resource name.

Yes, we have a structure of modules that is similar to yours. Modulies allow to you to create different build variants, as you need, with only one distribution.

Show
Francesco Panico added a comment - FusekiConfigurator.java class loads "fuseki-config.ttl" config file. In that file you choose to use SDB or TDB. This file is in "webapp\WEB-INF" We tested SDB for the reason I explained in mailng list. Loading config file that is outside the War is not so easy. It's easier to have a default config file inside the War file and the istruction to modify it in order to cheose SDB or TDB and DB locations. In "fuseki-config.ttl" we set DB connection parameters, it would be great to be able to define only JNDI resource name. Yes, we have a structure of modules that is similar to yours. Modulies allow to you to create different build variants, as you need, with only one distribution.
Hide
Andy Seaborne added a comment -

I agree that loading outside the WAR is not easy but I don't think that only in-WAR is good for users who are not java/maven developers.

The code can be generic and look in a number of places (init params, WEB-INF, well-known file system locations, ...).

Show
Andy Seaborne added a comment - I agree that loading outside the WAR is not easy but I don't think that only in-WAR is good for users who are not java/maven developers. The code can be generic and look in a number of places (init params, WEB-INF, well-known file system locations, ...).
 Labels gsoc2013
 Labels gsoc2013 gsoc2013 mentor
Hide
ASF subversion and git services added a comment -

Commit 1517341 from Andy Seaborne in branch 'jena/trunk'
[ https://svn.apache.org/r1517341 ]

Refactor to make the HttpAction objects and servlets independent of Jetty.
An indirect dependency existed for HttpAction on SPARQLServer.
Refactoring is a step towards JENA-201 (Deliver Fuseki as a WAR file).

Show
ASF subversion and git services added a comment - Commit 1517341 from Andy Seaborne in branch 'jena/trunk' [ https://svn.apache.org/r1517341 ] Refactor to make the HttpAction objects and servlets independent of Jetty. An indirect dependency existed for HttpAction on SPARQLServer. Refactoring is a step towards JENA-201 (Deliver Fuseki as a WAR file).
Hide

SUCCESS: Integrated in Jena_Development_Test #868 (See https://builds.apache.org/job/Jena_Development_Test/868/)
Refactor to make the HttpAction objects and servlets independent of Jetty.
An indirect dependency existed for HttpAction on SPARQLServer.
Refactoring is a step towards JENA-201 (Deliver Fuseki as a WAR file). (andy: rev 1517341)

• /jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/Fuseki.java
• /jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/server/SPARQLServer.java
• /jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_ServletBase.java
• /jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java
• /jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ServletBase.java
Show
Hudson added a comment - SUCCESS: Integrated in Jena_Development_Test #868 (See https://builds.apache.org/job/Jena_Development_Test/868/ ) Refactor to make the HttpAction objects and servlets independent of Jetty. An indirect dependency existed for HttpAction on SPARQLServer. Refactoring is a step towards JENA-201 (Deliver Fuseki as a WAR file). (andy: rev 1517341) /jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/Fuseki.java /jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/server/SPARQLServer.java /jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_ServletBase.java /jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java /jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ServletBase.java
Hide
Andy Seaborne added a comment - - edited

Prototype of a WAR-deployed Fuseki.
Uses file area /usr/share/fuseki.

This is builds a single war file that looks in /usr/share/fuseki/config-fuseki.ttl for a Fuseki configuration file. It uses a universal dispatch servlet. HTML pages are currently not supported.

Much of the FusekiServlet is adapting the existing universal dispatch servlet (SPARQL_UberServlet)
to work with servlet contexts (named webapps).

Limited testing deploying in Tomcat6 and in-memory datasets.

Ideally, the Fuseki build structure would be split into servlets (the core engine, Jetty independent), build for the standalone server and a build for the WAR version.

Use of the WAR version and a large TDB database may not do the web container (tomcat) much good because of TDB's memory needs. A standalone server isolates this.

Show
Andy Seaborne added a comment - - edited Prototype of a WAR-deployed Fuseki. Uses file area /usr/share/fuseki. This is builds a single war file that looks in /usr/share/fuseki/config-fuseki.ttl for a Fuseki configuration file. It uses a universal dispatch servlet. HTML pages are currently not supported. Much of the FusekiServlet is adapting the existing universal dispatch servlet (SPARQL_UberServlet) to work with servlet contexts (named webapps). Limited testing deploying in Tomcat6 and in-memory datasets. Ideally, the Fuseki build structure would be split into servlets (the core engine, Jetty independent), build for the standalone server and a build for the WAR version. Use of the WAR version and a large TDB database may not do the web container (tomcat) much good because of TDB's memory needs. A standalone server isolates this.
 Attachment fuseki-war-proto.zip [ 12599840 ]
Hide
Lewis John McGibbney added a comment -

Hi Andy, what work is required to get HTML pages supported here?
For my own web app I have forked Fuseki but ideally would like to make it available as a webapp from my Tomcat web server... currently this doesn't seem to be possible with the default Jetty implementation therefore I am keen to get HTML support as part of transitioning towards WAR packaging for Fuseki.
I can put time in to this is guided. In the mean time I will try to hack the code on my part and monitor this thread as well.

Show
Lewis John McGibbney added a comment - Hi Andy, what work is required to get HTML pages supported here? For my own web app I have forked Fuseki but ideally would like to make it available as a webapp from my Tomcat web server... currently this doesn't seem to be possible with the default Jetty implementation therefore I am keen to get HTML support as part of transitioning towards WAR packaging for Fuseki. I can put time in to this is guided. In the mean time I will try to hack the code on my part and monitor this thread as well.
Hide
Rob Vesse added a comment -

From a WAR perspective is it not just a case of making a copy of the pages/ directory into src/main/webapp directory

This could likely even be done with maven somehow during the package phase to avoid maintaining two copies of the HTML.

From http://maven.apache.org/plugins/maven-war-plugin/examples/adding-filtering-webresources.html the following should be sufficient:

<configuration>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>pages</directory>
</resource>
</webResources>
</configuration>

Show
Rob Vesse added a comment - From a WAR perspective is it not just a case of making a copy of the pages/ directory into src/main/webapp directory This could likely even be done with maven somehow during the package phase to avoid maintaining two copies of the HTML. From http://maven.apache.org/plugins/maven-war-plugin/examples/adding-filtering-webresources.html the following should be sufficient: <configuration> <webResources> <resource> <!-- this is relative to the pom.xml directory --> <directory> pages </directory> </resource> </webResources> </configuration>
Hide
Lewis John McGibbney added a comment -

Hi Rob, just the man. I will try this out after work and write here my results. I am also on users@ so I may see you there. Thanks for feedback.

Show
Lewis John McGibbney added a comment - Hi Rob, just the man. I will try this out after work and write here my results. I am also on users@ so I may see you there. Thanks for feedback.
Hide
Lewis John McGibbney added a comment - - edited

OK doke. Well after configuring Tomcat to use Log4j for fine grained logging I realized that config-fuseki.ttl needed to be under /usr/share/fuseki/ for the web app to run within Tomcat.
I am seeing traces (which I suspect are down to the config file). I post the logging below for the record.
I am working towards getting the pages working within Tomcat. I will post how I get on with this.
Thanks
Lewis

Aug 26, 2013 5:49:23 PM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deploying web application archive /home/law/Desktop/tomcat7/webapps/apache-jena-fuseki.war
17:49:24 INFO  Config               :: Init - Context path: '/apache-jena-fuseki'
17:49:24 INFO  Config               :: Service: <file:///usr/share/fuseki/config-fuseki.ttl#service1>
17:49:24 INFO  Config               ::   name = ds
17:49:24 INFO  Config               ::   query = /ds/query
17:49:24 INFO  Config               ::   query = /ds/sparql
17:49:24 INFO  Config               ::   update = /ds/update
17:49:24 INFO  Config               ::   graphStore(RW) = /ds/data
17:49:24 INFO  Config               ::   graphStore(R) = /ds/get
17:49:24 INFO  Config               :: Register: /ds : /ds
Aug 26, 2013 5:49:28 PM org.apache.catalina.core.ApplicationContext log
INFO: HTMLManager: list: Listing contexts for virtual host 'localhost'
17:49:29 INFO  FusekiServlet        :: Apache Jena Fuseki Server
17:49:29 INFO  FusekiServlet        :: URI                     = '/apache-jena-fuseki/
17:49:29 INFO  FusekiServlet        :: Context path            = '/apache-jena-fuseki'
17:49:29 INFO  FusekiServlet        :: Servlet path            = '/'
17:49:29 INFO  FusekiServlet        :: ServletContext path     = '/apache-jena-fuseki'
17:49:29 INFO  Fuseki               :: [1] GET http://localhost:8080/apache-jena-fuseki/
17:49:29 INFO  Fuseki               :: [1] All: GET  :: '' :: <none> ?
17:49:29 WARN  Server               :: Exception on counter inc
java.lang.NullPointerException
at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.incCounter(SPARQL_ServletBase.java:203)
at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.executeLifecycle(SPARQL_ServletBase.java:173)
at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.executeAction(SPARQL_UberServlet.java:169)
at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.execCommonWorker(SPARQL_ServletBase.java:153)
at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.doCommon(SPARQL_ServletBase.java:73)
at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.doGet(SPARQL_UberServlet.java:320)
at webapp.FusekiServlet.doGet(FusekiServlet.java:54)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:724) 17:49:29 WARN Server :: Exception on counter inc java.lang.NullPointerException at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.incCounter(SPARQL_ServletBase.java:203) at org.apache.jena.fuseki.servlets.SPARQL_REST.doGet$(SPARQL_REST.java:208)
at org.apache.jena.fuseki.servlets.SPARQL_REST.dispatch(SPARQL_REST.java:185)
at org.apache.jena.fuseki.servlets.SPARQL_REST.perform(SPARQL_REST.java:176)
at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.executeLifecycle(SPARQL_ServletBase.java:184)
at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.executeAction(SPARQL_UberServlet.java:169)
at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.execCommonWorker(SPARQL_ServletBase.java:153)
at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.doCommon(SPARQL_ServletBase.java:73)
at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.doGet(SPARQL_UberServlet.java:320)
at webapp.FusekiServlet.doGet(FusekiServlet.java:54)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:724) 17:49:29 WARN Server :: Exception on counter inc java.lang.NullPointerException at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.incCounter(SPARQL_ServletBase.java:203) at org.apache.jena.fuseki.servlets.SPARQL_REST.doGet$(SPARQL_REST.java:211)
at org.apache.jena.fuseki.servlets.SPARQL_REST.dispatch(SPARQL_REST.java:185)
at org.apache.jena.fuseki.servlets.SPARQL_REST.perform(SPARQL_REST.java:176)
at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.executeLifecycle(SPARQL_ServletBase.java:184)
at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.executeAction(SPARQL_UberServlet.java:169)
at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.execCommonWorker(SPARQL_ServletBase.java:153)
at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.doCommon(SPARQL_ServletBase.java:73)
at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.doGet(SPARQL_UberServlet.java:320)
at webapp.FusekiServlet.doGet(FusekiServlet.java:54)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:724) 17:49:29 WARN Server :: Exception on counter inc java.lang.NullPointerException at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.incCounter(SPARQL_ServletBase.java:203) at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.executeLifecycle(SPARQL_ServletBase.java:186) at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.executeAction(SPARQL_UberServlet.java:169) at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.execCommonWorker(SPARQL_ServletBase.java:153) at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.doCommon(SPARQL_ServletBase.java:73) at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.doGet(SPARQL_UberServlet.java:320) at webapp.FusekiServlet.doGet(FusekiServlet.java:54) at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)

Show
Lewis John McGibbney added a comment - - edited OK doke. Well after configuring Tomcat to use Log4j for fine grained logging I realized that config-fuseki.ttl needed to be under /usr/share/fuseki/ for the web app to run within Tomcat. I am seeing traces (which I suspect are down to the config file). I post the logging below for the record. I am working towards getting the pages working within Tomcat. I will post how I get on with this. Thanks Lewis Aug 26, 2013 5:49:23 PM org.apache.catalina.startup.HostConfig deployWAR INFO: Deploying web application archive /home/law/Desktop/tomcat7/webapps/apache-jena-fuseki.war 17:49:24 INFO Config :: Init - Context path: '/apache-jena-fuseki' 17:49:24 INFO Config :: Service: <file: ///usr/share/fuseki/config-fuseki.ttl#service1> 17:49:24 INFO Config :: name = ds 17:49:24 INFO Config :: query = /ds/query 17:49:24 INFO Config :: query = /ds/sparql 17:49:24 INFO Config :: update = /ds/update 17:49:24 INFO Config :: upload = /ds/upload 17:49:24 INFO Config :: graphStore(RW) = /ds/data 17:49:24 INFO Config :: graphStore(R) = /ds/get 17:49:24 INFO Config :: Register: /ds : /ds Aug 26, 2013 5:49:28 PM org.apache.catalina.core.ApplicationContext log INFO: HTMLManager: list: Listing contexts for virtual host 'localhost' 17:49:29 INFO FusekiServlet :: Apache Jena Fuseki Server 17:49:29 INFO FusekiServlet :: URI = '/apache-jena-fuseki/ 17:49:29 INFO FusekiServlet :: Context path = '/apache-jena-fuseki' 17:49:29 INFO FusekiServlet :: Servlet path = '/' 17:49:29 INFO FusekiServlet :: ServletContext path = '/apache-jena-fuseki' 17:49:29 INFO Fuseki :: [1] GET http: //localhost:8080/apache-jena-fuseki/ 17:49:29 INFO Fuseki :: [1] All: GET :: '' :: <none> ? 17:49:29 WARN Server :: Exception on counter inc java.lang.NullPointerException at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.incCounter(SPARQL_ServletBase.java:203) at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.executeLifecycle(SPARQL_ServletBase.java:173) at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.executeAction(SPARQL_UberServlet.java:169) at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.execCommonWorker(SPARQL_ServletBase.java:153) at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.doCommon(SPARQL_ServletBase.java:73) at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.doGet(SPARQL_UberServlet.java:320) at webapp.FusekiServlet.doGet(FusekiServlet.java:54) at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang. Thread .run( Thread .java:724) 17:49:29 WARN Server :: Exception on counter inc java.lang.NullPointerException at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.incCounter(SPARQL_ServletBase.java:203) at org.apache.jena.fuseki.servlets.SPARQL_REST.doGet$(SPARQL_REST.java:208) at org.apache.jena.fuseki.servlets.SPARQL_REST.dispatch(SPARQL_REST.java:185) at org.apache.jena.fuseki.servlets.SPARQL_REST.perform(SPARQL_REST.java:176) at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.executeLifecycle(SPARQL_ServletBase.java:184) at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.executeAction(SPARQL_UberServlet.java:169) at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.execCommonWorker(SPARQL_ServletBase.java:153) at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.doCommon(SPARQL_ServletBase.java:73) at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.doGet(SPARQL_UberServlet.java:320) at webapp.FusekiServlet.doGet(FusekiServlet.java:54) at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang. Thread .run( Thread .java:724) 17:49:29 WARN Server :: Exception on counter inc java.lang.NullPointerException at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.incCounter(SPARQL_ServletBase.java:203) at org.apache.jena.fuseki.servlets.SPARQL_REST.doGet$(SPARQL_REST.java:211) at org.apache.jena.fuseki.servlets.SPARQL_REST.dispatch(SPARQL_REST.java:185) at org.apache.jena.fuseki.servlets.SPARQL_REST.perform(SPARQL_REST.java:176) at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.executeLifecycle(SPARQL_ServletBase.java:184) at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.executeAction(SPARQL_UberServlet.java:169) at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.execCommonWorker(SPARQL_ServletBase.java:153) at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.doCommon(SPARQL_ServletBase.java:73) at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.doGet(SPARQL_UberServlet.java:320) at webapp.FusekiServlet.doGet(FusekiServlet.java:54) at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang. Thread .run( Thread .java:724) 17:49:29 WARN Server :: Exception on counter inc java.lang.NullPointerException at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.incCounter(SPARQL_ServletBase.java:203) at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.executeLifecycle(SPARQL_ServletBase.java:186) at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.executeAction(SPARQL_UberServlet.java:169) at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.execCommonWorker(SPARQL_ServletBase.java:153) at org.apache.jena.fuseki.servlets.SPARQL_ServletBase.doCommon(SPARQL_ServletBase.java:73) at org.apache.jena.fuseki.servlets.SPARQL_UberServlet.doGet(SPARQL_UberServlet.java:320) at webapp.FusekiServlet.doGet(FusekiServlet.java:54) at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang. Thread .run( Thread .java:724)
Hide
Andy Seaborne added a comment -

Rob - yes, that'll get to the same functionality as the standalone server (with caveats).

At the moment, the pages/ area is mounted as the root static content and reside on disk. When starting the standalone server you can have them somewhere else, use your own or editted pages, or arrange for no pages.

If included in the WAR file:

• The pages are always available.
• The pages are fixed.
• request routing needs to be page sensitive.

None of theose are entirely desirable. I guess it's framing what the WAR version is for; whether it is the standalone server but running in Tomcat or meeting a deployment need for a SPARQL server, where no pages makes sense.

Re: routing: to make the system generic, there is one uber SPARQL servlet to do all the routing (it's set as /*) so web.xml needs to have *.html, *.css, ... settings. In the standalone server, servlets are explicitly added for each service of each dataset, as if web.xml has /ds/query -> SPARQL_QueryDataset, /ds/update -> SPARQL_Update, ... .

This prototype webapp setup is a pure SPARQL server for programmatic access.

Show
Andy Seaborne added a comment - Rob - yes, that'll get to the same functionality as the standalone server (with caveats). At the moment, the pages/ area is mounted as the root static content and reside on disk. When starting the standalone server you can have them somewhere else, use your own or editted pages, or arrange for no pages. If included in the WAR file: The pages are always available. The pages are fixed. request routing needs to be page sensitive. None of theose are entirely desirable. I guess it's framing what the WAR version is for; whether it is the standalone server but running in Tomcat or meeting a deployment need for a SPARQL server, where no pages makes sense. Re: routing: to make the system generic, there is one uber SPARQL servlet to do all the routing (it's set as /* ) so web.xml needs to have *.html , *.css , ... settings. In the standalone server, servlets are explicitly added for each service of each dataset, as if web.xml has /ds/query -> SPARQL_QueryDataset , /ds/update -> SPARQL_Update , ... . See also JENA-350 (use of session cookies) and JENA-420 (new UI). This prototype webapp setup is a pure SPARQL server for programmatic access.
Hide
Andy Seaborne added a comment -

Lewis -

Re: NPE and missing counters.

GET http://localhost:8080/apache-jena-fuseki/ is going to the webapp, and has no dataset nor service. This needs to be graceful caught and make a 400 ... or to start yielding the index page.

Clearly, my testing had only covered what should work, not what shouldn't

Re:logging

There is a fight over logging going on - I didn't manage to sort that out and left it as Fuseki having it's own logging; I only managed to break things in an attempt to fix that, then I ran out of time.

Probably needs the whole of internal logging converted to using the logger for the servlet logger (getServletContext().log() which is bad style?) or a different setup to use java.util.logging, which is I think what Tomcat is using, or have a separate Fuseki log, not in catalina.out.

Show
Andy Seaborne added a comment - Lewis - Re: NPE and missing counters. GET http://localhost:8080/apache-jena-fuseki/ is going to the webapp, and has no dataset nor service. This needs to be graceful caught and make a 400 ... or to start yielding the index page. Clearly, my testing had only covered what should work, not what shouldn't Re:logging There is a fight over logging going on - I didn't manage to sort that out and left it as Fuseki having it's own logging; I only managed to break things in an attempt to fix that, then I ran out of time. Probably needs the whole of internal logging converted to using the logger for the servlet logger (getServletContext().log() which is bad style?) or a different setup to use java.util.logging, which is I think what Tomcat is using, or have a separate Fuseki log, not in catalina.out.
Hide
Lewis John McGibbney added a comment -

The pages are always available.

The pages are fixed.

For my use case this is exactly what I require Andy

I am going to work towards obtaining the 400 and presenting the index page upon startup. I think getting a web app (war packaging) which can be dropped in to Tomcat or some other container is certainly a start to overhauling the Fuseki interface. I will work on this anyway.

Separate Fuseki logging is certainly useful. A mish mash of Fuseki and Catalina INFO to catalina.out is not going to be particularly helpful as have numerous other applications spewing forth logging on this test server as well. I'll try to work towards separate logging for Fuseki as well. I am not having much joy obtaining any of the static files via my browser yet, even though they are included in the generated war however I should be able to sort this one out.

Show
Lewis John McGibbney added a comment - The pages are always available. The pages are fixed. For my use case this is exactly what I require Andy I am going to work towards obtaining the 400 and presenting the index page upon startup. I think getting a web app (war packaging) which can be dropped in to Tomcat or some other container is certainly a start to overhauling the Fuseki interface. I will work on this anyway. Separate Fuseki logging is certainly useful. A mish mash of Fuseki and Catalina INFO to catalina.out is not going to be particularly helpful as have numerous other applications spewing forth logging on this test server as well. I'll try to work towards separate logging for Fuseki as well. I am not having much joy obtaining any of the static files via my browser yet, even though they are included in the generated war however I should be able to sort this one out.
Hide
Andy Seaborne added a comment -

This links to JENA-420. The new UI requires full dynamic dispatch of operations under some base URI. This is exactly what is needed for a single WAR configuration for Fuseki.

Show
Andy Seaborne added a comment - This links to JENA-420 . The new UI requires full dynamic dispatch of operations under some base URI. This is exactly what is needed for a single WAR configuration for Fuseki.
Hide
ASF subversion and git services added a comment -

Commit 1553040 from Andy Seaborne in branch 'jena/branches/jena-fuseki-new-ui'
[ https://svn.apache.org/r1553040 ]

Use webapp setup - related to JENA-201.

Show
ASF subversion and git services added a comment - Commit 1553040 from Andy Seaborne in branch 'jena/branches/jena-fuseki-new-ui' [ https://svn.apache.org/r1553040 ] Use webapp setup - related to JENA-201 .
 Labels gsoc2013 mentor
 Link This issue is superceded by JENA-420 [ JENA-420 ]
Hide
Andy Seaborne added a comment -

There is a preview build of a Fuseki v2 server in WAR form.

Show
Andy Seaborne added a comment - There is a preview build of a Fuseki v2 server in WAR form. See http://mail-archives.apache.org/mod_mbox/jena-dev/201403.mbox/%3C53394253.1070506%40apache.org%3E
 Status Open [ 1 ] Closed [ 6 ] Assignee Andy Seaborne [ andy.seaborne ] Fix Version/s Fuseki 2.0.0 [ 12328543 ] Resolution Done [ 11 ]
Transition Time In Source Status Execution Times Last Executer Last Execution Date
 Open Closed
954d 18h 25m 1 Andy Seaborne 05/Sep/14 14:15

## People

• Assignee:
Andy Seaborne
Reporter:
Andy Seaborne