我正在使用 java-ee websockets 实现一个小型聊天应用程序。
有一次,由于各种原因,我想关闭客户端的会话,以便关闭连接。
为了关闭连接,我调用了onClose
函数,并在该函数中调用了session.close()
但之后我收到以下错误:
java.lang.IllegalStateException: The WebSocket session has been closed and no method (apart from close()) may be called on a closed session
at org.apache.tomcat.websocket.WsSession.checkState(WsSession.java:643)
at org.apache.tomcat.websocket.WsSession.addMessageHandler(WsSession.java:168)
at org.apache.tomcat.websocket.pojo.PojoEndpointBase.doOnOpen(PojoEndpointBase.java:81)
at org.apache.tomcat.websocket.pojo.PojoEndpointServer.onOpen(PojoEndpointServer.java:70)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:129)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:629)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Run Code Online (Sandbox Code Playgroud)
我不确定我做错了什么,也不知道为什么会出现这个异常。
使用 JPA 2.1 和 hibernate 5.1.x,这可以使用 JPQL
select s.lowerBound,
l.status
...
from Serie s
left join Line l on
s.lowerBound between l.lineStart and l.lineEnd
Run Code Online (Sandbox Code Playgroud)
我如何使用 Criteria api 编写这个?我试过这个
Root<Serie> serieRoot = query.from(Serie.class);
Root<Line> lineRoot query.from(Line.class);
query.where(criteriaBuilder.between(s.get("lowerBound"), l.get("lineStart"), s.get("lineEnd")))
Run Code Online (Sandbox Code Playgroud)
但这不允许我指定它是左连接。
我正在尝试迁移某些 JSON 数据绑定代码的实现细节,以使用 Java EE 8 JSON-B API 而不是 Jackson。
为了匹配 Jackson 的默认行为,当 JSON 负载包含无法识别的属性时,我想拒绝将 JSON 负载反序列化为 POJO 的任何尝试。
例如,如果我有以下 JSON 数据:
{
"name": "Bob",
"extraProp": "Something"
}
Run Code Online (Sandbox Code Playgroud)
我有以下 Java 对象可以将此数据建模为:
public class Thing {
public String name;
// no mention of "extraProp"
}
Run Code Online (Sandbox Code Playgroud)
我如何拒绝将上述 JSON 数据绑定到上述 POJO 的尝试?
如果我尝试以下操作,则Thing
创建的对象不会出错(这里我希望发生错误):
Jsonb jsonb = JsonbProvider.provider()
.create()
.build();
Thing t = jsonb.fromJson("{\"name\":\"Bob\",\"extraProp\":\"Something\"}", Thing .class);
Run Code Online (Sandbox Code Playgroud) 我在 Wildfly 10.10 中运行的单例 EJB 中有一个 EJB 计时器计划:
@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class MySingletonBean {
public method() {
//uses synchronization primitives to fine control the concurrent access
}
@Schedule(hour = "*", minute = "*", second = "*", persistent = false)
public void update() {
//each 120 seconds update method timeouts and the overlapping/log message occurs
}
}
Run Code Online (Sandbox Code Playgroud)
update() 模型中的任务运行流畅,大部分时间不到 1 秒。然而每2分钟,由于业务需要,该方法超时花费超过1秒。
问题:
每 2 分钟wildfly 输出一条日志消息,如:
(EJB 默认值 - 1)WFLYEJB0043:定时器 [] 的先前执行仍在进行中,跳过此重叠的计划执行:
我很清楚这条消息的含义:在下一次执行开始之前前一个计时器没有完成并且发生重叠。
此外,重叠会在正在更新的基础数据结构中引发并发问题。
我的问题:
1 - 如何在计时器缓慢的情况下放弃下一个计划以避免重叠/并发更新?
2 - …
我最近实现了简单的 JAX-RS REST 端点。我想知道是否有任何透明的集成测试方式?
我在 stackowerflow 上搜索了一下,发现了这些问题:first,second。它们有点过时了,我希望已经有一些更好的测试方法。那里提出的解决方案并没有解决我的问题,因为它们提供了特定于供应商的方法或一些复杂的第三方方法。
问:测试 JAX-RS 服务的现代方法是什么?Java EE 是否为此提供了解决方案?或者一般来说,在 Java EE 生态系统中编写控制器测试的最佳方式是什么?
更具体地说,我正在寻找某种可以轻松测试 REST 调用的方法。在 spring 框架中,它通常是这样的:
@Autowired
MockMvc mvc;
@MockBean
MyService service;
@Test
public void shouldGetMyDto() {
MyDto dto = new MyDto("test-id", "test-name");
given(service.getMyDto("test-id")).willReturn(dto);
mvc.perform(get("/api/my-entities/test-id"))
.andExpect(status().isOk())
.andExpect(content().contentType(APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("$.id", is("test-id")))
.andExpect(jsonPath("$.name", is("test-name")));
verify(service).getMyDto("test-id");
}
Run Code Online (Sandbox Code Playgroud) 我正在开发一个在 IBM WebSphere Application Server 上的集群 Java EE 环境中运行的应用程序。我们有一个启动单例 bean,它创建一个持久的 EJB 计时器,我们配置了 EJB 计时器服务,以便每个集群节点使用相同的数据库表。如何确保 2 个节点在启动时不会同时创建持久计时器?我知道如何确保只有一个节点实际运行超时方法,但不知道如何确保计时器不会被创建两次。
我们目前正在启动时取消并重新创建所有具有相同“名称”的计时器,这意味着(如果我理解正确的话),只要集群节点没有同时初始化这个 bean,那么最后一个启动的节点将清除任何现有的计时器并重新创建单个计时器实例。但是,我如何确保我们避免 2 个节点同时退出该cancelTimer()
方法并且都运行该TimerService.createTimer()
方法的罕见情况,为集群创建 2 个相同的计时器?
下面是一些示例代码:
@Startup
@Singleton
public class Timer{
String timerName = "myTimer";
@Resource
private SessionContext sessionCtx;
@PostConstruct
public void start() {
cancelTimer();
TimerService ts = sessionCtx.getTimerService();
ts.createTimer(new Date(), 60000, timerName);
}
@PreDestroy
public void stop() {
cancelTimer();
}
public void cancelTimer() {
TimerService ts = sessionCtx.getTimerService();
Collection<Timer> timers = ts.getTimers();
for(Timer timer : timers){ …
Run Code Online (Sandbox Code Playgroud) 我们有一个带有多个容器的 docker 设置(Windows 10、本机 docker、compose V3),其中一个运行带有 JMS 子系统(ActiveMQ)的 Wildfly 10。在 docker NAT 内部一切正常(各种服务通过 in-vm 或 http 连接器使用 JMS),但我们还需要从外部 docker 连接到 JMS。我们通过wildfly 公开的JMSConnectionFactory 上的远程JNDI 查找实现JMS 连接。问题是连接工厂公布了无法从外部访问的 docker 容器的内部 IP 地址。
我们有正确的端口(实际上只需要一个 http 端口)可以通过 localhost 公开和访问。
以下是我尝试过的一些解决方案:
理想情况下,我想要一个适用于 Windows 和 Linux 的优雅的“金子弹”解决方案,但我知道这可能无法实现。
更新:我找到了一个解决方案(有点hacky)但我认为除非有人提出更好的建议,否则应该这样做。
我在wildfly中创建了额外的JMSConnectionFactory(在standalone.xml中配置):
<connection-factory name="ExternalConnectionFactory" entries="java:jboss/exported/jms/ExternalConnectionFactory" connectors="external-http-connector"/>
Run Code Online (Sandbox Code Playgroud)
它使用自己的连接器
<http-connector name="external-http-connector" socket-binding="external-http" endpoint="http-acceptor"/>
Run Code Online (Sandbox Code Playgroud)
我使用出站套接字绑定,这部分有点麻烦,因为它允许我指定任何网络地址。
<outbound-socket-binding name="external-http">
<remote-destination …
Run Code Online (Sandbox Code Playgroud) 我试图在扩展中可观察到的 CDI 容器引发的事件的上下文中了解 @Initialized() 事件的生命周期/流程。
- 发现Bean之前
- ProcessAnnotatedType 和 ProcessSyntheticAnnotatedType
- 类型发现后
- ProcessInjectionTarget 和 ProcessProducer
- 进程注入点
- ProcessBean 属性
- ProcessBean、ProcessManagedBean、ProcessSessionBean、ProcessProducerMethod 和 ProcessProducerField
- 进程观察者方法
- 豆子发现之后
- 部署后验证
- 关机前
我无法找到的是在此容器生命周期中将@Initialized
触发事件的位置。我怀疑它是 AfterDeploymentValidation 完成的,但我找不到任何文档来支持这一事实。此外,我似乎无法在CDI 1.1 规范中找到任何指示何时/何处抛出 @Initalized 事件的内容。
例如,事件是在@PostConstruct
发现的bean的所有方法执行之前还是之后抛出?该事件是在 EJB@Startup
初始化之前还是之后引发的?是否有任何文档清楚地列出了 CDI 中这些事件的顺序/顺序?
除了这里对 CY2018的引用之外……我发现很难弄清楚何时(或是否)Weblogic Server 版本将支持 Java EE 8?
jakarta-ee ×10
java ×5
cdi ×2
ejb ×2
wildfly-10 ×2
criteria-api ×1
docker ×1
eclipse ×1
ejb-3.2 ×1
java-ee-8 ×1
jax-rs ×1
jms ×1
jpa-2.1 ×1
jsonb-api ×1
junit ×1
linux-mint ×1
rest ×1
timer ×1
weblogic ×1
weblogic12c ×1
websocket ×1
websphere ×1