web-dev-qa-db-ja.com

SwingがSpringBootではヘッドレスであると考えるのに、SpringやプレーンJavaではそうではないと考えるのはなぜですか?

次のコードが機能します。

import javax.swing.*;

public class HeadlessExceptionDemo {

   public static void main(String[] args) {

      JFrame frame = new JFrame("HeadlessExceptionDemo");
      frame.setSize(800, 600);
      frame.setLocationRelativeTo(null);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setVisible(true);

   }
}

次のコードも機能します。

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.swing.*;

@Configuration
public class HeadlessExceptionDemo {

   @Bean
   public JFrame frame() {
      JFrame frame = new JFrame("HeadlessExceptionDemo");
      frame.setSize(800, 600);
      frame.setLocationRelativeTo(null);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      return frame;
   }

   public static void main(String[] args) {

      AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(HeadlessExceptionDemo.class);
      JFrame frame = ctx.getBean(JFrame.class);
      frame.setVisible(true);

   }
}

次のコードはそうではありませんが:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;

import javax.swing.*;

@SpringBootApplication
public class HeadlessExceptionDemo {

    @Bean
    public JFrame frame() {
        JFrame frame = new JFrame("HeadlessExceptionDemo");
        frame.setSize(800, 600);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        return frame;
    }

    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(HeadlessExceptionDemo.class, args);
        JFrame frame = ctx.getBean(JFrame.class);
        frame.setVisible(true);
    }
}

以下の例外の原因:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.swing.JFrame]: Factory method 'frame' threw exception; nested exception is Java.awt.HeadlessException
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.Java:189) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.Java:588) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    ... 23 common frames omitted
Caused by: Java.awt.HeadlessException: null
    at Java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.Java:207) ~[na:1.8.0_45]
    at Java.awt.Window.<init>(Window.Java:536) ~[na:1.8.0_45]
    at Java.awt.Frame.<init>(Frame.Java:420) ~[na:1.8.0_45]
    at javax.swing.JFrame.<init>(JFrame.Java:233) ~[na:1.8.0_45]
    at com.inthemoon.snippets.springboot.HeadlessExceptionDemo.frame(HeadlessExceptionDemo.Java:15) [classes/:na]
    at com.inthemoon.snippets.springboot.HeadlessExceptionDemo$$EnhancerBySpringCGLIB$$3680a05b.CGLIB$frame$0(<generated>) ~[classes/:na]
    at com.inthemoon.snippets.springboot.HeadlessExceptionDemo$$EnhancerBySpringCGLIB$$3680a05b$$FastClassBySpringCGLIB$$b7def9bc.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.Java:228) ~[spring-core-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.Java:355) ~[spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at com.inthemoon.snippets.springboot.HeadlessExceptionDemo$$EnhancerBySpringCGLIB$$3680a05b.frame(<generated>) ~[classes/:na]
    at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_45]
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62) ~[na:1.8.0_45]
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43) ~[na:1.8.0_45]
    at Java.lang.reflect.Method.invoke(Method.Java:497) ~[na:1.8.0_45]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.Java:162) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    ... 24 common frames omitted

どうして? :)

13
Dims

Spring Bootは、 SpringApplication.Java のソースコードに見られるように、デフォルトでJava.awt.headlesstrueに設定します。

private boolean headless = true;

...

private void configureHeadlessProperty() {
        System.setProperty(SYSTEM_PROPERTY_Java_AWT_HEADLESS, System.getProperty(
                SYSTEM_PROPERTY_Java_AWT_HEADLESS, Boolean.toString(this.headless)));
}

これを行う理由については、setHeadlessメソッドのソースコードに、アイコンが表示されないようにすることについてのコメントがあります。

    /**
     * Sets if the application is headless and should not instantiate AWT. Defaults to
     * {@code true} to prevent Java icons appearing.
     * @param headless if the application is headless
     */
    public void setHeadless(boolean headless) {
        this.headless = headless;
    }
7
jonathan.cone

この行の代わりに

 SpringApplication.run(Application.class, args);

使用する

SpringApplicationBuilder builder = new SpringApplicationBuilder(Application.class);

    builder.headless(false);
    ConfigurableApplicationContext context = builder.run(args);
3
VRadhe