Glassfish 4 - Using the Concurrency API to Create Managed Threads

I am trying to use the new Concurrency API to enter ManagedThreadFactory and use it for an Oracle tutorial .

Here is an example of what I am saying:

@Singleton
@Startup
public class Demo {
    @Resource(name="concurrent/__DefaultManagedThreadFactory") ManagedThreadFactory threadFactory;

    @PostConstruct
    public void startup() {
        threadFactory.newThread(
            new Runnable() {
                @Override
                public void run() {
                    System.out.println("Do something.");
                }
            }
        ).start();
    }
}

I am developing in Eclipse using the Glassfish plugin. When I republish after making changes, I always get this line in the server log. It appears once for each start () call we make:

SEVERE: java.lang.IllegalStateException: Module (my application) is disabled

In fact, this does not throw an IllegalStateException, simply reporting that it was thrown (and caught) inside Glassfish. The application deploys normally, but none of the threads start. If I subsequently reprint it a second time, the “error” will disappear and the threads will start as expected.

"" Glassfish ( Eclipse), , "". - ( ).

API Concurrency? ? , ManagedExcecutorService.


: ManagedThread Singleton Enterprise Java Bean?, , , - , . !


UPDATE: Per-Axel Felth . ! , :

@Singleton
@Startup
public class Demo {

    @Resource(name="java:comp/DefaultManagedThreadFactory") ManagedThreadFactory threadFactory;
    @EJB private ConcurrencyInitializer concurrencyInitializer;
    @EJB private Demo self;

    @PostConstruct
    public void startup() {
        self.startThread();
    }

    @Asynchronous
    public void startThread() {
        //This line applies the workaround
        concurrencyInitializer.init();

        //Everything beyond this point is my original application logic
        threadFactory.newThread(
            new Runnable() {
                @Override
                public void run() {
                    System.out.println("Do something.");
                }
            }
        ).start();            
    }

}

 

/**
 * A utility class used to get around a bug in Glassfish that allows
 * Concurrency resources (ManagedThreadFactory, ManagedExecutorService, etc)
 * to be injected before they are ready to be used. 
 * 
 * Derived from solution by Per-Axel Felth in: https://stackoverflow.com/questions/23900826/glassfish-4-using-concurrency-api-to-create-managed-threads
 */
@Singleton
public class ConcurrencyInitializer {
    /**
     * The number of milliseconds to wait before try to 
     */
    public static final long RETRY_DELAY = 500L;

    /**
     * The maximum number of concurrency attempts to make before failing
     */
    public static final int MAX_RETRIES = 20;

    /**
     * Repeatedly attempts to submit a Runnable task to an injected ManagedExecutorService
     * to trigger the readying of the Concurrency resources.
     * 
     * @return true if successful (Concurrency resources are now ready for use),
     *         false if timed out instead
     */
    public boolean init() {
        final AtomicBoolean done = new AtomicBoolean(false);
        int i = 0;

        try {
            while (!done.get() && i++ < MAX_RETRIES) {
                executorService.submit(new Runnable() {
                    @Override
                    public void run() {
                        done.set(true);
                    }
                });
                Thread.sleep(RETRY_DELAY);
            }
        } catch(InterruptedException e) {
            //Do nothing.
        } 

        return done.get();
    }
}
+4
2

Glassfish. . , factory , " ", IllegalStateException.

. -, , , concurrency utils , init.

@Singleton
@Startup
public class Demo {

    @Resource(name = "concurrent/__DefaultManagedThreadFactory")
    ManagedThreadFactory threadFactory;
    @Resource
    ManagedExecutorService executorService;
    @EJB
    Demo me;

    @PostConstruct
    public void startup() {

        me.waitAndInitialize();
    }

    @Asynchronous
    public Future<?> waitAndInitialize() {
        try {
            final AtomicInteger done = new AtomicInteger(0);
            int i = 0;

            while (done.intValue() == 0 && i < 20) {
                System.out.println("Is executor service up?");

                i++;

                executorService.submit(
                        new Runnable() {

                            @Override
                            public void run() {
                                int incrementAndGet = done.incrementAndGet();
                                System.out.println("Run by executorservice");
                            }
                        });
                Thread.sleep(500);
            }

            if (done.intValue() == 0) {
                Logger.getAnonymousLogger().severe("Waited a long time for the ExecutorService do become ready, but it never did. Will not initialize!");
            } else {
                init();
            }
        } catch (Exception e) {
            Logger.getAnonymousLogger().log(Level.SEVERE, "Exception in waitAndInitialize: " + e.getMessage(), e);
        }

        return new AsyncResult<>(null);
    }

    private void init() {
        threadFactory.newThread(
                new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("Do something.");
                    }
                }
        ).start();
    }
}
+2

, ManagedThreadFactory , "Demo" .

Java EE 7 , factory JNDI "java: comp/DefaultManagedThreadFactory", @Resource

@Resource(name="java:comp/DefaultManagedThreadFactory")

Glassfish ( WildFly), JNDI. "concurrent/__ DefaultManagedThreadFactory" ( btw).

@Resource(lookup="concurrent/__DefaultManagedThreadFactory")
0

Source: https://habr.com/ru/post/1542257/


All Articles