Java サーブレット ベースのアプリケーションからいくつかの画像を動的に生成する必要があります。ハードコードされた位置と Graphics2D.drawString を使用するよりもレイアウトをメンテナンスしやすいものにしたかったので、そのために AWT/Swing レイアウトを使用すると考えました。
これは私の Windows 開発マシン (JFrame を作成し、コンポーネントを追加し、.pack() フレームを作成し、BufferedImage を component.paint() に渡してレンダリングします。.setVisible(true) を呼び出していないことに注意してください) で問題なく動作します。(注 - JFrame を使用する唯一の理由は、.pack() を呼び出すためのものです。それ以外の場合は、おそらくもっと軽量なものを使用できます。)
ただし、Elastic Beanstalk で管理されている AWS EC2 Tomcat7 マシンでは java.awt.HeadlessException で失敗します。
java.awt.HeadlessException
at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:173)
at java.awt.Window.<init>(Window.java:477)
at java.awt.Frame.<init>(Frame.java:419)
at javax.swing.JFrame.<init>(JFrame.java:218)
最初の質問 (廃止): X11 をインストールしなくても動作する可能性はありますか? はいの場合、「java.awt.headless」を何に設定すればよいですか? 「true」を使用すると、現在失敗している場所で失敗します。「false」を使用すると、ネイティブコードが実際にウィンドウシステムを使用しようとする他の場所で失敗しますか?
2 番目の質問: この「java.awt.headless」プロパティ (EBS 環境の場合) を設定するにはどうすればよいですか?
これまでのところ、次のことを行っているためです。
私の .ebextensions / .config に以下を追加しました:
option_settings:
- namespace: aws:elasticbeanstalk:container:tomcat:jvmoptions
option_name: Djava.awt.headless
value: false
/etc/tomcat7/tomcat7.conf を編集し、そこに以下を配置します。
JAVA_OPTS="-Djava.awt.headless=false"
それにもかかわらず、再デプロイ/Tomcat の再起動後、Tomcat に渡された JVM オプションは「java.awt.headless=true」のようです。
[ec2-user@ip-address ~]$ sudo ps aux | grep headless
tomcat 7200 12.6 45.4 1406724 276604 ? Sl 23:02 0:47 /usr/lib/jvm/jre/bin/java -DPARAM3= -DPARAM4= -DPARAM1=production_worker.properties -DPARAM2= -DJDBC_CONNECTION_STRING= -DPARAM5= -DAWS_SECRET_KEY= -DAWS_ACCESS_KEY_ID= -XX:MaxPermSize=64m -Xmx512m -Xms512m -classpath :/usr/share/tomcat7/bin/bootstrap.jar:/usr/share/tomcat7/bin/tomcat-juli.jar:/usr/share/java/commons-daemon.jar -Dcatalina.base=/usr/share/tomcat7 -Dcatalina.home=/usr/share/tomcat7 -Djava.awt.headless=true -Djava.endorsed.dirs= -Djava.io.tmpdir=/var/cache/tomcat7/temp -Djava.util.logging.config.file=/usr/share/tomcat7/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager org.apache.catalina.startup.Bootstrap start
さらに、私のコードはまだプロパティが設定されていることをまったく検出していません。
log.error("java.awt.headless=", System.getProperty("java.awt.headless"));
これは以下を出力します:
2013-01-14 22:13:17,421 +0000 [http-bio-8080-exec-4] ERROR ServiceImpl:45 - java.awt.headless=
編集 - 私も持っていました
System.setProperty("java.awt.headless", "false");
しかし、これも役に立たなかったようです。
Edit2 - JFrame を廃止し、代わりに JPanel をインスタンス化しました。これにより、ヘッドレス環境でレンダリングできるようになりました。
ただし、レイアウトを適切に行う方法がわかりません。さまざまなレイアウトで doLayout を呼び出し続け、コンポーネントで something.setSize(something.getPreferredSize()) を呼び出し続けていますが、とにかく結果が重複しているか、ラベルが表示されていません。JFrame.pack() を呼び出さなくなったためです (呼び出す JFrame がないため)。
3 番目の質問 - .pack() を呼び出す JFrame がなくても JPanel が適切にレイアウトされるようにするにはどうすればよいですか?
Edit3 - 3 番目の質問に対する答えは、 panel.addNotify(); を呼び出すことです。panel.setSize(panel.getPreferredSize()); panel.validate(); これは Andrew Thomson のおかげです:
JPanel (w/o JFrame) から BufferedImage を作成する場合、レイアウト マネージャーも使用できますか?