I am a newer for EJB3 dev.
When I write a EJB3 mdb and I want to deploy it to my jboss (jboss-4.2.3.GA)
some error info is here:
--- MBeans waiting for other MBeans --- ObjectName: jboss.j2ee:jar=HelloWorldEjb.jar,name=QueneMDB01,service=EJB3 State:
FAILED Reason: org.jboss.deployment.DeploymentException: Required
config property RequiredConfigPropertyM
etaData#12c08c7[name=destination
descriptions=[DescriptionMetaData#1941dc9[language=zh]]] for messag
ingType 'javax.jms.MessageListener' not found in activation config
[ActivationConfigProperty(destina tionType=javax.jms.Queue),
ActivationConfigProperty(acknowledgeMode=Auto-acknowledge)]
ra=jboss.jca: service=RARDeployment,name='jms-ra.rar'
--- MBEANS THAT ARE THE ROOT CAUSE OF THE PROBLEM --- ObjectName: jboss.j2ee:jar=HelloWorldEjb.jar,name=QueneMDB01,service=EJB3 State:
FAILED Reason: org.jboss.deployment.DeploymentException: Required
config property RequiredConfigPropertyM
etaData#12c08c7[name=destination
descriptions=[DescriptionMetaData#1941dc9[language=zh]]] for messag
ingType 'javax.jms.MessageListener' not found in activation config
[ActivationConfigProperty(destina tionType=javax.jms.Queue),
ActivationConfigProperty(acknowledgeMode=Auto-acknowledge)]
ra=jboss.jca: service=RARDeployment,name='jms-ra.rar'
and my mdb is :
#MessageDriven(activationConfig = {
#ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") })
public class QueneMDB01 implements MessageListener
{
public void onMessage(Message msg) {
// TODO Auto-generated method stub
try {
TextMessage textMessage = (TextMessage) msg;
System.out.println("MyQueneMDBBean is called "
+ textMessage.getText() + " ");
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
From your error i'd say you forgot to add the destination name (queue name probably).
FAILED Reason: org.jboss.deployment.DeploymentException: Required config property RequiredConfigPropertyM etaData#12c08c7[name=destination descriptions=[DescriptionMetaData#1941dc9[language=zh]]
Example:
http://www.javaissues.com/2011/06/ejb3-message-driven-bean-hello-world.html
BTW, you've set up your queues/topics in JBoss right?
Hope this helps,
Dave
Related
I'm having a rough time getting a very simple Keycloak ProtocolMapper working in Keycloak 6.0.1.
I'm trying to add extra claims to an access token. When I copy the built jar to the deployment directory I get the following NullPointerException in the deployment directory with the below contents in .failed file.
{"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"token-enhancer-1.0-SNAPSHOT.jar\".POST_MODULE" => "WFLYSRV0153: Failed to process phase POST_MODULE of deployment \"token-enhancer-1.0-SNAPSHOT.jar\"
Caused by: java.lang.NullPointerException"}}
The logs show the same exception right below
21:18:46,697 INFO [org.keycloak.subsystem.server.extension.KeycloakProviderDeploymentProcessor] (MSC service thread 1-1) Deploying Keycloak provider: token-enhancer-1.0-SNAPSHOT.jar
21:18:46,718 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-1) MSC000001: Failed to start service jboss.deployment.unit."token-enhancer-1.0-SNAPSHOT.jar".POST_MODULE: org.jboss.msc.service.StartException in service jboss.deployment.unit."token-enhancer-1.0-SNAPSHOT.jar".POST_MODULE: WFLYSRV0153: Failed to process phase POST_MODULE of deployment "token-enhancer-1.0-SNAPSHOT.jar"
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:183)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1738)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1700)
at org.jboss.msc.service.ServiceControllerImpl$ControllerTask.run(ServiceControllerImpl.java:1558)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
at org.keycloak.services.DefaultKeycloakSessionFactory.isInternal(DefaultKeycloakSessionFactory.java:370)
at org.keycloak.services.DefaultKeycloakSessionFactory.loadFactories(DefaultKeycloakSessionFactory.java:219)
at org.keycloak.services.DefaultKeycloakSessionFactory.deploy(DefaultKeycloakSessionFactory.java:115)
at org.keycloak.provider.ProviderManagerRegistry.deploy(ProviderManagerRegistry.java:42)
at org.keycloak.subsystem.server.extension.KeycloakProviderDeploymentProcessor.deploy(KeycloakProviderDeploymentProcessor.java:55)
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:176)
... 8 more
21:18:46,719 ERROR [org.jboss.as.controller.management-operation] (DeploymentScanner-threads - 1) WFLYCTL0013: Operation ("full-replace-deployment") failed - address: ([]) - failure description: {"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"token-enhancer-1.0-SNAPSHOT.jar\".POST_MODULE" => "WFLYSRV0153: Failed to process phase POST_MODULE of deployment \"token-enhancer-1.0-SNAPSHOT.jar\"
Caused by: java.lang.NullPointerException"}}
I've upload sample code to github.
My implemented ProtocolMapper class is below.
I'm having a rough time because I don't understand where to troubleshoot with such a vague error message. What would be a good strategy to investigate this issue?
import org.keycloak.models.ClientSessionContext;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.protocol.oidc.mappers.*;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.IDToken;
import java.util.*;
public class KeycloakTokenEnhancer extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper {
public static final String PROVIDER_ID = "oidc-token-enhancer-mapper";
private static final List<ProviderConfigProperty> configProperties = new ArrayList<>();
static {
OIDCAttributeMapperHelper.addIncludeInTokensConfig(configProperties, KeycloakTokenEnhancer.class);
}
#Override
public AccessToken transformAccessToken(AccessToken accessToken, ProtocolMapperModel protocolMapperModel, KeycloakSession keycloakSession, UserSessionModel userSessionModel, ClientSessionContext clientSessionContext) {
return accessToken;
}
#Override
public String getDisplayCategory() {
return "Token Enhancer mapper";
}
#Override
public String getDisplayType() {
return "Token Enhancer Mapper";
}
#Override
public String getHelpText() {
return "Add to claims for the User Service";
}
#Override
public List<ProviderConfigProperty> getConfigProperties() {
return configProperties;
}
#Override
public String getId() {
return PROVIDER_ID;
}
protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession) {
token.getOtherClaims().put("fruit", "pear, apple, tangerine");
}
public static ProtocolMapperModel create(String name, boolean accessToken, boolean idToken, boolean userInfo) {
ProtocolMapperModel mapper = new ProtocolMapperModel();
mapper.setName(name);
mapper.setProtocolMapper(PROVIDER_ID);
mapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
Map<String, String> config = new HashMap<String, String>();
if (accessToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true");
if (idToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true");
if (userInfo) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_USERINFO, "true");
mapper.setConfig(config);
return mapper;
}
}
Try adding a package statement at the top of your class (KeycloakTokenEnhancer) and moving your class into the package.
NPE is thrown from line 370 in DefaultKeycloakSessionFactory:
String packageName = factory.getClass().getPackage().getName();
See also:
Javadoc of Class.html#getPackage
Returns:
the package of the class, or null if no package information is available from the archive or codebase.
I need help in creating remote connections in Jboss-eap 6.4 HornetQ
I have this code:
import java.util.Hashtable;
import javax.jms.*;
import javax.naming.*;
public class QueueSend {
private final static String JNDI_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory";
private final static String JMS_FACTORY = "jms/RemoteConnectionFactory";
private final static String QUEUE = "jms/queue/test";
private final static String jbossUrl = "remote://localhost:4447";
private static InitialContext getInitialContext() throws NamingException {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, jbossUrl);
env.put(Context.SECURITY_PRINCIPAL, "appuser"); // <-- username
env.put(Context.SECURITY_CREDENTIALS, "appuser_2015"); // <-- password
return new InitialContext(env);
}
public static void main(String[] args) throws Exception {
InitialContext ic = getInitialContext();
QueueConnectionFactory qconFactory =
(QueueConnectionFactory)ic.lookup(JMS_FACTORY);
QueueConnection qcon =
qconFactory.createQueueConnection("appuser","appuser_2015");
QueueSession qsession = qcon.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue)ic.lookup(QUEUE);
QueueSender qsender = qsession.createSender(queue);
qcon.start();
TextMessage msg = qsession.createTextMessage();;
msg.setText("HelloWorld");
qsender.send(msg);
qsender.close();
qsession.close();
qcon.close();
System.out.println("Message Sent!");
}
}
And when I ran this code It displays an error:
Exception in thread "main" javax.naming.NamingException: Failed to create remoting connection [Root exception is java.lang.ExceptionInInitializerError]
at org.jboss.naming.remote.client.ClientUtil.namingException(ClientUtil.java:36)
at org.jboss.naming.remote.client.InitialContextFactory.getInitialContext(InitialContextFactory.java:121)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
at javax.naming.InitialContext.init(InitialContext.java:223)
at javax.naming.InitialContext.<init>(InitialContext.java:197)
at com.wendell.QueueSend.getInitialContext(QueueSend.java:28)
at com.wendell.QueueSend.main(QueueSend.java:32)
Caused by: java.lang.ExceptionInInitializerError
at org.jboss.naming.remote.protocol.v1.RemoteNamingStoreV1.sendVersionHeader(RemoteNamingStoreV1.java:69)
at org.jboss.naming.remote.protocol.v1.RemoteNamingStoreV1.start(RemoteNamingStoreV1.java:64)
at org.jboss.naming.remote.protocol.v1.VersionOne.getRemoteNamingStore(VersionOne.java:45)
at org.jboss.naming.remote.protocol.Versions.getRemoteNamingStore(Versions.java:49)
at org.jboss.naming.remote.client.RemoteContextFactory.createVersionedStore(RemoteContextFactory.java:68)
at org.jboss.naming.remote.client.NamingStoreCache.getRemoteNamingStore(NamingStoreCache.java:60)
at org.jboss.naming.remote.client.InitialContextFactory.getOrCreateCachedNamingStore(InitialContextFactory.java:166)
at org.jboss.naming.remote.client.InitialContextFactory.getOrCreateNamingStore(InitialContextFactory.java:139)
at org.jboss.naming.remote.client.InitialContextFactory.getInitialContext(InitialContextFactory.java:104)
... 6 more
Caused by: java.lang.RuntimeException: Could not find a marshaller factory for river marshalling strategy
at org.jboss.naming.remote.protocol.v1.WriteUtil.<clinit>(WriteUtil.java:50)
... 15 more
I don't know what's the problem here, Did I miss something? Where did I go wrong?
Please help. Thanks
You may be having jboss-marshalling-xxxx.jar but missing the jboss-marshalling-river-xxxx.jar in your client's classpath.
Add jboss-marshalling-river-xxxx.jar jar file to your classpath as well.
In my case, I had jboss-marshalling-1.4.11.Final.jar but was missingjboss-marshalling-river-1.4.11.Final.jar in my classpath.
My client was then able to make remote EJB calls to wildfly.
I got a little help from This link.
I have a MDB running on JBoss 7.1, and a simple Java application as a client on another machine. The goal is the following:
the client sends a request (ObjectMessage) to the server
the server processes the request and sends back a response to the client (ObjectMessage again)
I thought to use a TemporaryQueue on the client to listen for the response (because I don't know how to do it asynchronously), and the JMSReplyTo Message's property to correctly reply back because I should support multiple independent clients.
This is the client:
public class MessagingService{
private static final String JBOSS_HOST = "localhost";
private static final int JBOSS_PORT = 5455;
private static Map connectionParams = new HashMap();
private Window window;
private Queue remoteQueue;
private TemporaryQueue localQueue;
private ConnectionFactory connectionFactory;
private Connection connection;
private Session session;
public MessagingService(Window myWindow){
this.window = myWindow;
MessagingService.connectionParams.put(TransportConstants.PORT_PROP_NAME, JBOSS_PORT);
MessagingService.connectionParams.put(TransportConstants.HOST_PROP_NAME, JBOSS_HOST);
TransportConfiguration transportConfiguration = new TransportConfiguration(NettyConnectorFactory.class.getName(), connectionParams);
this.connectionFactory = (ConnectionFactory) HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transportConfiguration);
}
public void sendRequest(ClientRequest request) {
try {
connection = connectionFactory.createConnection();
this.session = connection.createSession(false, QueueSession.AUTO_ACKNOWLEDGE);
this.remoteQueue = HornetQJMSClient.createQueue("testQueue");
this.localQueue = session.createTemporaryQueue();
MessageProducer producer = session.createProducer(remoteQueue);
MessageConsumer consumer = session.createConsumer(localQueue);
ObjectMessage message = session.createObjectMessage();
message.setObject(request);
message.setJMSReplyTo(localQueue);
producer.send(message);
ObjectMessage response = (ObjectMessage) consumer.receive();
ServerResponse serverResponse = (ServerResponse) response.getObject();
this.window.dispatchResponse(serverResponse);
this.session.close();
} catch (JMSException e) {
// TODO splittare e differenziare
e.printStackTrace();
}
}
Now I'm having troubles writing the server side, as I cannot figure out how to establish a Connection to a TemporaryQueue...
public void onMessage(Message message) {
try {
if (message instanceof ObjectMessage) {
Destination replyDestination = message.getJMSReplyTo();
ObjectMessage objectMessage = (ObjectMessage) message;
ClientRequest request = (ClientRequest) objectMessage.getObject();
System.out.println("Queue: I received an ObjectMessage at " + new Date());
System.out.println("Client Request Details: ");
System.out.println(request.getDeparture());
System.out.println(request.getArrival());
System.out.println(request.getDate());
System.out.println("Replying...");
// no idea what to do here
Connection connection = ? ? ? ? ? ? ? ?
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer replyProducer = session.createProducer(replyDestination);
ServerResponse serverResponse = new ServerResponse("TEST RESPONSE");
ObjectMessage response = session.createObjectMessage();
response.setObject(serverResponse);
replyProducer.send(response);
} else {
System.out.println("Not a valid message for this Queue MDB");
}
} catch (JMSException e) {
e.printStackTrace();
}
}
I cannot figure out what am I missing
You are asking the wrong question here.. You should look at how to create a Connection inside any Bean.
you need to get the ConnectionFactory, and create the connection accordingly.
For more information, look at the javaee examples on the HornetQ download.
In specific look at javaee/mdb-tx-send/ when you download hornetq.
#MessageDriven(name = "MDBMessageSendTxExample",
activationConfig =
{
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
#ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/testQueue")
})
public class MDBMessageSendTxExample implements MessageListener
{
#Resource(mappedName = "java:/JmsXA")
ConnectionFactory connectionFactory;
public void onMessage(Message message)
{
Connection conn = null;
try
{
// your code here...
//Step 11. we create a JMS connection
conn = connectionFactory.createConnection();
//Step 12. We create a JMS session
Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
//Step 13. we create a producer for the reply queue
MessageProducer producer = sess.createProducer(replyDestination);
//Step 14. we create a message and send it
producer.send(sess.createTextMessage("this is a reply"));
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if(conn != null)
{
try
{
conn.close();
}
catch (JMSException e)
{
}
}
}
}
I am trying to get the following code to work so I can consume from a JPA entity.
String DATASOURCE_CONTEXT = "java:jboss/datasources/WikiDS";
Connection result = null;
DataSource datasource = null;
try {
Context initialContext = new InitialContext();
datasource = (DataSource)initialContext.lookup(DATASOURCE_CONTEXT);
if (datasource == null) {
System.out.println("Data source is null");
}
else {
System.out.println("Data source is OK!!!");
}
}
catch(NamingException ex) {
System.out.println("Naming exception is: " + ex.getMessage());
}
SimpleRegistry reg = new SimpleRegistry() ;
reg.put("myDataSource",datasource);
CamelContext context = new DefaultCamelContext(reg);
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
context.addComponent("test-jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
context.addRoutes(new RouteBuilder() {
public void configure() {
from("jpa://org.apache.camel.example.jmstofile?consumer.namedQuery=step1&consumeDelete=false").to("file://test");
}
});
ProducerTemplate template = context.createProducerTemplate();
context.start();
Whatever I do I get the following exception.
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.1.1:java (default-cli) on project camel-example-jms-file: An exception occured while executing the Java class. null: InvocationTargetException: No Persistence provider for EntityManager named camel.
Any ideas how to fix this?
Regards,
Sean
Add &persistenceUnit=<name-of-your-unit> to your URI, where <name-of-your-unit> is the name of the persistence unit given in persistence.xml.
I am using JMS for the first time and am using Glassfish 3.1.1. I have set up a JMS Connection Factory:
Pool Name: jms/QueueConnectionFactory
JNDI Name: jms/QueueConnectionFactory
Resource Type: javax.jms.QueueConnectionFactory
and a Destination Resource:
JNDI Name: jms/ProcessBatchQueue
Physical Destination: ProcessBatchQueue
Resource Type: javax.jms.Queue
I have deployed a war with a servlet that accepts a file, parses it and saves the contents to a database. If this is all successful it sends a message to the queue:
#Resource(lookup = "jms/ProcessBatchQueue")
private Queue processBatchQueue;
private void sendProcessBatchMessage(String batchID) throws JMSException
{
log.info("Attempting to send process batch message for batch ID: "
+ batchID);
Connection jmsConnection = connectionFactory.createConnection();
Session jmsSession = jmsConnection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
TextMessage message = jmsSession.createTextMessage();
message.setText(batchID);
MessageProducer msgProducer = jmsSession.createProducer(processBatchQueue);
msgProducer.send(message);
jmsConnection.close();
}
I have a deployed an ear with an MDB that should be listening to the queue and actioning the message:
#MessageDriven(mappedName = "jms/ProcessBatchQueue")
public class BatchReceiver
{
private final Logger log = LoggerFactory.getLogger(BatchReceiver.class);
public void onMessage(Message message)
{
log.info("Received message from jms/ProcessBatchQueue: " + message);
try
{
if (message instanceof TextMessage)
{
String batchId = ((TextMessage) message).getText();
// do processing
}
else
{
log.error("Received invalid message type from jms/ProcessBatchQueue");
}
}
catch (Exception ex)
{
String error = "Received error '" + ex.toString()
+ "' retrieving message from jms/BatchProcessingTopic.";
Throwable linkedEx = ex.getCause();
if (linkedEx != null)
{
log.error(error += "Linked exception: " + linkedEx.getMessage(),
linkedEx);
}
else
{
log.error(error + ", " + ex.getMessage(), ex);
}
}
}
}
In my war logs, I get the
log.info("Attempting to send process batch message for batch ID: " + batchID);
statement, but in the ear logs, I get nothing that would indicate that the MDB is receiving the message.
My understanding is that I should be able to "just" deploy the ear with the MDB and it should start receiving the messages. Is there a config step that I've missed?
Is there some way to confirm that the message generated in the servlet is making it to the queue in the first place? There are no errors in any log including server.log.
Your bean does not implement javax.jms.MessageListener, it just has an onMessage() method with a the same signature.
It's also possible that you miss the activationConfig part of the annotation, but I'm not sure if it's required in Java EE 6. See if it's the case anyway:
#MessageDriven(
activationConfig = {
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
#ActivationConfigProperty(propertyName = "destination", propertyValue = "ProcessBatchQueue")},
mappedName = "jms/ProcessBatchQueue")