Proviso:请不要将数据库用于以下内容。
我收到了一个封闭的套接字异常,我将其归因于在localhost上运行的leafnode的延迟。预计会有延迟,我只是不确定如何处理它。
我知道,从单独的CLI程序中,leafnode正确回复并且实用程序类正在运行。对于这个应用程序,我可以从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消息最终会被加载。它只是它似乎没有及时回到bean,或者,如果它确实回来,它可能是bean的错误实例。我推断第一个bean通过正常,但另一个bean得到套接字问题因为Leafnode很忙。看起来bean构造函数被多次调用,这当然没问题,但可能就是第二个bean关闭套接字的原因。
那么,我如何隔离延迟问题,以便任何MessageBean获取,错误,?枚举单例? 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类,该类与localhost上的leafnode进行交互,因此它在CLI中非常快。但是,对于facelets而言,显然不够快,因为我一直遇到套接字错误。
从日志记录到Glassfish,我看到leafnode正确地将文章返回到实用程序类,并且最终,MessageBean甚至有一个大的List。
问题似乎是,应该存在多个MessageBean实例。然而,他们并不是所有人都能够同时查询leafnode,大概是成功的。也许这是套接字错误的来源。
无论如何,我不想将javax.mail.Message持久存储到数据库中,leafnode已经将消息保留得很好。我严格要在localhost上与leafnode接口。
我需要一些可怕的枚举单身人士吗?这是我所知道的唯一“模式”,所以我认为它必须适用于这种情况。或者,是否有一些替代方法来减慢MessageBean,以确保它实际上从实用程序NNTP类获取其消息,然后将它们传递给facelet?或者,这种延迟会导致某种错误吗?
这里有什么好方法?我不打算构建一个功能齐全的NNTP客户端,只是摆弄了一个有一些延迟的leafnode。
解决方案:关闭套接字properly并使用容器类,如下面的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);
}
}
}
答案 0 :(得分:1)
根据我对您的问题的理解,您实际上需要对NNTP.getMessages()
进行同步并发访问。如果是这样,并且您在EJB上下文中使用托管bean,我相信Managing Concurrent Access in a Singleton Session Bean可以帮助您。如果没有直接帮助,我相信您可以利用ReentrantLock
来测试对NNTP
的并发控制是否可以解决问题。