I am trying to connect to a QM and send message to one of the queues, using below code:
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.JMSException;
import com.ibm.msg.client.commonservices.*;
import com.ibm.mq.commonservices.internal.trace.*;
import com.ibm.msg.client.jms.JmsConnectionFactory;
import com.ibm.msg.client.jms.JmsFactoryFactory;
import com.ibm.msg.client.wmq.WMQConstants;
public class MQConnect {
public static void main(String[] args) {
Connection connection = null;
Session session = null;
Destination destination = null;
Destination tempDestination = null;
MessageProducer producer = null;
MessageConsumer consumer = null;
try {
System.out.println(WMQConstants.WMQ_PROVIDER);
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
JmsConnectionFactory cf = ff.createConnectionFactory();
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, "hostname");
cf.setIntProperty(WMQConstants.WMQ_PORT, port);
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, "channel");
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, "QMName");
connection = cf.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = session.createQueue("test_java_q");
producer = session.createProducer(destination);
long uniqueNumber = System.currentTimeMillis() % 1000;
TextMessage message = session.createTextMessage(" " + uniqueNumber);
connection.start();
producer.send(message);
}catch (JMSException jmsex) {
System.out.println(jmsex.getErrorCode());
System.out.println(jmsex.getLinkedException().getCause());
System.out.println(jmsex.getMessage());
}
}
}
The error I'm getting is :
Exception in thread "main" java.lang.NoClassDefFoundError:
com/ibm/msg/client/commonservices/trace/Trace
at com.ibm.msg.client.jms.JmsFactoryFactory.<clinit>(JmsFactoryFactory.java:54)
at MQConnect.main(MQConnect.java:33)
Caused by: java.lang.ClassNotFoundException: com.ibm.msg.client.commonservices.trace.Trace
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 2 more
I have the required jar files but I believe something is still missing from project references.
I have checked the jars and class specified in error is present in one of the jar files.
These are the jar files I have referenced:
com.ibm.mq.headers.jar
com.ibm.mq.jar
com.ibm.mq.pcf.jar
com.ibm.mq.tools.ras.jar
jms.jar
com.ibm.mqjms.jar
com.ibm.mq.jmqi.jar
com.ibm.mq.commonservices.jar
There are also several other jars which are not com.ibm.*
Any suggestions?
You really shouldn't be picking and choosing MQ JAR files. For IBM MQ v8.0 or higher, you should be using the com.ibm.mq.allclient.jar and jms.jar files. That's it, just 2 files. IBM has posted the com.ibm.mq.allclient.jar file on Maven (and use the most recent one). You can find com.ibm.mq.allclient.jar here and jms.jar from here.
If you are using IBM MQ v7.5 or lower (which all releases are out of support) then the correct JAR files are:
connector.jar
com.ibm.mq.jar
com.ibm.mq.commonservices.jar
com.ibm.mq.headers.jar
com.ibm.mq.jmqi.jar
com.ibm.mq.pcf.jar
com.ibm.mqjms.jar
jms.jar
fscontext.jar
jndi.jar
jta.jar
ldap.jar
Also, do NOT mix and match JAR files between different releases of IBM MQ. It will cause you all kinds of headaches.
Finally, what is this line:
destination = session.createQueue("test_java_q");
It should be:
destination = context.createQueue("queue:///MY.TEST.QUEUE");
where 'MY.TEST.QUEUE' actually exists in the queue manager. All MQ objects are case sensitive and MQ Best Practises says to use uppercase object names. i.e. avoid lowercase names.
Updated Feb. 14, 2022.
You need to add some code to your program so we can see what is going on.
(1) Add the following MQLevel class (taken from my open source project Universal File Mover) to your project:
public class MQLevel extends MQJavaLevel
{
/**
* The constructor
*/
public MQLevel()
{
super();
}
/**
* Get the IBM name for the MQ JAR class.
* #return
*/
public String getName()
{
return queryValue(0);
}
/**
* Get the version of the MQ JAR class.
* #return
*/
public String getVersion()
{
return queryValue(1);
}
}
(2) Next add the following lines of code in your main method or at the very top of your code:
System.out.println(System.getProperty("java.class.path").replace(';','\n'));
try
{
MQLevel mql = new MQLevel();
System.out.println("MQ JAR Version = " + mql.getName()+" V"+mql.getVersion());
}
catch(Exception e)
{
e.printStackTrace();
}
Note: If you are on Linux/Unix rather than Windows then change the ';' (semi-colon) in the replace method to a ':' (colon).
i.e.
System.out.println(System.getProperty("java.class.path").replace(':','\n'));
Run your program with the updates, then update the original posting both with the new output.
Related
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Producer {
private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;
private static String QUEUE_NAME = "kesaven";
private static final Logger logger = LogManager.getLogger(Producer.class.getName());
public static void main(String[] args) throws JMSException
{
//System.out.println(url);
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(QUEUE_NAME);
MessageProducer producer = session.createProducer(destination);
//TextMessage message = session.createTextMessage("My first log message to queue");
logger.info("My first log message to queue");
//producer.send(message);
//System.out.println("Sentage '" + message.getText() + "'");
connection.close();
}
}
i am trying to log the message to a queue using log4j2 and activemq. i am using log4j2.3 and for queue i am using activemq 5.9.0 . i am able to see exception message in queue not the message i sent. Following is the error message in queue
javax.jms.JMSException: Failed to build body from content.
Serializable class not available to broker. Reason:
java.lang.ClassNotFoundException:
org.apache.logging.log4j.core.impl.Log4jLogEvent$LogEventProxy
What appender are you using to write the data to ActiveMQ? I would suggest that instead of using Java serialization to write the log event that you serialize it to JSON, use the RFC5424 layout or some other format that doesn't require the Log4j2 jars when reading the events.
Since the Log4event is put on the queue , can you check if you have the log4j2 jars available on the broker end.
I added the following jars from log4j2 to the activeMQ server /lib directory to make this work
log4j-api-2.6.1,
log4j-core-2.6.1
I logged Strings only, if I tried to log ObjectMessages, the queue entry would not open in the Queue manager view, the JSP failed.
I have an application that uses embedded jetty. When I run this application in Netbeans IDE then I can browse my site # localhost:8080/
When I launch the jar file of my application from command line: java -jar app.jar then browsing localhost:8080/ jetty server says "page not found"
What am I missing here? Can't figure out the problem.
EDIT:
Netbeans project is uploaded to Github
Everything works fine if I run this project in Netbeans.
But when I take the jar file with lib folder and run it in cmd like this: java -jar EmbeddedJettyJspJstl.jar
Then navigating to http://localhost:8080/test I get errors:
org.apache.jasper.JasperException: java.lang.ClassNotFoundException: org.apache.jsp.WEB_002dINF.jstl_jsp
org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
My JSP page uses JSTL and looks like it is not locating the jstl libraries?
And this is the code that starts the server:
package server;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.AllowSymLinkAliasChecker;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* #author lkallas
*/
public class JettyServer {
// Resource path pointing to where the WEBROOT is
private static final String WEBROOT = "/webapp/";
private static final Logger logger = LoggerFactory.getLogger(JettyServer.class);
public void start() throws IOException, InterruptedException, URISyntaxException {
Server server = new Server();
// HTTP connector
ServerConnector connector = new ServerConnector(server);
connector.setHost("localhost");
connector.setPort(8080);
connector.setIdleTimeout(30000);
// Set the connector
server.addConnector(connector);
// Setup JMX for web applications
MBeanContainer mbContainer = new MBeanContainer(
ManagementFactory.getPlatformMBeanServer());
server.addBean(mbContainer);
//Setting up web application
WebAppContext webapp = new WebAppContext();
webapp.setAttribute("javax.servlet.context.tempdir", getScratchDir());
webapp.setDescriptor(WEBROOT + "WEB-INF/web.xml");
webapp.setResourceBase(getWebRootResourceUri().toASCIIString());
webapp.setContextPath("/");
webapp.setWar(getWebRootResourceUri().toASCIIString());
webapp.addAliasCheck(new AllowSymLinkAliasChecker());
//For debugging
logger.info("Descriptor file: {}", webapp.getDescriptor());
logger.info("Resource base: {}", getWebRootResourceUri().toASCIIString());
logger.info("WAR location: {}", webapp.getWar());
HandlerList handlerList = new HandlerList();
handlerList.setHandlers(new Handler[]{webapp, new DefaultHandler()});
// This webapp will use jsps and jstl. We need to enable the
// AnnotationConfiguration in order to correctly
// set up the jsp container
Configuration.ClassList classlist = Configuration.ClassList
.setServerDefault(server);
classlist.addBefore(
"org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
"org.eclipse.jetty.annotations.AnnotationConfiguration");
// Set the ContainerIncludeJarPattern so that jetty examines these
// container-path jars for tlds, web-fragments etc.
// If you omit the jar that contains the jstl .tlds, the jsp engine will
// scan for them instead.
webapp.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*/[^/]*taglibs.*\\.jar$");
// A WebAppContext is a ContextHandler as well so it needs to be set to
// the server so it is aware of where to send the appropriate requests.
server.setHandler(handlerList);
try {
server.start();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
server.dumpStdErr();
}
/**
* Establish Scratch directory for the servlet context (used by JSP
* compilation)
*/
private File getScratchDir() throws IOException {
File tempDir = new File(System.getProperty("java.io.tmpdir"));
File scratchDir = new File(tempDir.toString(), "embedded-jetty");
if (!scratchDir.exists()) {
if (!scratchDir.mkdirs()) {
throw new IOException("Unable to create scratch directory: " + scratchDir);
}
}
return scratchDir;
}
/**
* Get webroot URI.
*
* #return
* #throws FileNotFoundException
* #throws URISyntaxException
*/
private URI getWebRootResourceUri() throws FileNotFoundException, URISyntaxException {
URL indexUri = this.getClass().getResource(WEBROOT);
if (indexUri == null) {
throw new FileNotFoundException("Unable to find resource " + WEBROOT);
}
logger.debug("WEBROOT: {}", indexUri.toURI().toASCIIString());
return indexUri.toURI();
}
}
I have already looked # http://www.eclipse.org/jetty/documentation/current/advanced-embedding.html
There's a number of reasons and causes that could be affecting you.
However you haven't posted any code to help us identify what the specific cause is.
The Jetty Project maintains an example for this setup, btw.
https://github.com/jetty-project/embedded-jetty-uber-jar
Pay attention to your context.setContextPath() (like #Haider-Ali pointed out), and also your context.setBaseResource()
For JSPs in Embedded Jetty you can look at the other example project
https://github.com/jetty-project/embedded-jetty-jsp
Note prior answer about Embedded Jetty and JSP.
I'm using in my program the bluecove library.
While running the program via eclipse, all works smooth. I'm now trying to deploy my program, and following this post i'm using fat-jar.
When i run the jar file (created by fat-jar), the library can't be located, and i'm getting the exception BlueCove libraries not available as result of this line local = LocalDevice.getLocalDevice();.
In the fat-jar window i tried also to add bluecove-2.1.0.jar to the Class-Path place, and also with the path \src\JoJoServer\bluecove-2.1.0.jar.
I tried also to place the bluecove's jar file in different folders, such as the src, or an external folder.
Although i know it's not recommended, i tried the option of One-Jar, nevertheless it didn't help.
To run the jar (the one created by fat jar) i simply double click the file.
What i'm missing?
This is the entire code:
import java.io.IOException;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
#Override
public void run() {
// retrieve the local Bluetooth device object
LocalDevice local = null;
StreamConnectionNotifier notifier;
StreamConnection connection = null;
// setup the server to listen for connection
try {
local = LocalDevice.getLocalDevice();
local.setDiscoverable(DiscoveryAgent.GIAC);
UUID uuid = new UUID("0000110100001000800000805F9B34FB", false);
System.out.println(uuid.toString());
String url = "btspp://localhost:" + uuid.toString() + ";name=RemoteBluetooth";
notifier = (StreamConnectionNotifier)Connector.open(url);
} catch (BluetoothStateException e) {
System.out.println("Bluetooth is not turned on.");
e.printStackTrace();
return;
}
// ...
}
I have no clue what could be your problem, but I've tried the process and everything works, so just a summary of what I've did. Maybe you will figure it out by following it...
I don't understand how the posted code could be the entire, I see no class definition. :)
So I've modified it to the main method and it works both from the Eclipse and also by running the JAR generated by the FatJar.
The modified code of the BTTest class:
package test;
import java.io.IOException;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
public class BTTest {
public static void main(String[] args) throws Exception{
// retrieve the local Bluetooth device object
LocalDevice local = null;
StreamConnectionNotifier notifier;
StreamConnection connection = null;
// setup the server to listen for connection
try {
local = LocalDevice.getLocalDevice();
local.setDiscoverable(DiscoveryAgent.GIAC);
UUID uuid = new UUID("0000110100001000800000805F9B34FB", false);
System.out.println(uuid.toString());
String url = "btspp://localhost:" + uuid.toString()
+ ";name=RemoteBluetooth";
notifier = (StreamConnectionNotifier) Connector.open(url);
} catch (BluetoothStateException e) {
System.out.println("Bluetooth is not turned on.");
e.printStackTrace();
return;
}
// ...
}
}
To run or produce it, I have just put the bluecove library in the build path and created the fat jar with a simple way:
http://oi60.tinypic.com/vg1jpt.jpg
Starting the generated jar from command line:
D:\testProjects\bttest>java -jar bttest_fat.jar
BlueCove version 2.1.0 on winsock
0000110100001000800000805f9b34fb
BlueCove stack shutdown completed
Can you post a difference to your process?
I would like to publish a test message to EMS topic and could use some directions. So far I have managed to do this
import com.tibco.tibjms.TibjmsConnectionFactory;
import com.tibco.tibjms.TibjmsTopicConnectionFactory;
public class Connect {
public static void main(String[] args) {
String url = "tcp://host:6600";
TibjmsConnectionFactory cf = new TibjmsTopicConnectionFactory(url);
cf.setUserName("user1");
cf.setUserPassword("");
System.out.println(cf);
}
}
which produces the below. How do I publish a message to topic "topic1" or queue "Q1"
TopicConnectionFactory[URL=tcp://localhost:6600;clientID=null;Properties={com.tibco.tibjms.factory.password=, com.tibco.tibjms.factory.username=user1}]
I created the following code by modifying the "tibjmsMsgProducer.java" from my EMS 8.0 "sample" folder. Look at all the Java example in this folder for further references.
This code publish a simple hard-coded text message to a local EMS with default user and password. The target Topic is "topic1" (on the last line).
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
public class tibjmsMsgTopicProducer {
static String serverUrl = "localhost";
static String userName = "admin";
static String password = "admin";
public static void sendTopicMessage(String topicName, String messageStr) {
Connection connection = null;
Session session = null;
MessageProducer msgProducer = null;
Destination destination = null;
try {
TextMessage msg;
System.out.println("Publishing to destination '" + topicName
+ "'\n");
ConnectionFactory factory = new com.tibco.tibjms.TibjmsConnectionFactory(
serverUrl);
connection = factory.createConnection(userName, password);
/* create the session */
session = connection
.createSession(javax.jms.Session.AUTO_ACKNOWLEDGE);
/* create the destination */
destination = session.createTopic(topicName);
/* create the producer */
msgProducer = session.createProducer(null);
/* publish messages */
/* create text message */
msg = session.createTextMessage();
/* set message text */
msg.setText(messageStr);
/* publish message */
msgProducer.send(destination, msg);
System.out.println("Published message: " + messageStr);
/* close the connection */
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
/*-----------------------------------------------------------------------
* main
*----------------------------------------------------------------------*/
public static void main(String[] args) {
tibjmsMsgTopicProducer.sendTopicMessage("topic1",
"This is the message content !");
}
}
Note : You could also want to use EMS with Spring-JMS for a more "Enterprise grade" solution. The code above is a lot simpler.
Note2: I made the method "static". This is only for demonstration purpose. Connections are costly in JMS, so normally we try to reuse them. See all TIBCO provided example for better setup of the Java classes. Instantiate and reuse connections if you can.
Additionally, J2EE or Spring solutions will have support for connection pools built-in.
I haven't touched EMS for some time - but basically EMS is nothing but a JMS implementation. All implementation specific stuff has been hidden for you. You just use standard JMS way to pub/sub to topics, which you can find good example on Java tutorial and online sources. I would save my ugly sample code here :-)
You can take a look at this test project #gelnyang built. And this is the class for publishing EMS message specifically. Under the project, you can find other EMS related functionalities as well.
I'm in the process of making a proof of concept to dissociate the business code from the gui for the ps3 media server (http://www.ps3mediaserver.org/). For this I've got a project hosted at source forge (http://sourceforge.net/projects/pms-remote/). The client should be a simple front end to configure the server from any location within a network having the rights to connect to the server.
On the server side, all service have been exposed using javax.jws and the client proxy has been generated using wsimport.
One of the features of the current features (actually, the only blocking one), is to define the folders that will be shared by the server. As the client and server are now running as a single application on the same machine, it's trivial to browse its file system.
Problem: I'd like to expose the file system of the server machine through web services. This will allow any client (the one I'm currently working on is the same as the original using java swing) to show available folders and to select the ones that will be shown by the media server. In the end the only thing I'm interested in is an absolute folder path (string).
I thought I'd find a library giving me this functionality but couldn't find any.
Browsing the files using a UNC path and accessing a distant machine doesn't seem feasible, as it wouldn't be transparent for the user.
For now I don't want to worry about security issues, I'll figure these out once the rest seems feasible.
I'd be grateful for any input.
Thanks, Philippe
I've ended up creating a pretty simple web service letting either list all root folders or all child folders for a given path.
It's now up to the client to have a (GUI) browser to access this service.
package net.pms.plugin.webservice.filesystem;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import net.pms.plugin.webservice.ServiceBase;
#WebService(serviceName = "FileSystem", targetNamespace = "http://ps3mediaserver.org/filesystem")
public class FileSystemWebService extends ServiceBase {
#WebMethod()
public List<String> getRoots() {
List<String> roots = new ArrayList<String>();
for(File child : File.listRoots()) {
roots.add(child.getAbsolutePath());
}
return roots;
}
#WebMethod()
public List<String> getChildFolders(#WebParam(name="folderPath") String folderPath) throws FileNotFoundException {
List<String> children = new ArrayList<String>();
File d = new File(folderPath);
if(d.isDirectory()) {
for(File child : d.listFiles()) {
if(child.isDirectory() && !child.isHidden()) {
children.add(child.getAbsolutePath());
}
}
} else {
throw new FileNotFoundException();
}
return children;
}
}
For people wanting to use this, here's the ServiceBase class as well
package net.pms.plugin.webservice;
import javax.xml.ws.Endpoint;
import org.apache.log4j.Logger;
public abstract class ServiceBase {
private static final Logger log = Logger.getLogger(ServiceBase.class);
protected boolean isInitialized;
/**
* the published endpoint
*/
private Endpoint endpoint = null;
/**
*
* Start to listen for remote requests
*
* #param host ip or host name
* #param port port to use
* #param path name of the web service
*/
public void bind(String host, int port, String path) {
String endpointURL = "http://" + host + ":" + port + "/" + path;
try {
endpoint = Endpoint.publish(endpointURL, this);
isInitialized = true;
log.info("Sucessfully bound enpoint: " + endpointURL);
} catch (Exception e) {
log.error("Failed to bind enpoint: " + endpointURL, e);
}
}
/**
* Stop the webservice
*/
public void shutdown() {
log.info("Shut down " + getClass().getName());
if (endpoint != null)
endpoint.stop();
endpoint = null;
}
}
From the client, you might be able to leverage the output of smbclient -L. On the server, a suitable servlet might do.