I'm trying to enqueue a message on a jms queue (weblogic) from a java application.
InitialContext ctx = getInitialContext();
qconFactory = (QueueConnectionFactory)ctx.lookup("jms.bfred1cf");
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup("jms.bfred1queue");
private static InitialContext getInitialContext() throws NamingException {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://soabpm-vm:7001/");
return new InitialContext(env);
}
When i invoke the getInitalContext() methos it works fine. I got the context.
But when trying to get the connection factory, using the context, it gives the following error:
<Exception in thread "main" java.lang.AbstractMethodError: weblogic.rmi.internal.RMIEnvironment.getProperties(Ljava/lang/Object;)Ljava/util/Hashtable;
at weblogic.rjvm.ResponseImpl.getRMIClientTimeout(ResponseImpl.java:281)
at weblogic.rjvm.ResponseImpl.<init>(ResponseImpl.java:42)
at weblogic.rjvm.MsgAbbrevOutputStream.sendRecv(MsgAbbrevOutputStream.java:404)
at weblogic.rjvm.BasicOutboundRequest.sendReceive(BasicOutboundRequest.java:109)
at weblogic.rmi.cluster.ClusterableRemoteRef.invoke(ClusterableRemoteRef.java:345)
at weblogic.rmi.cluster.ClusterableRemoteRef.invoke(ClusterableRemoteRef.java:259)
at weblogic.jndi.internal.ServerNamingNode_1035_WLStub.lookup(Unknown Source)
at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:423)
at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:411)
at javax.naming.InitialContext.lookup(InitialContext.java:409)
at demo.Demo.main(Unknown Source)
Looking into Weblogic console, JNDI Tree I've the following:
JMS:
ConnectionFactory:
name: bfred1cf
className: weblogic.rmi.cluster.ClusterableRemoteObjec
Binding Name: jms.bfred1cf
Class: weblogic.jms.client.JMSXAConnectionFactory
Queue
name: bfred1queue
className: weblogic.jms.common.WrappedDestinationImpl
Binding Name: jms.bfred1queue
Class: weblogic.jms.common.DestinationImpl
If i try to enqueue a message from a SOA Suite project (BPEL) with a JMS Adapter, using the Outbound Conection Pool
(eis/jms/bfre1) configured for the CF it works fine.
Does anyone have an idea about what can cause this error?
Thanks,
Fabio
Try to use:
wlthint3client.jar
instead of wlclient.jar and wljmsclient.jar
Related
I'm new with EJB and Im trying to consume a remote EJB from Liferay. EJB is deployed on WebLogic, Im using t3 client (wlthint3client.jar).
Part of the code of EJB is:
Stateless(name = "myDataEJB", mappedName = "ejb/MyDataEJB",
description = "Get important Data")
#Remote({
MyDataEJB.class,
SecurityContext.class
})
#RolesAllowed({
"MyRole"
})
#TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class MyDataEJBEJBImpl extends TheBaseSpringSecurityEJB implements MyDataEJBEJB {
//some stuff
And my code from Liferay is the next:
Properties p = new Properties();
p.put(Context.PROVIDER_URL, "t3://someip:someip,anotherip:anotherport");
p.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
p.put(Context.SECURITY_PRINCIPAL, "some");
p.put(Context.SECURITY_CREDENTIALS, "somepass");
try {
Context ctx = new InitialContext(p);
MyDataEJB mydataEJB =
(MyDataEJB)ctx.lookup("ejb/MyDataEJB#com.company.proyect.worker.ejb.MyDataEJB");
And I´m getting this:
javax.naming.NameNotFoundException: While trying to lookup 'ejb.MyDataEJB#com.company.proyect.worker.ejb.MyDataEJB' didn't find subcontext 'MyDataEJB#com'. Resolved 'ejb'[Root exception is javax.naming.NameNotFoundException:While trying to lookup 'ejb.MyDataEJB#com.company.proyect.worker.ejb.MyDataEJB' didn't find subcontext 'ejb.MyDataEJB#com.Resolved 'ejb'] remaining name 'ejb.MyDataEJB#com/company/proyect/worker/ejb/MyDataEJB''
Do you have any idea about what's happening?
Is the pattern ejb/MyDataEJB#com.company.proyect.worker.ejb.MyDataEJB for my lookup wrong?
Thank you so much! :)
try to use
MyDataEJB mydataEJB =
(MyDataEJB)ctx.lookup("ejb/MyDataEJB");
because your EJB is mapped by ejb/MyDataEJB in the JNDI.
I am having this small message producer:
public static void main(String[] args) throws Exception {
BasicConfigurator.configure();
Properties env = new Properties();
InputStream is = Producer.class.getResourceAsStream("/jms.properties");
env.load(is);
Context context = new InitialContext(env);
ConnectionFactory factory = (ConnectionFactory) context.lookup("jms/RemoteConnectionFactory");
Destination queue = (Destination) context.lookup("jms/demoQueue");
JMSContext jmsContext = factory.createContext();
jmsContext.createProducer().send(queue, "Message");
}
Using the following properties:
java.naming.factory.initial = org.wildfly.naming.client.WildFlyInitialContextFactory
java.naming.provider.url = http-remoting://localhost:8080
java.naming.security.principal = alex
java.naming.security.credentials = password
messagingProvider = demo
connectionFactoryNames = QueueFactory
queue.queueReq = jms.queueReq
queue.queueResp = jms.queueResp
But I get an exception:
"Caused by: javax.jms.JMSSecurityException: AMQ119031: Unable to
validate user"
I believe I have misconfigured something on the server. But what exactly? Security settings have pattern: # with role guest and admin. I don't see anything else related to security
Call the overloaded createContext() method with 2 arguments:
JMSContext context = factory.createContext("alex", "password");
Then it should work if the "alex" user has correct role assigned.
I remember I had a discussion with developers about how the createContext() should work (it was in relation with Elytron - the new securtity subsystem), and the decission for now was like: It works as designed, but it can be enhanced in the future.
See comments in JBEAP-10527 for details.
I've run ActiveMQ in my machine (imqbrokerd.exe) and got below details. I've hidden my machine name with
[#|2015-10-01T19:16:06.788+0530|WARNING|5.1|imq.log.Logger|_ThreadID=1;_ThreadNa
me=main;|[S2004]: Log output channel com.sun.messaging.jmq.util.log.SysLogHandle
r is disabled: no imqutil in java.library.path|#]
[#|2015-10-01T19:16:06.804+0530|FORCE|5.1|imq.log.Logger|_ThreadID=1;_ThreadName
=main;|
================================================================================
Message Queue 5.1
Oracle
Version: 5.1 (Build 9-b)
Compile: July 29 2014 1229
Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
================================================================================
Java Runtime: 1.7.0_40 Oracle Corporation C:\Program Files (x86)\Java\jre7
|#]
[#|2015-10-01T19:16:06.819+0530|FORCE|5.1|imq.log.Logger|_ThreadID=1;_ThreadName
=main;| IMQ_HOME=C:\MessageQueue5.1\mq
|#]
[#|2015-10-01T19:16:06.819+0530|FORCE|5.1|imq.log.Logger|_ThreadID=1;_ThreadName
=main;|IMQ_VARHOME=C:\MessageQueue5.1\var\mq
|#]
[#|2015-10-01T19:16:06.819+0530|FORCE|5.1|imq.log.Logger|_ThreadID=1;_ThreadName
=main;|Windows 7 6.1 x86 <MachineName> (4 cpu)
|#]
[#|2015-10-01T19:16:06.835+0530|FORCE|5.1|imq.log.Logger|_ThreadID=1;_ThreadName
=main;|Java Heap Size: max=190080k, current=15872k
|#]
[#|2015-10-01T19:16:06.835+0530|FORCE|5.1|imq.log.Logger|_ThreadID=1;_ThreadName
=main;|Arguments:
|#]
[#|2015-10-01T19:16:06.850+0530|FORCE|5.1|imq.log.Logger|_ThreadID=1;_ThreadName
=main;|[B1060]: Loading persistent data...
|#]
[#|2015-10-01T19:16:06.866+0530|FORCE|5.1|imq.log.Logger|_ThreadID=1;_ThreadName
=main;|Using built-in file-based persistent store: C:\MessageQueue5.1\var\mq\ins
tances\imqbroker\
|#]
[#|2015-10-01T19:16:07.194+0530|FORCE|5.1|imq.log.Logger|_ThreadID=1;_ThreadName
=main;|[B1270]: Processing messages from transaction log file...
|#]
[#|2015-10-01T19:16:07.396+0530|FORCE|5.1|imq.log.Logger|_ThreadID=1;_ThreadName
=main;|[B1039]: Broker "imqbroker#<MachineName>:7676"
ready.
|#]
And I'm using below java program to connect to this queue.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Hashtable;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class QueueSendLinear {
public static void main(String args[]) throws JMSException, NamingException {
// Defines the JNDI context factory.
final String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
// Defines the JMS context factory.
final String JMS_FACTORY="jms/TestConnectionFactory";
// Defines the queue.
final String QUEUE="jms/TestJMSQueue";
QueueConnectionFactory qconFactory;
QueueConnection qcon;
QueueSession qsession;
QueueSender qsender;
Queue queue;
TextMessage msg;
String xml = "Sample XML comes here!! ";
String url = "t3://<MachineName>:7676";
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
InitialContext ic = new InitialContext(env);
qconFactory = (QueueConnectionFactory) ic.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ic.lookup(QUEUE);
qsender = qsession.createSender(queue);
msg = qsession.createTextMessage();
qcon.start();
msg.setText(xml);
qsender.send(msg);
qsender.close();
qsession.close();
qcon.close();
}
}
question here...
a. What should be the values in JNDI_FACTORY, JMS_FACTORY, QUEUE, url and what do they signify?
b. What does 't3://' in url means? Is this a protocol ? if so, what should be given for active MQ?
FYI, i'm getting below error
Oct 01, 2015 7:20:58 PM com.sun.corba.se.impl.naming.namingutil.CorbalocURL badAddress
WARNING: "IOP00110603: (BAD_PARAM) Bad host address in -ORBInitDef"
org.omg.CORBA.BAD_PARAM: vmcid: SUN minor code: 603 completed: No
[UPDATE #1]:
When I use below code, I get below error. I've attached images of my activeMQ queue details. I know that the URL that i'm using is wrong. Can you please help me out with the right one?
Exception in thread "main" javax.naming.NamingException: Couldn't connect to the specified host : [Root exception is org.omg.CORBA.COMM_FAILURE: vmcid: SUN minor code: 208 completed: Maybe]
at weblogic.corba.j2ee.naming.Utils.wrapNamingException(Utils.java:83)
at weblogic.corba.j2ee.naming.ORBHelper.getORBReferenceWithRetry(ORBHelper.java:656)
final String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
final String JMS_FACTORY="jms/?";
final String QUEUE = "mq.sys.dmq";
QueueConnectionFactory qconFactory;
QueueConnection qcon;
QueueSession qsession;
QueueSender qsender;
Queue queue;
TextMessage msg;
String xml = "Sample XML comes here!! ";
String url = "t3://localhost:51010";
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
InitialContext ic = new InitialContext(env);
qconFactory = (QueueConnectionFactory) ic.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ic.lookup(QUEUE);
qsender = qsession.createSender(queue);
msg = qsession.createTextMessage();
qcon.start();
Hope this Helps..
I have passed the JMS server name as an argument. And WLS library jar should be imported
private static final String CONNECTION_FACTORY_NAME ="connection factory name goes here";
private static final String TOPIC_NAME = "Topic Name goes here";
private static final String SERVER_URL_PREFIX = "t3://";
private static final String SERVER_URL_SUFFIX = ".url.com:port";
private static final String USER = "";
private static final String PASSWORD = "";
private static final String LOCAL_DIRECTORY = "C:\\tmp\\poslog\\";
public static void main(String args[]) throws JMSException,
NamingException, IOException, InterruptedException {
System.out.println("start" + new Date());
// INITIALIZE
System.out.println("creating context for " + args[0]);
Hashtable<String, String> properties = new Hashtable<String, String>();
properties.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
properties.put(Context.PROVIDER_URL, SERVER_URL_PREFIX + args[0] + SERVER_URL_SUFFIX);
//properties.put(Context.SECURITY_PRINCIPAL, USER);
//properties.put(Context.SECURITY_CREDENTIALS, PASSWORD);
InitialContext ctx = new InitialContext(properties);
TopicConnectionFactory connectionFactory = (TopicConnectionFactory) ctx
.lookup(CONNECTION_FACTORY_NAME);
TopicConnection connection = connectionFactory.createTopicConnection();
TopicSession session = connection.createTopicSession(false, 0);
Topic topic = (Topic) ctx.lookup(TOPIC_NAME);
TopicPublisher sender = session.createPublisher(topic);
JNDI_FACTORY is more like a driver that you want to use to connect, they are usually specific to the vendor in your case is weblogic and is pre-defined.
JMS_FACTORY is the connection factory that you have already predefined in web logic for this type of integration. it is responsible for managing the connections to the queue.
QUEUE also is something that you need to predefine / setup on weblogic admin console. It is the reference to the queues that reside on weblogic which you have setup before hand.
t3 is the connection type you are using, the other alternative could be iiop. t3 it is a more lightweight type of connection.
I have installed Websphere Network deployment server 7.0.0.0
I have configured a cluster on it.
I have configured a data source on it say ORA_DS this data source using "JAAS - J2C authentication data"
When i test the ORA_DS by clicking on "Test connection" button, the test connection is success.
The issue comes when i try to access this data source using my java code.
Here is my code to access data source and create a connection:
public class DSTester
{
/**
* Return the data source.
* #return the data source
*/
private DataSource getDataSource()
{
DataSource dataSource = null;
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
env.put(Context.PROVIDER_URL, "iiop://localhost:9811");
// Retrieve datasource name
String dataSourceName = "EPLA1";
if (dataSource == null)
{
try
{
Context initialContext = new InitialContext(env);
dataSource = (DataSource) initialContext.lookup(dataSourceName);
}
catch (NamingException e1)
{
e1.printStackTrace();
return null;
}
}
return dataSource;
}
public static void main(String[] args)
throws Exception
{
DSTester dsTester = new DSTester();
DataSource ds = dsTester.getDataSource();
System.out.println(ds);
System.out.println(ds.getConnection());
}
}
Here is the output:
com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource#17e40be6
Exception in thread "P=792041:O=0:CT" java.sql.SQLException: ORA-01017: invalid username/password; logon denied
DSRA0010E: SQL State = 72000, Error Code = 1,017
at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:206)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:455)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:406)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)
at oracle.jdbc.driver.T4CTTIoauthenticate.receiveOauth(T4CTTIoauthenticate.java:799)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:368)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:508)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:203)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:33)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:510)
at oracle.jdbc.pool.OracleDataSource.getPhysicalConnection(OracleDataSource.java:275)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:206)
at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPhysicalConnection(OracleConnectionPoolDataSource.java:139)
at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPooledConnection(OracleConnectionPoolDataSource.java:88)
at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPooledConnection(OracleConnectionPoolDataSource.java:70)
at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper$1.run(InternalGenericDataStoreHelper.java:1175)
at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper.getPooledConnection(InternalGenericDataStoreHelper.java:1212)
at com.ibm.ws.rsadapter.spi.WSRdbDataSource.getPooledConnection(WSRdbDataSource.java:2019)
at com.ibm.ws.rsadapter.spi.WSManagedConnectionFactoryImpl.createManagedConnection(WSManagedConnectionFactoryImpl.java:1422)
at com.ibm.ws.rsadapter.spi.WSDefaultConnectionManagerImpl.allocateConnection(WSDefaultConnectionManagerImpl.java:81)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:646)
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:613)
at com.test.DSTester.main(DSTester.java:70)
The code works fine if i replace
ds.getConnection()
with
ds.getConnection("ora_user", "ora_password")
My issue is i need to get the connection without specifying login details for Oracle.
Please help me on this issue.
Any clue will be appreciated.
Thanks
I'd guess it would work if you retrieved the datasource from an application running on the WAS.
Try creating a servlet.
Context initialContext = new InitialContext();
DataSource dataSource = (DataSource) initialContext.lookup("EPLA1");
Connection con = dataSource.getConnection();
As within a servlet it is running within WAS it should be fine, if the "Test Connection" works. Running it outside is probably a different context.
I think you need to check all your configuration:
1) Is it application deplyed on cluster or into only one of cluster member?
2) JAAS - J2C authentication data - what is the scope?
Sometimes you need restar all your WAS environment. It depends on resource configuration scope
I'd recomend to you add resource refences for better configuration options.
SeeIBM Tech note
I am new in Java EJB 3.0. It is possible to call a (session) bean—deployed on JBoss—from a desktop application client?
Thanks in advance.
Yes you can. Some specifics are here (references EJB2 but it the same for EJB3 when it comes to remote clients): http://www.theserverside.com/discussions/thread.tss?thread_id=9197
Paraphrased:
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
env.put("java.naming.provider.url", "jnp://localhost:1099");
env.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
Context ctx = new InitialContext(env);
// name is whatever JNDI name you gave it
Object o = ctx.lookup("home name");
EJBHome ejbHome = (EJBHome) PortableRemoteObject.narrow(o,EJBHome.class);
// This is userID should be the one passed.
EJB ejb = ejbHome.create(..);
Yes.
public static void main(String args[]) throws Exception {
InitialContext ctx = new InitialContext();
YourService yourService = (YourService) ctx.lookup("com.example.session.YourService");
String time = yourService.getTime();
System.out.println("Time is: " + time);
}
For client configuration you must provide jndi.properties file with contents
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
If you are looking for working examples on JBoss try download source code of Enterprise JavaBeans 3.0, Fifth Edition
Let's assume you have the following remote interface:
#Remote
public interface HelloBeanRemote {
public String sayHello();
}
And a session bean implementing it:
#Stateless
public class HelloBean implements HelloBeanRemote {
...
}
And that this EJB is correctly packaged and deployed on JBoss.
On the client side, create a jndi.properties with the following content and put it on the classpath:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost:1099
Then use the following code to call your EJB:
Context context;
try {
context = new InitialContext();
HelloBeanRemote beanRemote = (HelloBeanRemote)context.lookup("HelloBean/remote");
beanRemote.test();
} catch (NamingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
Alternatively, if you don't want to provide a jndi.properties file, you can explicitly setup the JNDI environment in the code and create the context like this:
Properties properties = new Properties();
properties.put("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
properties.put("java.naming.factory.url.pkgs","=org.jboss.naming:org.jnp.interfaces");
properties.put("java.naming.provider.url","localhost:1099");
Context context = new InitialContext(properties);
But I'd recommend using the jndi.properties for the sake of portability.
You can also expose the bean as a web service. I believe this is available as of EJB 3. It is quite nice considering you can do it with annotations. You may wish to consider using this option to decrease coupling. Here is a link to a tutorial.