web-dev-qa-db-ja.com

Jettyに「静的」ページを動的にロードさせる方法

私はJava Webアプリケーションを構築していますが、従来の「コード-コンパイル-デプロイ-テスト」サイクルが嫌いです。小さな変更を1つ入力して、結果をすぐに確認したいのですが、コンパイルしてデプロイします。

幸いなことに、 Jetty はこれに最適です。これは純粋なJavaWebサーバーです。それは本当に素晴らしい mavenプラグイン が付属しており、ビルドツリーから直接Jetty読み取りを起動できます-warファイルをパッケージ化したりデプロイしたりする必要はありません。 scanInterval設定もあります。これをゼロ以外の値にすると、Javaファイルとさまざまな構成ファイルの変更を監視し、変更を加えてから数秒後に自動的に再デプロイされます。 。

私を涅槃から遠ざけることが一つだけあります。 src/main/webappディレクトリにjavascriptファイルとcssファイルがあり、Jettyによって提供されます。これらこれらを編集して、ブラウザでページを更新したときに変更が表示されるようにしたいと思います。残念ながら、Jettyはこれらのファイルを開いたままにしているため、実行中に(Windowsでは)変更できません。

Jettyにこれらのファイルを手放して編集できるようにし、編集したファイルを後続のリクエストに提供する方法を知っている人はいますか?

28
mcherm

Jettyは、メモリマップファイルを使用して静的コンテンツをバッファリングします。これにより、Windowsでファイルがロックされます。 DefaultServletのuseFileMappedBufferをfalseに設定してみてください。

Windowsでのロックされたファイルのトラブルシューティング(Jetty wikiから) 手順があります。

18
Athena

上記の答えの1つはxmlでjettyを構成するのに正確に正しいですが、コードでこのオプションを構成する場合(組み込みサーバーの場合)、答えは異なり、そのページにはありません。

あなたは含む多くの提案をオンラインで見つけるでしょう

context.getInitParams()。put( "useFileMappedBuffer"、 "false");

または、WebAppContextをオーバーライドするか、initパラメーターに完全修飾名を使用します。これらの提案はどれも私にはうまくいきませんでした(Jetty 7.2.2を使用)。問題の一部は、useFileMappedBufferオプションを、コンテキストではなく、WebAppContextが静的ファイルを提供するために使用しているサーブレットに設定する必要があることでした。

結局、私は単純な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();
16
kybernetikos

これは古い問題ですが、私は this 投稿が非常に役立つことがわかりました。つまり、構成を次のように変更するだけです。

            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <configuration>
                <connectors>
                    <connector implementation="org.Eclipse.jetty.server.bio.SocketConnector">
                        <port>8080</port>
                    </connector>
                </connectors>
                </configuration>
            </plugin>

これにより、JettyでのNIOサポートが無効になります(ただし、単純なケースのデバッグ目的では問題にはなりません)。

10
FUD

Jetty 9.2ドキュメント は、サーブレットの代わりにResourceHandlerを使用して静的ファイルを提供するJettyEmbeddedの例を示しています。

// 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はNIO(メモリ内ファイルマッピング)を使用するため、 Windowsオペレーティングシステムでファイルをロックします 。これは既知の問題であり、サーブレットには多くの回避策があります。

ただし、この例はサーブレットに依存していないため、webappパラメーター(useFileMappedBuffer、maxCachedFiles)に基づく関連する回答は機能しません。

インメモリファイルマッピングを防ぐには、次の構成行を追加する必要があります。

resource_handler.setMinMemoryMappedContentLength(-1);

注:Javadocに記述されているように(そして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。ただし、値Integer.MAX_VALUEで同じ動作が発生しました。

このパラメーターを設定すると、JettyはWindowsで静的ファイルを提供し、それらを編集できます。

7
Julien Kronegg

Webdefault.xmlでuseFileMappedBufferにfalseを設定すると、[〜#〜] not [〜#〜]は機能しました(Jetty 8.1.10.v20130312)。幸い、maxCachedFilesを0に設定すると(webdefault.xmlでも)、うまくいきました。

5
Jakub Torbicki

私もこの問題を抱えていました。

そして、追加のクラスを作成してweb.xmlをいじりたくありませんでした

だからここにあなたができることがあります:

プロジェクトがMavenベースであり、(たとえば)「my-web-app」と呼ばれていると仮定します。

1)ファイルmy-web-app/jetty /jetty-config.xmlを作成します

2)このようなものを中に入れます:

<?xml version="1.0" encoding="UTF-8"?>
<Configure class="org.Eclipse.jetty.webapp.WebAppContext">
  <Call name="setInitParameter">
    <Arg>org.Eclipse.jetty.servlet.Default.useFileMappedBuffer</Arg>
    <Arg>false</Arg>
  </Call>
</Configure>

3)これがあなたの桟橋の設定です:

<plugin>
    <groupId>org.Eclipse.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <configuration>
            <httpConnector>
                <Host>localhost</Host>
                <port>8801</port>
            </httpConnector>
            <webApp>
                <contextPath>/${project.artifactId}</contextPath>
            </webApp>
        <contextXml>${project.basedir}/jetty/jetty-config.xml</contextXml>
    </configuration>
</plugin>

このソリューションは、静的リソースのロックを無効にする属性をサーブレットコンテキストに追加します。

楽しんで :)

4

@kybernetikosの回答に似ていますが、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は、Jettyの奥深くに設定されているように見えるuseFileMappedBufferの独自のコピーを探します。ただし、プロパティ名の前に上記のようにすることで、この値が優先されます。

4

埋め込みJetty8.1.10を使用する場合、「useFileMappedBuffer = false」設定はどのモードでも機能しません。 DefaultServletのコードを読み、プロパティを読み取りましたが、何にも使用されていません。

代わりに、バッファーの作成が構成されている場所を調べたところ、SelectChannelConnectorをサブクラス化して継続のメリットを得ることができましたが、Windowsでファイルをロックする必要はありませんでした。単にorg.mortbay.jetty.bio.SocketConnectorを使用すると、継続サポートは受けられません。

これが私の例です:

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.
 * <p> 
 * 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);
    }
}

私はこれをロックの問題についてテストしました、そしてそれは問題を修正します。継続で動作することはまだテストしていません。

0
David Roussel