jboss-eap-quickstarts cluster-ha-singleton client JNDI Lookup Class Cast Exception

Posted

技术标签:

【中文标题】jboss-eap-quickstarts cluster-ha-singleton client JNDI Lookup Class Cast Exception【英文标题】: 【发布时间】:2016-01-03 16:42:36 【问题描述】:

我正在使用 JBoss 6.2 并尝试从 webapp 过滤器调用单例服务。

我已经在集群环境中成功安装并启动了一个单例服务,如下面的快速入门教程所述:

https://github.com/jboss-developer/jboss-eap-quickstarts/tree/44c8c90/cluster-ha-singleton

我们可以看到单例服务已经成功部署在管理控制台中(我上传了一张图片到我的网站,因为我没有足够高的堆栈溢出声誉来发布图片):

http://www.rakkatak.com/so/***_question_singletonservice_img1.png

作为快速入门教程的补充,我想要一个从外部客户端调用单例服务的示例。在我的例子中,这是一个过滤器(LoginFilter),通过放置在 JBoss 模块目录中的 service.jar 访问。这个 jar 包含以下内容:

/META-INF/jboss-ejb-client.properties /com/login/filter/LoginFilter.class

出于我想要做的事情的目的,我没有使用集群环境,只有 Node1 将运行。

jboss-ejb-client.properties 包含:

remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=node1
remote.connection.node1.host=localhost
remote.connection.node1.port = 9999
remote.connection.node1.connect.timeout = 500
remote.connection.node1.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false

LoginFilter.java 包含:

final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
final Context context = new InitialContext(jndiProperties);

System.out.println(">>>>> JNDI LOOKUP >>>>>");
Object obj = context.lookup("global/jboss-cluster-ha-singleton-service/SchedulerBean!org.jboss.as.quickstarts.cluster.hasingleton.service.ejb.Scheduler");
Scheduler scheduler = (Scheduler) obj;
System.out.println(">>>>> JNDI END >>>>>");

我将 service.jar 复制到 $JBOSS_HOME/modules/com/login/filter/main 然后启动 node1 服务器。

在 service.jar 所在的目录中,我们在 module.xml 中定义了以下依赖项:

<module xmlns="urn:jboss:module:1.0" name="td.oca.spike.kernel">
    <resources>
        <resource-root path="service.jar"/>
    </resources>
    <dependencies>
        ...
        <module name="org.jboss.as.quickstarts" />
    </dependencies>
</module>

其中 org.jboss.as.quickstarts 是另一个包含 SchedulerBean 接口的模块。

接下来,我在浏览器中打开了 Login webapp,它被配置为使用上面的 LoginFilter 类。当我调用它时,我们永远不会看到 System out >>>>> JNDI END >>>>>" 相反,我得到以下类转换异常:

java.lang.ClassCastException: org.jboss.as.quickstarts.cluster.hasingleton.service.ejb.Scheduler$$$view1 cannot be cast to org.jboss.as.quickstarts.cluster.hasingleton.service.ejb.Scheduler

我认为我必须缺少某种配置以允许从 LoginFilter 调用单例服务。请提出您认为可能有帮助的任何建议,并提前致谢!

Scheduler.java

package org.jboss.as.quickstarts.cluster.hasingleton.service.ejb;

/**
 * @author <a href="mailto:wfink@redhat.com">Wolf-Dieter Fink</a>
 */
public interface Scheduler 

    void count();

    void initialize(String info);

    void stop();


SchedulerBean.java

package org.jboss.as.quickstarts.cluster.hasingleton.service.ejb;

import javax.annotation.Resource;
import javax.ejb.ScheduleExpression;
import javax.ejb.Singleton;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerConfig;
import javax.ejb.TimerService;

import org.jboss.logging.Logger;


@Singleton
public class SchedulerBean implements Scheduler 
    private static Logger LOGGER = Logger.getLogger(SchedulerBean.class);
    @Resource
    private TimerService timerService;

    private int counter=0;

    @Timeout
    public void scheduler(Timer timer) 
        LOGGER.info("*** HASingletonTimer: Info=" + timer.getInfo());
    

    @Override
    public void initialize(String info) 
        ScheduleExpression sexpr = new ScheduleExpression();
        // set schedule to every 10 seconds for demonstration
        sexpr.hour("*").minute("*").second("0/10");
        // persistent must be false because the timer is started by the HASingleton service
        timerService.createCalendarTimer(sexpr, new TimerConfig(info, false));
    

    @Override
    public void stop() 
        LOGGER.info("Stop all existing HASingleton timers");
        for (Timer timer : timerService.getTimers()) 
            LOGGER.trace("Stop HASingleton timer: " + timer.getInfo());
            timer.cancel();
        
    


    @Override
    public void count() 
        counter++;
        LOGGER.info("***** HASingletonTimer: Counter=" + counter);
    

【问题讨论】:

你能把SchedulerSchedulerBean 的代码贴出来吗?这是远程接口吗? 嗨,休,感谢您的回复。我已经编辑了原始帖子并添加了 Scheduler 和 SchedulerBean。谢谢 【参考方案1】:

我认为问题在于您正在尝试远程访问Scheduler,但由于它没有被注释为远程接口,因此默认为本地:https://docs.oracle.com/javaee/6/tutorial/doc/gipjf.html

您能否在Scheduler 中添加@Remote,看看是否能让事情变得更好?

【讨论】:

嗨休!这行得通,非常感谢!现在唯一让我感到困惑的是,当我从 node1 和 node2 调用单例 count() 方法时,即节点 1 的 localhost:8080 和 localhost:8180 (不同的端口)我看到以下输出:“***** HASingletonTimer : Counter=1" (node1) 和 "***** HASingletonTimer: Counter=1" (node2)。我期待看到节点 2 的“***** HASingletonTimer: Counter=2”? (抱歉回复慢)不确定,恐怕。如果您对两个调用都使用相同的节点,看看计数器是否正确递增会很有趣? 嗨,休,没关系 :) 如果您对两个调用使用相同的节点,计数器确实会正确递增。 有没有办法从 webapp 外部调用 HATimerService 服务(来自原始 cluster-ha-singleton tuturial)?

以上是关于jboss-eap-quickstarts cluster-ha-singleton client JNDI Lookup Class Cast Exception的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 数据库镜像

09-创建故障转移群集遇到“约束冲突”的错误

saltstack 系列centos7使用saltstack源码安装nginx

一个热爱编程的82岁老太太:2008年图灵奖得主Barbara Liskov访谈录

Redis 应用进阶

MySQL???????????????????????????????????????????????????