I have been trying to get a Windows service running from my JAR file. WinRun4j seems to be able to do the job, but I can't get it to work. I am especially finding it quite difficult to debug. I tried several methods for logging (writing to a .txt file, WinRun4j's EventLog class) but I can't seem to generate any output.
The service installs fine (eventually..) and I can start it. It should start a Jetty server that generates an XML file that can be reached over HTTP. The app works for a stand-alone version, just not for the service. The service is started, but as soon as I call the URL it stops without generating an error.
This is my Service class:
package com.some.package;
import org.boris.winrun4j.AbstractService;
import org.boris.winrun4j.ServiceException;
/**
* A basic service.
*/
public class StockService extends AbstractService {
private StockServer srv;
public int serviceMain(String[] args) throws ServiceException {
while (!shutdown) {
try {
Thread.sleep(5000);
} catch(InterruptedException e) {
}
if(srv == null) {
try {
srv = new StockServer();
srv.start();
} catch (Exception e) {
}
}
}
return 0;
}
}
I found out that the service didn't want to start if I started the Jetty server from the serviceMain class. I had to start a new thread. So StockServer extends Thread:
public class StockServer extends Thread {
private Server server;
public void run() {
if (server == null) {
try {
server = new Server(8080);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/example");
StockServlet stockServlet = new StockServlet();
context.addServlet(new ServletHolder(stockServlet), "/stock/*");
server.setHandler(context);
server.setStopAtShutdown(true);
server.start();
server.join();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
Since it runs perfectly fine as Java application I just don't know how to get this thing debugged. I hope one of you can point me in the right direction :).
I ended up using the Java Service Wrapper (JSW). This seemed a lot more complex but ended up to be quite easy. It also provides logging by default so I could easily fix the errors. The JSW had problems finding the correct JDK, since JSW is 32bit and I installed JDK1.7 64 bit (and 1.6 32bit). Installing JDK1.7 32bit fixed it. That might have been the problem with WinRun4j as well, but that is something I will never know :).
Related
I have a GUI which uses RMI to get the data that has to be visualized. I'm doing server queries with an AnimationTimer, so in the worst case it could be 60 times/sec. When the server is running everything works perfectly.
However, if I run the client without the server beeing startet, the whole GUI gets really slow. It seems like the attempt to create a connection is the problem that blocks everything else. But I don't know how to solve it.
Another issue that I don't understand is following: When I close the server application via "x" in it's menubar there is still something running. I have to cancel the program a second time (in the Netbeans toolbar) to fully close it.
Following is the code which runs on client side. The getAllSignals()-method is invoked by an AnimationTimer:
public static RMI rmiConnect() {
try{
Registry reg = LocateRegistry.getRegistry("127.0.0.1", 1099);
RMI rmi = (RMI) reg.lookup("server");
return rmi;
} catch(RemoteException | NotBoundException e){
System.out.println(e);
return null;
}
}
public static Map<String, double> getAllSignals() throws RemoteException, IOException {
try {
RMI rmi = rmiConnect();
Map<String, double> signals = rmi.getAllSignals();
return (Map<String, double>) signals;
} catch (Exception ex) {
ExceptionsHandling exception = new ExceptionsHandling();
Map<String, double> list = exception.failedSignalsQuery();
return list;
}
}
While performing a client-server communication with various forums, I am unable to perform Remote-object's lookup on the client machine.
The errors which I receive are ConnectIOException(NoRouteToHostException), and sometimes ConnectException and sometimes someother.
This is not what I want to ask. But, the main concern is how should I setup client platform and server platform --- talking about networking details --- this is what I doubt interferes with my connection.
My questions :-
How should I edit my /etc/hosts file on both client-side and server-side? Server's IP- 192.168.1.8 & Client's IP-192.168.1.100. Means, should I add the system name in both the files:
192.168.1.8 SERVER-1 # on the server side
192.168.1.100 CLIENT-1 # on the client side
Should I edit like this? Can this be one of the possible concerns? I just want to remove any doubts left over to perform the rmi-communication!
Also, I am also setting Server's hostname property using System.setProperty("java.rmi.server.hostname",192.168.1.8); on the server side. Should I do the same on the client-side too?
I've read about setting classpath while running the java program on both server-side as well as the client-side. I did this too,but,again the same exceptions. No difference at all. I've read that since Java update 6u45, classpaths aren't necessary to include! Please throw some light on this too...
If I am missing something, Please enlighten about the same too. A brief idea/link to resources are most preferred.
You don't need any of this unless you have a problem. The most usual problem is the one described in the RMI FAQ #A.1, and editing the hosts file of the server or setting java.rmi.server.hostname in the server JVM is the solution to that.
'No route to host' is a network connectivity problem, not an RMI problem, and not one you'll solve with code or system property settings.
Setting the classpath has nothing to do with network problems.
Here is server example of which transfers an concrete class. This class must be exist in server and client classpath with same structure
Message:
public class MyMessage implements Serializable {
private static final long serialVersionUID = -696658756914311143L;
public String Title;
public String Body;
public MyMessage(String strTitle) {
Title = strTitle;
Body = "";
}
public MyMessage() {
Title = "";
Body = "";
}
}
And here is the server code that gets an message and returns another message:
public class SimpleServer {
public String ServerName;
ServerRemoteObject mRemoteObject;
public SimpleServer(String pServerName) {
ServerName = pServerName;
}
public void bindYourself() {
try {
mRemoteObject = new ServerRemoteObject(this);
java.rmi.registry.Registry iRegistry = LocateRegistry.getRegistry(RegistryContstants.RMIPort);
iRegistry.rebind(RegistryContstants.CMName, mRemoteObject);
} catch (Exception e) {
e.printStackTrace();
mRemoteObject = null;
}
}
public MyMessage handleEvent(MyMessage mMessage) {
MyMessage iMessage = new MyMessage();
iMessage.Body = "Response body";
iMessage.Title = "Response title";
return iMessage;
}
public static void main(String[] server) {
SimpleServer iServer = new SimpleServer("SERVER1");
iServer.bindYourself();
while (true) {
try {
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
and here is the remote interface of server remote object:
public interface ISimpleServer extends java.rmi.Remote{
public MyMessage doaction(MyMessage message) throws java.rmi.RemoteException;
}
all you need is adding MyMessage class both in server and client classpath.
I have an issue with JGroups where after building my project, running it produces this error:
Caused by: java.lang.ClassNotFoundException: org.jgroups.ReceiverAdapter
My class looks something like this -
import org.jgroups.ReceiverAdapter;
import org.jgroups.Channel;
import org.jgroups.JChannel;
public class MyClass extends ReceiverAdapter implements MyInterface {
Channel channel;
String state = "state";
public MyClass() {
super();
start();
}
public void start() {
try {
channel = new JChannel();
channel.setReceiver(this);
channel.connect("ServerCluster");
channel.getState(null, 0);
System.out.println("Connected to cluster");
} catch (Exception e) {
System.out.println("Failed to connect to cluster");
}
}
public void getState(OutputStream output) throws Exception {
System.out.println("get response");
}
public void setState(InputStream input) throws Exception {
System.out.println("set test");
}
}
Running the project from IntelliJ produces no errors, but does not produce the desired prints from getState() and setState() either. I tried creating a brand new project in the Eclipse IDE, but the same is happening there too. Connecting has been working fine, states is a new addition to my project.
Running java MyClass from the command line fires the error seen at the start of this question. The JGroups jar seems to be added to the classpath properly as org.jgroups.Channel and org.jgroups.Channel (among others) are being found.
There is a SimpleChat program provided by the JGroup devs, but when I created a new project for this I encountered the same problem.
Edit
So it turns out I have to explicitly set the classpath when running from the CLI. But still, when running the code it seems like the getState() and setState() methods are never called as there are no print statements. SimpleChat doesn't print received state... like it is meant to.
Does anyone have a solution?
Best.
So, I on the JChannel I was using RpcDispatcher and it seems I can't use the dispatcher and the getState() and setState() methods on the same channel. Simple solution: create a second channel. Seems my knowledge on the fundamentals of JGroups is lacking!
I am trying to implement a web service which triggers OCR actions of the server side.
Client code:
...
sy = belgeArsivle(testServisIstegi, ab);
...
private static ServisYaniti belgeArsivle(com.ocr.ws.ServiceRequest serviceRequest,com.ocr.ws.Document document) {
com.ocr.ws.ServiceRequest service = new com.ocr.ws.OCRArsivWSService();
com.ocr.ws.OCRArsivWS port = service.getOCRArsivWSPort();
return port.docArchive(serviceRequest, document);
}
When I run the code on the server side there is no problem. But whenever I call the web service method from the client I got this error code:
Exception: javax.xml.ws.soap.SOAPFaultException: Unable to load library 'libtesseract302': The specified module could not be found.
The working server-side code is:
public static void main(String[] args) {
// TODO code application logic here
File imageFile = new File("...OCR\\testTurWithBarcodeScanned.png");
Tesseract instance = Tesseract.getInstance();
try {
String lang = "tur";
instance.setLanguage(lang);
String result = instance.doOCR(imageFile);
System.out.println(result);
// write in a file
try {
File file = new File("...MyOutputWithBarcode.txt");
BufferedWriter out = new BufferedWriter(new FileWriter(file));
out.write(result);
out.close();
} catch (IOException ex) {
}
} catch (TesseractException ep) {
System.err.println(ep.getMessage());
}
}
I know that this error code is about Tesseract libraries. I put the corresponding .dll files (liblept168 and libtesseract302) under the client project's folder, added corresponding libraries (jna, jai_imageio, ghost4j_0.3.1), did neccessary changes in classpath but still getting this error.
I run a test code on the server side, it works fine. But the client side code is not working. Do I need to make some extra adjustment on the client side to run this web service?
I found out that the actual problem was with the Tomcat Server. I had to put the jar files to the Tomcat's Sources under Properties, than voila!
We're using embedded Tomcat 7 to host a web application.
It works very well, with one slight exception.
The reason that we're using embedded Tomcat is because we need to operate on multiple platforms and our architect has made the call.
The Problem
We would like to give our users the ability to check for WAR updates while the wrapper/container Java application is running (live update).
Currently they have to restart our application which is much less desirable.
Basically, our code just checks a remote server for newer WAR files, if they exist they are downloaded.
The problem is that we can't seem to get the Tomcat server to shutdown or release lock that it has on the exploded WAR folders.
If we completely destroy the Tomcat instance, then we can deploy the WAR files and delete the exploded WAR folders, but Tomcat won't explode and host them until we completely kill the wrapper/container JAVA application and re-launch.
Once we re-launch, Tomcat explodes the WAR files and hosts the applications nicely.
What I'm Looking For
I'm hoping that there is a way to either un-deploy the application being updated or properly shutdown/stop the Tomcat server.
Code Sample
I simplified the below code sample by not including the implementation for the downloading as this works fine.
The Tomcat instance isn't public, but just made it so for ease of use.
Also, the sleep within the Thread was just thown-in to simplify the example.
The endless-loop was just put in for this sample.
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.Context;
import org.apache.catalina.Globals;
import org.apache.catalina.LifecycleState;
import org.apache.catalina.loader.WebappLoader;
import org.apache.catalina.startup.Tomcat;
...
public class Testing123
{
public static void main(String[] args)
{
final Testing123 test = new Testing123();
test.createTomcat();
test.downloadUpdate();
(new Thread())
{
public void run()
{
Thread.sleep(10000);
test.downloadUpdate();
}
}.start();
while (true)
{
// this loop is just for this example...
}
}
public Tomcat tomcat = null;
private String webappsPath = "c:\\tomcat\\webapps";
private void createTomcat()
{
this.tomcat = new Tomcat();
this.tomcat.setBaseDir(this.webappsPath);
this.tomcat.setPort("5959");
this.tomcat.getServer().setPort("5960");
this.tomcat.getServer().setShutdown("SHUTDOWN");
this.tomcat.getHost().setCreateDirs(true);
this.tomcat.getHost().setDeployIgnore(null);
this.tomcat.getHost().setDeployOnStartup(true);
this.tomcat.getHost().setAutoDeploy(true);
this.tomcat.getHost().setAppBase(this.webappsPath);
Context ctx = this.tomcat.addWebapp(null, "/app1", "APP1");
ctx.setLoader(new WebappLoader(Testing123.class.getClassLoader()));
ctx.setReloadable(true);
}
private boolean isTomcatRunning()
{
if ((this.tomcat == null) || (LifecycleState.STARTED == this.tomcat.getServer().getState()))
{
return true;
}
return false;
}
private void shutdownTomcat() throws Exception
{
if (this.isTomcatRunning())
{
if ((this.tomcat!= null) && (this.tomcat.getServer() != null))
{
this.tomcat.stop();
while ((LifecycleState.STOPPING == this.tomcat.getServer().getState()) || (LifecycleState.STOPPING_PREP == this.tomcat.getServer().getState()))
{
// wait for the server to stop.
}
}
}
}
private void startTomcat() throws Exception
{
if (this.isTomcatRunning())
{
if ((this.tomcat!= null) && (this.tomcat.getServer() != null))
{
try
{
this.tomcat.init();
while (LifecycleState.INITIALIZING == this.tomcat.getServer().getState())
{
// wait for the server to initialize.
}
}
catch (Throwable e)
{
// ignore
}
this.tomcat.start();
while ((LifecycleState.STARTING == this.tomcat.getServer().getState()) || (LifecycleState.STARTING_PREP == this.tomcat.getServer().getState()))
{
// wait for the server to start.
}
}
}
}
private void downloadUpdate()
{
this.shutdownTomcat();
// Download the WAR file and delete the exploded WAR folder...
this.startTomcat();
}
}