I need to write a simple java class which send messages to a Sonic Topic. I can use the JNDI values for lookup.
Here is the code.
Hashtable<String, String> properties = new Hashtable<>();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sonicsw.jndi.mfcontext.MFContextFactory");
properties.put(Context.PROVIDER_URL, "tcp://Devserver:7002");
properties.put(Context.SECURITY_PRINCIPAL, "username");
properties.put(Context.SECURITY_CREDENTIALS, "password");
properties.put("com.sonicsw.jndi.mfcontext.domain", "dmDEV");
Context jndiContext = new InitialContext(properties);
ConnectionFactory connectionFactory = (ConnectionFactory) jndiContext.lookup("TopicConnectionFactory");
Topic topic = (Topic) jndiContext.lookup("testtopic");
This throws an error
javax.naming.NameNotFoundException: /testtopic not found in the specified context
When I debug the code, I can see "connectionFactory" variable has following fields and values which are totally different from the values I specify above in properties.
brokerHostName "MyMachine" (id=55)
brokerPort 0
brokerProtocol "tcp" (id=59)
brokerURL "" (id=66)
clientID null
connectID null
defaultPassword "" (id=67)
defaultUserName "Administrator" (id=68)
I need to know how to write a simple Java client to connect to a Sonic topic.
I used the following which resolved my issue. Here is it in case you face the same issue. topic = session.createTopic(topicName);
Related
I don't want to use jdni.properties file, so to add new properties to my JNDI settings, I wrote following:
Hashtable<String, Object> jndi_env = new Hashtable<String, Object>();
jndi_env.put(InitialContext.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
jndi_env.put("connectionFactory.ConnectionFactory","vm://0");
jndi_env.put("topic.example","example");
My Problem is, when I call this class:
initialContext = new InitialContext(jndi_env);
Since I pass a name parameter in the last line a URL context factory is looked up.
This makes my code looking for a tcp://localhost:61616 connection which I actually don't want.
I see that there are
QueueConnectionFactory: org.apache.activemq.ActiveMQConnectionFactory
example: org.apache.activemq.command.ActiveMQTopic
XAConnectionFactory: org.apache.activemq.ActiveMQXAConnectionFactory
which I don't want, or at least not the type they are.
If I check without passing an argument using my jndi.properties file where I don't get the issue of establishing a tcp connection, then I find just:
ConnectionFactory: org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory
queue: org.apache.activemq.artemis.jndi.ReadOnlyContext
queue/exampleQueue: org.apache.activemq.artemis.jms.client.ActiveMQQueue
dynamicTopics: org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory$2
dynamicQueues: org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory$1
So how can I change the object types of my added jndi_env.put("topic.example","example"); so it will be like this (but of course for Topics)
queue: org.apache.activemq.artemis.jndi.ReadOnlyContext
queue/exampleQueue: org.apache.activemq.artemis.jms.client.ActiveMQQueue
When you create your InitialContext you're passing in the wrong factory. Currently you're passing in org.apache.activemq.jndi.ActiveMQInitialContextFactory. This is the factory for ActiveMQ 5.x, not Artemis. You need to pass in org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory instead, e.g.:
Hashtable<String, Object> jndi_env = new Hashtable<String, Object>();
jndi_env.put(InitialContext.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory");
jndi_env.put("connectionFactory.ConnectionFactory","vm://0");
jndi_env.put("topic.example","example");
Building an SPI to push events into Kafka, to get deployed as an EAR inside Keycloak 6.0.1, which uses the WildFly Server, packaged in a Docker image based on jboss/keycloak:6.0.1.
I ran into: Kafka Producer - org.apache.kafka.common.serialization.StringSerializer could not be found
So I applied the suggested solution of setting Thread.currentThread().setContextClassLoader(null);.
This seems to work fine for my local Kafka on port 9092, without authentication. As soon as I authenticate as described here:
String jaasTemplate = "org.apache.kafka.common.security.scram.ScramLoginModule required username=\"%s\" password=\"%s\";";
String jaasCfg = String.format(jaasTemplate, username, password);
Properties props = new Properties();
props.put("sasl.jaas.config", jaasCfg);
// ...
Thread.currentThread().setContextClassLoader(null);
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
I run into the error:
org.apache.kafka.common.KafkaException: javax.security.auth.login.LoginException: unable to find LoginModule class: org.apache.kafka.common.security.scram.ScramLoginModule
at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:160)
at org.apache.kafka.common.network.ChannelBuilders.create(ChannelBuilders.java:146)
at org.apache.kafka.common.network.ChannelBuilders.clientChannelBuilder(ChannelBuilders.java:67)
at org.apache.kafka.clients.ClientUtils.createChannelBuilder(ClientUtils.java:99)
at org.apache.kafka.clients.producer.KafkaProducer.newSender(KafkaProducer.java:441)
at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:422)
I suspect that this is caused by setting the ClassLoader to null, but I'm not certain.
The JAAS string mentions this org.apache.kafka.common.security.scram.ScramLoginModule. I tried not using JAAS but instead plain username + password like so:
Properties props = new Properties();
props.put("sasl.username", username);
props.put("sasl.password", password);
// ...
Thread.currentThread().setContextClassLoader(null);
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
But that also resulted in an Exception, just mentioning a different Class could not be located:
org.apache.kafka.common.KafkaException: javax.security.auth.login.LoginException: unable to find LoginModule class: org.jboss.as.security.remoting.RemotingLoginModule
at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:160)
at org.apache.kafka.common.network.ChannelBuilders.create(ChannelBuilders.java:146)
at org.apache.kafka.common.network.ChannelBuilders.clientChannelBuilder(ChannelBuilders.java:67)
at org.apache.kafka.clients.ClientUtils.createChannelBuilder(ClientUtils.java:99)
at org.apache.kafka.clients.producer.KafkaProducer.newSender(KafkaProducer.java:441)
at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:422)
How can I make it, that the org.apache.kafka.common.security.scram.ScramLoginModule is found? Thanks!
Warning: ugly hack!
Just before you create the KafkaProducer, set the context classloader shown bellow:
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
I need to use ldap connection pooling in a web application. To authenticate admin, I am using below code:
Properties props = new Properties();
System.setProperty("com.sun.jndi.ldap.connect.pool", "true");
System.setProperty("com.sun.jndi.ldap.connect.pool.maxsize", "1");
System.setProperty("com.sun.jndi.ldap.connect.pool.debug", "fine");
props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
props.put(Context.PROVIDER_URL, "ldap://localhost:10389/o=myldap");
props.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");//adminuser
props.put(Context.SECURITY_CREDENTIALS, "xxxxx");
InitialDirContext context = new InitialDirContext(props);
To lookup and authenticate another user, I need to change the SECURITY_PRINCIPAL and SECURITY_CREDENTIALS and then create a new context again. When I do this is a POJO, it uses connection pool but when I use this in multi user web application (I tried it with two threads), it does not use connection pool.
What workaround can be used for this?
You need to set the parameters as JVM system parameters, using -D parameters on the java invocation.
System.setProperty("com.sun.jndi.ldap.connect.pool", "true");
System.setProperty("com.sun.jndi.ldap.connect.pool.maxsize", "1");
System.setProperty("com.sun.jndi.ldap.connect.pool.debug", "fine");
Wrong properties object. You should be setting those into the 'props' object, not the system properties object.
EDIT And don't debug to true. Setting it has has the curious effect of turning pooling off.
I'm seeing an issue where when connected to a mailbox using IMAP the infinite timeout default is causing an issue. I am having an issue getting Java Mail to recgonise IMAP properties. I verified IMAP did not seem to be using the properties by setting things like port number to the value 1, which should not work.
This is the code snippit:
Properties props = new Properties()
props.put("mail.imap.port", "1");
props.put("mail.imap.timeout", "1");
props.put("mail.imaps.connectiontimeout", "1");
Session session = Session.getInstance(props, null);
Store store = session.getStore("imaps");
store.connect(***,***,***);
If anyone knows where the problem is arising from that would great, all help is appreciated.
I believe you should be using props.setProperty(key, value) instead of using props.put(key, value). The documentation here: http://docs.oracle.com/javase/tutorial/essential/environment/properties.html warns you not to use hashTable methods
You're using the "imaps" protocol but setting properties for the "imap" protocol. Change your property names to "mail.imaps.*".
I have created the data source in Websphere server and its name is myDataSource(JNDI name is oracleDS). Now I want to access it through the stand alone application.
I just wrote the bellow code to access the data sorce.
Hashtable<String, String> pdEnv = new Hashtable<String, String>();
pdEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
pdEnv.put(Context.PROVIDER_URL, "iiop://localhost:2809");
Context initialContext = new InitialContext(pdEnv);
DataSource dataSource = (DataSource) initialContext
.lookup("java:comp/env/jdbc/oracleDS");
But when I run the application I am getting the bellow exception.
Aug 6, 2013 11:33:41 PM null null
SEVERE: javaAccessorNotSet
javax.naming.ConfigurationException: Name space accessor for the java: name space has not been set. Possible cause is that the user is specifying a java: URL name in a JNDI Context method call but is not running in a J2EE client or server environment.
Please let me know do I have to do any configuration changes in websphere to access the data source or any other code level changes do I have to do?
Please confirm me can we access the datasource from outside of the container(websphere)?
Update1:
I followd the way which PhilipJ mentioned. Then I am gtting the bellow exception.
SEVERE: Cannot get connection: javax.naming.NameNotFoundException: Context: LTC-VIRTUS-24WZNode01Cell/nodes/LTC-VIRTUS-24WZNode01/servers/server1, name: jdbc/oracleDS: First component in name oracleDS not found. [Root exception is org.omg.CosNaming.NamingContextPackage.NotFound: IDL:omg.org/CosNaming/NamingContext/NotFound:1.0]
javax.naming.NameNotFoundException: Context: LTC-VIRTUS-24WZNode01Cell/nodes/LTC-VIRTUS-24WZNode01/servers/server1, name: jdbc/oracleDS: First component in name oracleDS not found. [Root exception is org.omg.CosNaming.NamingContextPackage.NotFound: IDL:omg.org/CosNaming/NamingContext/NotFound:1.0]
at com.ibm.ws.naming.jndicos.CNContextImpl.mapNotFoundException(CNContextImpl.java:4365)
at com.ibm.ws.naming.jndicos.CNContextImpl.doLookup(CNContextImpl.java:1794)
at com.ibm.ws.naming.jndicos.CNContextImpl.doLookup(CNContextImpl.java:1749)
at com.ibm.ws.naming.jndicos.CNContextImpl.lookupExt(CNContextImpl.java:1500)
at com.ibm.ws.naming.jndicos.CNContextImpl.lookup(CNContextImpl.java:637)
at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:165)
at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:179)
at javax.naming.InitialContext.lookup(InitialContext.java:436)
at com.nyl.connection.ConnectionUtil.getConnection(ConnectionUtil.java:38)
at com.nyl.main.Main.main(Main.java:9)
Caused by: org.omg.CosNaming.NamingContextPackage.NotFound: IDL:omg.org/CosNaming/NamingContext/NotFound:1.0
at org.omg.CosNaming.NamingContextPackage.NotFoundHelper.read(NotFoundHelper.java:95)
at com.ibm.WsnOptimizedNaming._NamingContextStub.resolve_complete_info(_NamingContextStub.java:506)
at com.ibm.ws.naming.jndicos.CNContextImpl$2.run(CNContextImpl.java:2797)
at com.ibm.ws.naming.jndicos.CNContextImpl$2.run(CNContextImpl.java:2793)
at com.ibm.ws.naming.util.CommonHelpers.retry(CommonHelpers.java:763)
at com.ibm.ws.naming.jndicos.CNContextImpl.cosResolve(CNContextImpl.java:2791)
at com.ibm.ws.naming.jndicos.CNContextImpl.doLookup(CNContextImpl.java:1790)
... 8 more
Update2:
I found the way to avoid the exception. The code should be bellow,
Hashtable<String, String> pdEnv = new Hashtable<String, String>();
pdEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
pdEnv.put(Context.PROVIDER_URL, "iiop://localhost:2809");
Context initialContext = new InitialContext();
DataSource datasource = (DataSource) initialContext.lookup("oracleDS");
if (datasource != null) {
connection = datasource.getConnection("admin","admin");
} else {
LOGGER.info("Failed to lookup datasource.");
}
But the problem here is I am giving the database credintials to creat the connection. I don't want to give it. Can any one please let me know how to create the connection without giving the database credintials?
I found the solution for this issue.
When we creat the InitialContext we have to set two environment variables correctly as bellow,
Hashtable<String, String> pdEnv = new Hashtable<String, String>();
pdEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
pdEnv.put(Context.PROVIDER_URL, "iiop://localhost:2810");
Context initialContext = new InitialContext(pdEnv);
Note:
We can find the listening port of iiop protocol by using the bellow way,
Login to Webaphere admin console => Server => Server Types => Webspher application servers => Click on the name of the server which we use => Communication => Ports.
Then you can find the port for Port name BOOTSTRAP_ADDRESS.
Working code to create the connection using the datasource
Hashtable<String, String> pdEnv = new Hashtable<String, String>();
pdEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
pdEnv.put(Context.PROVIDER_URL, "iiop://localhost:2810");
Context initialContext = new InitialContext(pdEnv);
DataSource datasource = (DataSource) initialContext.lookup("testDS");
if (datasource != null) {
connection = datasource.getConnection("admin","admin"); // DB credintials
} else {
LOGGER.info("Failed to lookup datasource.");
}
Note: I created the data source in websphere(Version 7) and the JNDI name is testDS
and we have to add com.ibm.ws.ejb.thinclient_7.0.0.jar jar in the class path.
Thanks Sean F and PhilipJ for your support regarding this issue.
DataSource dataSource = (DataSource) initialContext
.lookup("jdbc/oracleDS");
try this way.
look here