Синхронизация бина @Named с localhost - PullRequest
0 голосов
/ 02 апреля 2012

Proviso: я не хочу использовать базу данных для следующего, пожалуйста.

Я получаю исключение закрытого сокета, которое я приписываю задержке из-за leafnode, работающего на localhost. Ожидается, что будет задержка, я просто не знаю, как с этим справиться.

Я знаю, что из отдельной программы CLI этот узел отвечает правильно и что класс утилит работает. Для этого приложения, я могу видеть из журналов Glassfish:

nntp: <68 <x1-QQumhvcthNpaS3eWCQlR7Bleszk@gwene.org>
nntp: <69 <x1-N15vT7mtEkMzewjHjlTmjzBSpFY@gwene.org>
nntp: <70 <x1-cfsH29WrlKvYMd+t1ohsVSekIy0@gwene.org>
nntp: <71 <x1-DaQK7LTcaCQP3O3Us+8HTxTDALQ@gwene.org>
nntp: <72 <x1-1+PG1MuOkVUmzmY2XWRAWCKwbD8@gwene.org>
nntp: <73 <x1-sXoWsN3I56qalgUJAuT6+jWCYLE@gwene.org>
nntp: <74 <x1-osEXmt5CXnwu3eVGVAb4e11PZnY@gwene.org>
nntp: <.
nntp: >QUIT
nntp: <205 Always happy to serve!
INFO: GOT MESSAGES AS SO..
INFO: [gnu.mail.providers.nntp.NNTPMessage@1e2218b, gnu.mail.providers.nntp.NNTPMessage@10838ec, gnu.mail.providers.nntp.NNTPMessage@d14f1b, gnu.mail.providers.nntp.NNTPMessage@1a0b187, gnu.mail.providers.nntp.NNTPMessage@e74409, gnu.mail.providers.nntp.NNTPMessage@123ce36, gnu.mail.providers.nntp.NNTPMessage@1b7515a, gnu.mail.providers.nntp.NNTPMessage@3e0a57, gnu.mail.providers.nntp.NNTPMessage@118d5e0, gnu.mail.providers.nntp.NNTPMessage@1819b07, gnu.mail.providers.nntp.NNTPMessage@1e91886, gnu.mail.providers.nntp.NNTPMessage@493ab5, gnu.mail.providers.nntp.NNTPMessage@1ad7ec5, gnu.mail.providers.nntp.NNTPMessage@15dbf8d, gnu.mail.providers.nntp.NNTPMessage@1cae695, gnu.mail.providers.nntp.NNTPMessage@1e86f47, gnu.mail.providers.nntp.NNTPMessage@e1d295, gnu.mail.providers.nntp.NNTPMessage@1c87547, gnu.mail.providers.nntp.NNTPMessage@18b9691, gnu.mail.providers.nntp.NNTPMessage@14a0c6f, gnu.mail.providers.nntp.NNTPMessage@765340, gnu.mail.providers.nntp.NNTPMessage@53b2e4, gnu.mail.providers.nntp.NNTPMessage@10597ed, gnu.mail.providers.nntp.NNTPMessage@396c01, gnu.mail.providers.nntp.NNTPMessage@1e1f03d, gnu.mail.providers.nntp.NNTPMessage@63410a, gnu.mail.providers.nntp.NNTPMessage@433231, gnu.mail.providers.nntp.NNTPMessage@1945928, gnu.mail.providers.nntp.NNTPMessage@696ea0, gnu.mail.providers.nntp.NNTPMessage@1dde855, gnu.mail.providers.nntp.NNTPMessage@1c0559e, gnu.mail.providers.nntp.NNTPMessage@352a35, gnu.mail.providers.nntp.NNTPMessage@660b04, gnu.mail.providers.nntp.NNTPMessage@15d401f, gnu.mail.providers.nntp.NNTPMessage@11cddfb, gnu.mail.providers.nntp.NNTPMessage@31917d, gnu.mail.providers.nntp.NNTPMessage@46be43, gnu.mail.providers.nntp.NNTPMessage@7523ed, gnu.mail.providers.nntp.NNTPMessage@89a405, gnu.mail.providers.nntp.NNTPMessage@6f5b1b, gnu.mail.providers.nntp.NNTPMessage@c649d6, gnu.mail.providers.nntp.NNTPMessage@19882d, gnu.mail.providers.nntp.NNTPMessage@3b8201, gnu.mail.providers.nntp.NNTPMessage@d44937, gnu.mail.providers.nntp.NNTPMessage@112e45c, gnu.mail.providers.nntp.NNTPMessage@14e8cfc, gnu.mail.providers.nntp.NNTPMessage@a15e3, gnu.mail.providers.nntp.NNTPMessage@22f041, gnu.mail.providers.nntp.NNTPMessage@1cb71d7, gnu.mail.providers.nntp.NNTPMessage@19ee882, gnu.mail.providers.nntp.NNTPMessage@1b2d490, gnu.mail.providers.nntp.NNTPMessage@1a16b05, gnu.mail.providers.nntp.NNTPMessage@79412e, gnu.mail.providers.nntp.NNTPMessage@a66063, gnu.mail.providers.nntp.NNTPMessage@10203ea, gnu.mail.providers.nntp.NNTPMessage@14f0db5, gnu.mail.providers.nntp.NNTPMessage@10ceef3, gnu.mail.providers.nntp.NNTPMessage@1bc33e, gnu.mail.providers.nntp.NNTPMessage@af5b1a, gnu.mail.providers.nntp.NNTPMessage@860956, gnu.mail.providers.nntp.NNTPMessage@1cf1146, gnu.mail.providers.nntp.NNTPMessage@1770fb1, gnu.mail.providers.nntp.NNTPMessage@1a76bc3, gnu.mail.providers.nntp.NNTPMessage@940c94, gnu.mail.providers.nntp.NNTPMessage@1c5d10c, gnu.mail.providers.nntp.NNTPMessage@1fa00d, gnu.mail.providers.nntp.NNTPMessage@44ecf0, gnu.mail.providers.nntp.NNTPMessage@11f88e8, gnu.mail.providers.nntp.NNTPMessage@1554648, gnu.mail.providers.nntp.NNTPMessage@17921a7, gnu.mail.providers.nntp.NNTPMessage@1905dbf, gnu.mail.providers.nntp.NNTPMessage@fad175]
INFO: ..GOT MESSAGES AS SO

что сообщения NNTP, в конечном счете, загружаются. Просто кажется, что он не возвращается вовремя к бобу, или, если он возвращается, это может быть неправильный экземпляр боба. Я предполагаю, что первый компонент проходит нормально, но другой компонент получает проблему с сокетом, потому что Leafnode занят. Похоже, конструктор бина вызывается более одного раза, что, конечно, нормально, но может быть поэтому сокет закрыт для второго бина.

Итак, как мне изолировать проблему задержки так, чтобы любой MessageBean получил, err,? Enum singleton? javax.mail.Message правильно? (Я использую библиотеку GNU NNTP, которая намного лучше, чем Apache, и работает нормально.)

Вот клиент Facelets:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
                template="./template.xhtml"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:c="http://java.sun.com/jsp/jstl/core"
                xmlns:f="http://java.sun.com/jsf/core">
    <ui:define name="left">
        <h:button id="submit" value="click me" />
    </ui:define>
    <ui:define name="content">
        <ui:repeat value="#{messageBean.messages}" var="message">
            <li>
                <h:outputText value="#{message.messageNumber}" />
                <h:outputText value="#{message.subject}" />
            </li>
        </ui:repeat>
    </ui:define>
</ui:composition>

и вспомогательный MessageBean как так:

package net.bounceme.dur.nntp;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import javax.mail.Message;

@Named
@SessionScoped
public class MessageBean implements Serializable {

    private static final long serialVersionUID = 1;
    private static Logger logger = Logger.getLogger(MessageBean.class.getName());
    private static Level level = Level.INFO;

    public MessageBean() {
        logger.log(level, "MessageBean..");
    }

    public List<Message> getMessages() throws Exception {
        logger.log(level, "MessageBean.getMessages..");
        List<Message> messages = new ArrayList<Message>();
        messages = NNTP.getMessages();
        logger.log(level, "GOT MESSAGES AS SO..");
        logger.log(level, messages.toString());
        logger.log(level, "..GOT MESSAGES AS SO");
        return messages;
    }
}

Теперь MessageBean вызывает служебный класс NNTP, который взаимодействует с листовым узлом на локальном хосте, так что это довольно быстро из CLI. Тем не менее, недостаточно быстро, по-видимому, для facelets, потому что я продолжаю получать ошибки сокета.

От входа в Glassfish, я вижу, что leafnode правильно возвращает статьи в служебный класс, и что, в конце концов, MessageBean даже имеет большой список.

Проблема заключается в том, что, возможно, существует несколько экземпляров MessageBean, как и должно быть. Тем не менее, не все они смогут одновременно запрашивать конечные узлы и быть успешными. Возможно, это источник ошибки сокета.

В любом случае я не хочу сохранять javax.mail.Message в базе данных, leafnode уже хорошо сохраняет сообщения. Я строго хочу взаимодействовать с leafnode на localhost.

Нужен ли мне какой-нибудь ужасный синглтон enum? Это единственный «шаблон», который я знаю, поэтому я считаю, что он должен применяться в этом сценарии. Или есть какой-то альтернативный способ замедлить MessageBean, чтобы быть уверенным, что он на самом деле получает свои сообщения от служебного класса NNTP, прежде чем передавать их в лицевую сторону? Или такая задержка может вызвать какую-то ошибку?

Какой хороший подход здесь? Я не пытаюсь создать полнофункциональный NNTP-клиент, просто возиться с листовым узлом, который имеет некоторую задержку.

-----------------------------------

решение: правильно закройте сокеты и используйте класс контейнера, как показано в setEntities ниже:

package net.bounceme.dur.nntp;

import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.*;

public enum SingletonNNTP {

    INSTANCE;
    private final Logger logger = Logger.getLogger(SingletonNNTP.class.getName());
    private final Level level = Level.INFO;
    private Properties props = new Properties();
    private List<Message> messages = new ArrayList<Message>();
    private boolean loaded = false;
    private List<MessageEntity> messageEntities = new ArrayList<MessageEntity>();

    private SingletonNNTP() {
        logger.logp(level, "SingletonNNTP", "SingletonNNTP", "only once...");
        props = PropertiesReader.getProps();
        if (!loaded) {
            try {
                loaded = setMessages();
            } catch (Exception ex) {
                Logger.getLogger(SingletonNNTP.class.getName()).log(Level.SEVERE, "FAILED TO LOAD MESSAGES", ex);
            }
        }
    }

    public List<Message> getMessages(boolean debug) throws Exception {
        logger.logp(level, "SingletonNNTP", "getMessages", "returning messages");
        return Collections.unmodifiableList(messages);
    }

    private boolean setMessages() throws Exception {
        logger.logp(level, "SingletonNNTP", "setMessages", "connecting to leafnode");
        Session session = Session.getDefaultInstance(props);
        session.setDebug(false);
        Store store = session.getStore(new URLName(props.getProperty("nntp.host")));
        store.connect();
        Folder root = store.getDefaultFolder();
        Folder folder = root.getFolder(props.getProperty("nntp.group"));
        folder.open(Folder.READ_ONLY);
        Message[] msgs = folder.getMessages();
        messages = Arrays.asList(msgs);
        setEntities();
        folder.close(false);
        store.close();
        return true;
    }

    public List<MessageEntity> getEntities() {
        logger.logp(level, "SingletonNNTP", "getEntities", "getting entities");
        for (MessageEntity m : messageEntities) {
            for (Header h : m.getHeaders()) {
                logger.log(level, h.toString());
            }
        }
        return Collections.unmodifiableList(messageEntities);
    }

    private void setEntities() throws Exception {
        logger.logp(level, "SingletonNNTP", "loadEntities", "trying to convert");
        messageEntities = new ArrayList<MessageEntity>();
        for (Message message : messages) {
            MessageEntity entity = new MessageEntity();
            Enumeration allHeaders = message.getAllHeaders();
            List<Header> headers = new ArrayList<Header>();
            while (allHeaders.hasMoreElements()) {
                Header hdr = (Header) allHeaders.nextElement();
                headers.add(hdr);
            }
            entity.setHeaders(headers);
            entity.setSubject(message.getSubject());
            entity.setContent(message.getContent().toString());
            entity.setSentDate(message.getReceivedDate());
            messageEntities.add(entity);
        }
    }
}

1 Ответ

1 голос
/ 02 апреля 2012

Из того, что я понимаю из вашей проблемы, вам действительно нужно иметь синхронизированный одновременный доступ к NNTP.getMessages(). Если это так, и вы используете управляемые bean-компоненты в контексте EJB, я считаю, что Управление параллельным доступом в компоненте Singleton Session Bean может вам помочь. Если это не очень полезно, я полагаю, что вы можете воспользоваться ReentrantLock, чтобы проверить, может ли одновременный контроль над NNTP решить проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...