Come fare in modo che Jetty carichi dynamicmente le pagine “statiche”

Sto costruendo applicazioni web Java e odio il tradizionale ciclo “code-compile-deploy-test”. Voglio digitare una piccola modifica, quindi vedere il risultato ISTANTANEAMENTE, senza dover compilare e distribuire.

Fortunatamente, Jetty è fantastico per questo. È un server web puramente java. Viene fornito con un plugin Maven davvero carino che ti permette di avviare la lettura del Jetty direttamente dal tuo albero di compilazione – non è necessario creare un pacchetto o un file di guerra. Ha persino un’impostazione scanInterval: posiziona questo valore su un valore diverso da zero e guarderà i tuoi file java e i vari file di configurazione per le modifiche e verrà automaticamente ridistribuito alcuni secondi dopo aver apportato una modifica.

C’è solo una cosa che mi tratti dal nirvana. Ho i file javascript e css nella mia directory src / main / webapp che viene appena pubblicata da Jetty. Mi piacerebbe essere in grado di modificarli e visualizzare le modifiche quando aggiorno la pagina nel browser. Sfortunatamente, Jetty tiene aperti questi file, quindi non posso (su Windows) modificarli mentre è in esecuzione.

Qualcuno sa come fare in modo che Jetty lasci andare questi file in modo che io possa modificarli, quindi pubblicare i file modificati per le richieste successive?

Jetty utilizza file mappati in memoria per il buffer del contenuto statico, che causa il blocco dei file in Windows. Prova a impostare useFileMappedBuffer per DefaultServlet su false.

Risoluzione dei problemi I file bloccati su Windows (dal wiki di Jetty) contengono istruzioni.

Mentre una delle risposte di cui sopra è esattamente adatta per la configurazione di jetty per xml, se si desidera configurare questa opzione nel codice (per un server incorporato) la risposta è diversa e non trovata in quella pagina.

Troverai un numero di suggerimenti online incluso

context.getInitParams (). put (“useFileMappedBuffer”, “false”);

Oppure eseguire l’override di WebAppContext o utilizzare un nome completo per il parametro init. Nessuno di questi suggerimenti ha funzionato per me (usando Jetty 7.2.2). Parte del problema era che l’opzione useFileMappedBuffer deve essere impostata sul servlet che WebAppContext sta usando per servire i file statici, piuttosto che sul contesto.

Alla fine ho fatto qualcosa di simile su un semplice ServletContextHandler

// Startup stuff final Server server = new Server(port); ServletContextHandler handler = new ServletContextHandler(); handler.setResourceBase(path); SessionManager sm = new HashSessionManager(); SessionHandler sh = new SessionHandler(sm); handler.setSessionHandler(sh); DefaultServlet defaultServlet = new DefaultServlet(); ServletHolder holder = new ServletHolder(defaultServlet); holder.setInitParameter("useFileMappedBuffer", "false"); handler.addServlet(holder, "/"); server.setHandler(handler); server.start(); server.join(); 

Anche se questo è un vecchio problema, ma ho trovato questo post molto utile, in breve basta cambiare la configurazione in

   org.mortbay.jetty jetty-maven-plugin    8080     

Questo disabilita il supporto NIO in Jetty (ma non dovrebbe essere un problema per il debug di puropse per casi semplici).

La documentazione di Jetty 9.2 fornisce un esempio di Jetty Embedded per servire file statici usando un ResourceHandler invece di un servlet:

 // Create a basic Jetty server object that will listen on port 8080. Note that if you set this to port 0 // then a randomly available port will be assigned that you can either look in the logs for the port, // or programmatically obtain it for use in test cases. Server server = new Server(8080); // Create the ResourceHandler. It is the object that will actually handle the request for a given file. It is // a Jetty Handler object so it is suitable for chaining with other handlers as you will see in other examples. ResourceHandler resource_handler = new ResourceHandler(); // Configure the ResourceHandler. Setting the resource base indicates where the files should be served out of. // In this example it is the current directory but it can be configured to anything that the jvm has access to. resource_handler.setDirectoriesListed(true); resource_handler.setWelcomeFiles(new String[]{ "index.html" }); resource_handler.setResourceBase("."); // Add the ResourceHandler to the server. HandlerList handlers = new HandlerList(); handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() }); server.setHandler(handlers); // Start things up! By using the server.join() the server thread will join with the current thread. // See "http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join()" for more details. server.start(); server.join(); 

Jetty usa NIO (mapping dei file in memoria) e quindi blocca i file sui sistemi operativi Windows . Questo è un problema noto e si possono trovare soluzioni alternative per i servlet.

Tuttavia, poiché questo esempio non si basa sui servlet, le risposte associate basate sui parametri webapp (useFileMappedBuffer, maxCachedFiles) non funzionano.

Per impedire la mapping dei file in memoria, è necessario aggiungere la seguente riga di configurazione:

 resource_handler.setMinMemoryMappedContentLength(-1); 

Nota: come scritto in Javadoc (e notato da nimrodm): the minimum size in bytes of a file resource that will be served using a memory mapped buffer, or -1 for no memory mapped buffers . Ho comunque ottenuto lo stesso comportamento con valore Integer.MAX_VALUE .

Una volta impostato questo parametro, il tuo Jetty può pubblicare file statici su Windows E puoi modificarli.

Impostare false su useFileMappedBuffer in webdefault.xml NON ha funzionato per me (Jetty 8.1.10.v20130312). Fortunatamente l’impostazione di maxCachedFiles su 0 (anche in webdefault.xml) ha funzionato.

Ho anche avuto questo problema.

E non volevo creare classi aggiuntive e fare scherzi con web.xml

Quindi ecco cosa puoi fare:

Supponendo che il tuo progetto sia basato su maven e (diciamo) chiamato “my-web-app”

1) crea un file my-web-app / jetty / jetty-config.xml

2) metti questa roba dentro:

    org.eclipse.jetty.servlet.Default.useFileMappedBuffer false   

3) Ecco la tua configurazione di jetty:

  org.eclipse.jetty jetty-maven-plugin   localhost 8801   /${project.artifactId}  ${project.basedir}/jetty/jetty-config.xml   

Questa soluzione aggiungerà un attributo al contesto di servlet che disabiliterà il blocco delle risorse statiche.

Divertiti 🙂

Simile alla risposta di @kybernetikos, ma senza dover ricreare il DefaultServlet:

 // Startup stuff final Server server = new Server(port); WebAppContext webAppContext = new WebAppContext(path, "/") webAppContext.setInitParam( "org.eclipse.jetty.servlet.Default.useFileMappedBuffer", "false"); server.setHandler(webAppContext); server.start(); server.join(); 

DefaultServlet cercherà la propria copia di useFileMappedBuffer, che sembra essere impostata in profondità all’interno di Jetty. Ma anteponendo il nome della proprietà come sopra, questo valore è preferito.

Quando si utilizza Jetty 8.1.10 incorporato, l’impostazione ‘useFileMappedBuffer = false’ non funziona in nessuna modalità. Ho letto il codice per DefaultServlet e legge la proprietà ma non è utilizzato per nulla.

Invece ho guardato dove è stata configurata la creazione del buffer, e ho scoperto che potevo sottoclass SelectChannelConnector per ottenere i vantaggi di Continuation, ma senza bloccare i file su Windows. Se usi semplicemente org.mortbay.jetty.bio.SocketConnector , non avrai il supporto per la continuazione.

Ecco il mio esempio:

 import org.eclipse.jetty.io.Buffers.Type; import org.eclipse.jetty.server.nio.SelectChannelConnector; /** * A Connector that has the advantages NIO, but doesn't lock files in Windows by * avoiding memory mapped buffers. * 

* It used to be that you could avoid this problem by setting "useFileMappedBuffer" as described in * http://stackoverflow.com/questions/184312/how-to-make-jetty-dynamically-load-static-pages * However that approach doesn't seem to work in newer versions of jetty. * * @author David Roussel * */ public class SelectChannelConnectorNonLocking extends SelectChannelConnector { public SelectChannelConnectorNonLocking() { super(); // Override AbstractNIOConnector and use all indirect buffers _buffers.setRequestBufferType(Type.INDIRECT); _buffers.setRequestHeaderType(Type.INDIRECT); _buffers.setResponseBufferType(Type.INDIRECT); _buffers.setResponseHeaderType(Type.INDIRECT); } }

Ho provato questo per il problema di blocco e risolve il problema. Non ho ancora provato che funzioni con le Continuazioni.

Quando si utilizza IntelliJ e Jetty 9 con un ResourceHandler, una delle soluzioni consiste nel modificare il contenuto statico nella directory di destinazione, anziché nel file di origine.

Probabilmente è il browser che si sta aggrappando ad esso.

all’interno di IE: Strumenti | Opzioni Internet | File temporanei Internet> Impostazioni, fare clic sul pulsante Radio “Ogni visita alla pagina”. premere OK.

Prima di farlo, elimina tutti i file temporanei Internet.