Hi Jan

Thanks for the reply and sorry about my "thinking out loud" emails. Things
are getting clearer as we speak and I now actually know what change I want
(to contribute). I write this mail to hear if you're interested in a patch
for this or if I would be wasting my time.

On Thu, Jan 8, 2015 at 2:06 PM, Jan Bartel <[email protected]> wrote:

>
> Sheesh, we already give you so many ways to start jetty, and its still
> not enough :) :) :)
>

Actually, you're right - there are enough ways. The approach that I am
using is the same as the one from the Heroku sample application. It is also
the way described under "Setting a Web Application Context" under
https://wiki.eclipse.org/Jetty/Tutorial/Embedding_Jetty. I personally thing
these are the best ways of using Jetty.

The example code from Heroku is similar to the one I showed:
https://github.com/heroku/java-getting-started/. However, I also need
static resources like HTML, CSS and JavaScript. It can look like this
(provided that the resources are included in the jar-file):

WebAppContext webapp = new WebAppContext("/webapp", "/app");


This approach works great on the server, but it is very cumbersome during
development if the project also contains static resources (HTML. CSS, JS).
If I start Jetty with a WebAppContext in the IDE I will encounter a problem:

   - If I change a static file (HTML, CSS, JS) and save, the IDE will try
   and copy this file to the output directory. Since the file has been opened
   with useFileMappedBuffers, this copy will fail. In Eclipse, the project
   will get an error and I have to stop Jetty and cleanly build it to continue.

You can change this behavior by changing the line above to use the source
folder instead. If I'm using Maven, it will probably look like this:

WebAppContext webapp = new WebAppContext("/webapp",
"src/main/resources/app");


This avoids leaving the project in an invalid state, but it leads to two
other problems:

   - It makes the code to use during development different from the
   production code as described here
   
https://wiki.eclipse.org/Jetty/Tutorial/Embedding_Jetty#Setting_a_Web_Application_Context.
   I've experienced this as the seed that leads to a large amount of
   development-only code in more than one project.
   - The useFileMappedBuffers is still in effect and if I try and modify a
   static file, the IDE will reject saving it (after it has been served)

What I really want is to be able to say something to the effect of the
first line:

WebAppContext webapp = new WebAppContext("/webapp", "/app");


This can probably not be made to be backwards compatible, but I *can* do
something like this:

WebAppContext webapp = new WebAppContext("/webapp",
Resource.newProjectResource("/app", new String[] { "src/main/resource" }));


What this would do:

   - Look for /app in the classpath. If it is in a directory (and not a
   JAR), this means we're running in exploded mode. In that case, try to
   substitute the source directories (in this case src/main/resource). If that
   works, make sure file mapped buffers are *not* used.
   - If /app is in a jar-file or not in the source folders, it works
   exactly as Resource.newResource("/app")

On more thing: org.eclipse.jetty.annotations.AnnotationConfiguration
doesn't currently work with classpath resources, only with WAR-files.

I have made an experimental implementation of the above code. In order to
make it work, I had to
fight org.eclipse.jetty.server.ResourceCache.getDirectBuffer pretty hard. I
can fool this code "if (_useFileMappedBuffer && resource.getFile()!=null)"
by making my resource return null for a file, but it would probably be more
meaningful to create a new method
org.eclipse.jetty.util.resource.Resource.isSupportingDirectBuffer.

The resulting code would look something like this:

public class SimpleServer {
    public static void main(String[] args) throws Exception {
        HandlerList handlers = new HandlerList();
        handlers.addHandler(new ShutdownHandler("randomtoken", false,
true));
        handlers.addHandler(new WebApplication("/app",
Resource.newProjectResource("/app")));
        Server server = new Server(5000);
        server.setHandler(handlers);
        server.start();
        System.out.println("Started " + server.getURI());
    }
}

Again: This is the same way of starting the Jetty as Heroku and on the
Emdedding Jetty documentation pages, with additional ease of use during
development. So it is not a new method, but an improvement to what I
personally feel is the current best method. It also addresses the section
"Setting a Web Application Context" under
https://wiki.eclipse.org/Jetty/Tutorial/Embedding_Jetty, where there are
currently two examples. This approach unifies them. (This section seems to
be missing from the new documentation at
https://www.eclipse.org/jetty/documentation/current/embedding-jetty.html)

The changes I would contribute are as follows:

   - ResourceBuffer.getDirectBuffer() would use the new method
   Resource.isSupportingDirectBuffer() instead of checking for
   Resource.getFile() == null
   - A new method Resource.newProjectResource would check if the classpath
   resource should be treated as a source resource and return a subclass of
   Resource which does not support direct buffer if so
   - A new constructor to WebAppContext would take contextPath and
   baseResource

In addition, I would like to contribute a subclass of WebAppContext
(ClasspathWebAppContext) with a new method scanForAnnotations which mimics
AnnotationConfiguration when you're not dealing with a WAR-file.

Would you be interested in patches to this effect? If so, I can create a
bug report with the modifications to Resource, WebAppContext and
ResourceBuffer.


~Johannes


> > On Fri, Jan 2, 2015 at 6:04 PM, Jan Bartel <[email protected]> wrote:
> >>
> >> Hi Johannes,
> >>
> >> Have you considered using the jetty-runner? Here's the doc:
> >>
> >>
> http://www.eclipse.org/jetty/documentation/current/runner.html#jetty-runner
> >>
> >> You could point it at your src/main/resources/webapp dir as the webapp
> >> to deploy. However, as it seems you're running on windows, you'll need
> >> to use a context xml file instead to set the context param to turn off
> >> fileMappedBuffers, and to point to your webapp and context path.
> >>
> >> OTOH, your main is a pretty simple class ... it could be made more
> >> generic by using system properties to set the context path, webapp to
> >> deploy and the fileMappedBuffers property.
> >>
> >> cheers
> >> Jan
> >>
> >> On 2 January 2015 at 16:15, Johannes Brodwall <[email protected]>
> >> wrote:
> >> > Hi
> >> >
> >> > I would like to hear if someone could suggest how to scratch this
> itch I
> >> > often have when using Jetty embedded in applications.
> >> >
> >> > I am often using Jetty during development. I'd like for static files
> >> > that
> >> > are normally packaged into a war or jar file to be easy to edit when I
> >> > am
> >> > developing (that is, when the files are not packaged). At the same
> time,
> >> > I
> >> > want my code to be as similar as possible during development and in
> >> > production.
> >> >
> >> > My best attempt so far has been to place the static content under
> >> > src/main/resources/webapp and package it into the Jar-file.
> >> >
> >> > In order to avoid locking the files when I'm running the server in the
> >> > debugger, I've implemented the following:
> >> >
> >> >     public static WebAppContext createApplicationContext() {
> >> >         WebAppContext webapp = new WebAppContext("/webapp", "/app");
> >> >
> >> >         if
> >> >
> >> >
> (SimpleServer.class.getResource(webapp.getWar()).getProtocol().equals("file"))
> >> > {
> >> >             // Avoid locking static content when running exploded
> >> >             webapp.setWar("src/main/resources/webapp");
> >> >
> >> >
> >> >
> webapp.setInitParameter("org.eclipse.jetty.servlet.Default.useFileMappedBuffer",
> >> > "false");
> >> >         }
> >> >         return webapp;
> >> >     }
> >> >
> >> > This runs in a main method like so:
> >> >
> >> > public class SimpleServer {
> >> >
> >> >     public static void main(String[] args) throws Exception {
> >> >         HandlerList handlers = new HandlerList();
> >> >         handlers.addHandler(new ShutdownHandler("randomtoken", false,
> >> > true));
> >> >         handlers.addHandler(createApplicationContext());
> >> >
> >> >         Server server = new Server(5000);
> >> >         server.setHandler(handlers);
> >> >         server.start();
> >> >
> >> >         System.out.println("Started " + server.getURI());
> >> >     }
> >> > }
> >> >
> >> > As the rest of the code is extremely simple, the magic replacement of
> >> > the
> >> > target file with the source file and the setting of the very poorly
> >> > documented "org.eclipse.jetty.servlet.Default.useFileMappedBuffer"
> >> > parameter
> >> > both feel really frustrating. The code is magic enough that I've ended
> >> > up
> >> > creating a "framework" to run it which is clearly not what I want.
> >> >
> >> >
> >> > 1. Are there currently better ways of doing this?
> >> > 2. Is there any way something that accomplishes the same could be
> added
> >> > to
> >> > Jetty itself?
> >> >
> >> >
> >> > ~Johannes
> >> >
> >> >
> >> >
> >> > _______________________________________________
> >> > jetty-users mailing list
> >> > [email protected]
> >> > To change your delivery options, retrieve your password, or
> unsubscribe
> >> > from
> >> > this list, visit
> >> > https://dev.eclipse.org/mailman/listinfo/jetty-users
> >>
> >>
> >>
> >> --
> >> Jan Bartel <[email protected]>
> >> www.webtide.com
> >> 'Expert Jetty/CometD developer,production,operations advice'
> >> _______________________________________________
> >> jetty-users mailing list
> >> [email protected]
> >> To change your delivery options, retrieve your password, or unsubscribe
> >> from this list, visit
> >> https://dev.eclipse.org/mailman/listinfo/jetty-users
> >
> >
> >
> > _______________________________________________
> > jetty-users mailing list
> > [email protected]
> > To change your delivery options, retrieve your password, or unsubscribe
> from
> > this list, visit
> > https://dev.eclipse.org/mailman/listinfo/jetty-users
>
>
>
> --
> Jan Bartel <[email protected]>
> www.webtide.com
> 'Expert Jetty/CometD developer,production,operations advice'
> _______________________________________________
> jetty-users mailing list
> [email protected]
> To change your delivery options, retrieve your password, or unsubscribe
> from this list, visit
> https://dev.eclipse.org/mailman/listinfo/jetty-users
>
_______________________________________________
jetty-users mailing list
[email protected]
To change your delivery options, retrieve your password, or unsubscribe from 
this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users

Reply via email to