Tomcat/websocket responding with error 404 - java

I have developed a web site locally on my mac using tomcat 8.0.027 and java jdk 7. The site relies on websockets and all works well locally. When I deploy the site to a virtual private java server I get an error 404. The url for the websocket is ws://www.modelstudio3d.com/handler, my site is www.modelstudio3d.com. I've tried appending :8080 to the host name, that changes the error to connection refused. Changing the url to ../handlerx also generates a connection refused. I've checked that I'm not packaging additional websocket jars in my war file (I'm not as far as I can tell). My server is running tomcat 8.0.22 and JDK 7. My ISP is unable to provide any guidance.
My client code is
this.getWebSocketURI = function () {
var loc = window.location, wsUri;
if (loc.protocol === "https:") {
wsUri = "wss:";
} else {
wsUri = "ws:";
console.log("Websocket is not secure.");
}
wsUri += "//" + loc.host;
wsUri += loc.pathname + "handler";
console.log("wsUri" + wsUri);
return wsUri;
};
this.init = function () {
var self = this;
self.websocket = new WebSocket(self.getWebSocketURI());
...
The interesting part of the server code is
#ServerEndpoint(value = "/handler",
configurator = GetHttpSessionConfigurator.class)
public class WebSocket {
I've read something here about an Apache location filter that might be interfering by redirecting ws: to http: but have no idea where that resides or how to change it.

My hosting service finally agreed to investigate the problem. They say mod_proxy_wstunnel is not enabled and cannot be enabled. Don't use Mocha Host if you need to use websockets.

Related

cloudrail java desktop app

I'm trying to use cloudrail SDK in my java desktop app for testing ,
but I have problem with runing the sample code in cloudrailsite;
the following codes are main class:
public class DropboxWithCloudRail {
private static String REDIRECT_URL = "http://localhost:3000/";
InputStream inputStream = null;
public void loadDropbox() throws FileNotFoundException, ParseException {
CloudRail.setAppKey("*************");
Dropbox service = new Dropbox(new LocalReceiver(8082),
"*************",
"*************",
REDIRECT_URL,
"Dropbox"
);
service.createFolder(
"/myFolder1"
);
}
}
I set the Redirect URIs in dropbox console http://localhost:3000/
but when I run the project , I get this page:
This site can’t be reached
localhost refused to connect.
Did you mean http://localhost3000.org/?
Search Google for localhost 3000
ERR_CONNECTION_REFUSED
The issue seems to be that you configure your LocalRedirect receiver with the port 8082 which makes it wait for incoming redirects on http://localhost:8082. So this is the URL you have to use as a redirect uri for Dropbox and not http://localhost:3000.

Vertx HttpClient getNow not working

I have problem with vertx HttpClient.
Here's code which shows that tests GET using vertx and plain java.
Vertx vertx = Vertx.vertx();
HttpClientOptions options = new HttpClientOptions()
.setTrustAll(true)
.setSsl(false)
.setDefaultPort(80)
.setProtocolVersion(HttpVersion.HTTP_1_1)
.setLogActivity(true);
HttpClient client = vertx.createHttpClient(options);
client.getNow("google.com", "/", response -> {
System.out.println("Received response with status code " + response.statusCode());
});
System.out.println(getHTML("http://google.com"));
Where getHTML() is from here: How do I do a HTTP GET in Java?
This is my output:
<!doctype html><html... etc <- correct output from plain java
Feb 08, 2017 11:31:21 AM io.vertx.core.http.impl.HttpClientRequestImpl
SEVERE: java.net.UnknownHostException: failed to resolve 'google.com'. Exceeded max queries per resolve 3
But vertx can't connect. What's wrong here? I'm not using any proxy.
For reference: a solution, as described in this question and in tsegismont's comment here, is to set the flag vertx.disableDnsResolver to true:
-Dvertx.disableDnsResolver=true
in order to fall back to the JVM DNS resolver as explained here:
sometimes it can be desirable to use the JVM built-in resolver, the JVM system property -Dvertx.disableDnsResolver=true activates this behavior
I observed this DNS resolution issue with a redis client in a kubernetes environment.
I had this issue, what caused it for me was stale DNS servers being picked up by the Java runtime, i.e. servers registered for a network the machine was no longer connected to. The issue is first in the Sun JNDI implementation, it also exists in Netty which uses JNDI to bootstrap its list of name servers on most platforms, then finally shows up in VertX.
I think a good place to fix this would be in the Netty layer where the set of default DNS servers is bootstrapped. I have raised a ticket with the Netty project so we'll see if they agree with me! Here is the Netty ticket
In the mean time a fairly basic workaround is to filter the default DNS servers detected by Netty, based on whether they are reachable or not. Here is a code Sample in Kotlin to apply before constructing the main VertX instance.
// The default set of name servers provided by JNDI can contain stale entries
// This default set is picked up by Netty and in turn by VertX
// To work around this, we filter for only reachable name servers on startup
val nameServers = DefaultDnsServerAddressStreamProvider.defaultAddressList()
val reachableNameServers = nameServers.stream()
.filter {ns -> ns.address.isReachable(NS_REACHABLE_TIMEOUT)}
.map {ns -> ns.address.hostAddress}
.collect(Collectors.toList())
if (reachableNameServers.size == 0)
throw StartupException("There are no reachable name servers available")
val opts = VertxOptions()
opts.addressResolverOptions.servers = reachableNameServers
// The primary Vertx instance
val vertx = Vertx.vertx(opts)
A little more detail in case it is helpful. I have a company machine, which at some point was connected to the company network by a physical cable. Details of the company's internal name servers were set up by DHCP on the physical interface. Using the wireless interface at home, DNS for the wireless interface gets set to my home DNS while the config for the physical interface is not updated. This is fine since that device is not active, ipconfig /all does not show the internal company DNS servers. However, looking in the registry they are still there:
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces
They get picked up by the JNDI mechanism, which feeds Netty and in turn VertX. Since they are not reachable from my home location, DNS resolution fails. I can imagine this home/office situation is not unique to me! I don't know whether something similar could occur with multiple virtual interfaces on containers or VMs, it could be worth looking at if you are having problems.
Here is the sample code which works for me.
public class TemplVerticle extends HttpVerticle {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
// Create the web client and enable SSL/TLS with a trust store
WebClient client = WebClient.create(vertx,
new WebClientOptions()
.setSsl(true)
.setTrustAll(true)
.setDefaultPort(443)
.setKeepAlive(true)
.setDefaultHost("www.w3schools.com")
);
client.get("www.w3schools.com")
.as(BodyCodec.string())
.send(ar -> {
if (ar.succeeded()) {
HttpResponse<String> response = ar.result();
System.out.println("Got HTTP response body");
System.out.println(response.body().toString());
} else {
ar.cause().printStackTrace();
}
});
}
}
Try using web client instead of httpclient, here you have an example (with rx):
private val client: WebClient = WebClient.create(vertx, WebClientOptions()
.setSsl(true)
.setTrustAll(true)
.setDefaultPort(443)
.setKeepAlive(true)
)
open fun <T> get(uri: String, marshaller: Class<T>): Single<T> {
return client.getAbs(host + uri).rxSend()
.map { extractJson(it, uri, marshaller) }
}
Another option is to use getAbs.

Consuming web service from a remote computer

I have a desktop application built with jdk 6 which publishes web services to be consumed by a web application. So far I've had no problem while both applications are running in the same physical computer, i can access the wsdl without any problem and the web application works with the desktop application just fine. The thing is I cannot access to the services from a remote computer in the same network. The two PCs are connected and can interact. If I run both applications in PC1, from PC2 I can use the webapp through
http://PC1:8080
I am currently publishing like this:
public Publicador(){
servicios= new Servicios();
Endpoint endpoint = Endpoint.publish("http://PC1:8686/servicios", servicios);
}
where PC1 is the name of the pc. From PC1, i can see the generated wsdl from the following address, and it's the one I used for the wsimport command:
http://PC1:8686/servicios?wsdl
But I cannnot from PC2.
Any ideas why it is not visible from outside PC1?
Incredible as it may seem, I found the simplest of answers... Instead of publishing as
Endpoint endpoint = Endpoint.publish("http://PC1:8686/servicios", servicios);
I published as
Endpoint endpoint = Endpoint.publish("http://0.0.0.0:8686/servicios", servicios);
and that solved it...
Another solution was to get the address to publish from a file, that worked too. I don't know why it didn't hardcoded... I ended up doing it like this:
Properties prop = new Properties();
InputStream is = null;
String currenDir = System.getProperty("user.dir");
String nombreArchivo = currenDir + File.separator + "ubicacion.PROPERTIES";
try {
is=new FileInputStream(nombreArchivo);
prop.load(is);
} catch(IOException ioe) {}
String pc = prop.getProperty("ServiciosWeb");
Endpoint endpoint = Endpoint.publish( pc, servicios);
}

WebSockets, GlassFish, Grizzly -- can't connect

I am trying to get started with WebSockets, and trying to write a simple application to send messages back and forth via a websoket.
However, it looks like the socket that I am trying to create never gets connected. Why can that be?
Below is the code of my WebSockets class. When .onConnect() is called, it logs:
I am socket, I was connected. Am i connected? - false
Update: in JavaScript, where I create the socket in question, the readyState is 1, which means "socket open, communication is possble".
import a.b.Misc; //writes logs.
import com.sun.grizzly.websockets.BaseServerWebSocket;
import com.sun.grizzly.websockets.DataFrame;
import com.sun.grizzly.websockets.WebSocketListener;
public class ChatWebSocket_v2 extends BaseServerWebSocket {
private String user;
public ChatWebSocket_v2(WebSocketListener... listeners) {
super(listeners);
}
public String getUser() {
if (user == null) {
Misc.print("User is null in ChatWebSocket");
throw new NullPointerException("+=The user is null in chat web socket");
}
return user;
}
public void setUser(String user) {
Misc.print("Just set user: " + user);
this.user = user;
}
#Override
public void onMessage(String message) {
Misc.print(message +"\n");
}
#Override
public void onMessage(byte[] message) {
Misc.print(new String(message) +" << Bytes\n");
}
#Override
public void onConnect() {
Misc.print("I am socket, i was connected. Am i connected? - " + this.isConnected());
}
#Override
public void onClose(DataFrame df) {
Misc.print("I am socket, i was closed");
}
}
If you're just trying to make a connection somewhere, you might want to try this instead. There is a live working demo and you can download the javascript code and play with it yourself. Note that the javascript code only works if you have it installed on a server (due to browser security because it's 'fancy'.) There is also a step by step browser-based client tutorial in the works that I will post as soon as it's ready. Most proxy servers haven't been upgraded to handle websockets so they will screw up connection request and most people won't be able to connect to websocket servers from work. Firefox 7 (release) or Google Chrome 14 or later support the latest version of the websocket protocol that the demo server runs.
If you want to try to get the grizzly demo working, you might have some debugging to do and maybe I'll help with that. Note that in comments below the article, other people said they couldn't get it working either and I haven't found any follow up. At this point it seems no better than the echo app above even if we do get it running and is possibly overly complicated and underly documented if you're just trying to get started. But if you want to try to get it running, you should 'git' the latest version of the code here, which was at least committed recently and may be fixed.
Then make sure that app.url in the application javascript file is set to your installation directory. His is hard-coded as:
url: 'ws://localhost:8080/grizzly-websockets-chat/chat',
If you're using Firefox 7, the javascript needs to be modified to use the Moz prefix, for example:
if (typeof MozWebSocket != "undefined") { // window.MozWebSocket or "MozWebSocket" in window
ok
} else if (window.WebSocket) { // he uses if ("WebSocket" in window)
ok
} else {
do your print "browser doesn't support websockets"
}
.... then if the browser supports websockets
websocket = new WebSocket(app.url); or
websocket = new MozWebSocket(app.url);
// depending on which it is.
The HLL websocket server demo code has this all sorted out.
(another) UPDATE: As I work through grizzly myself, I found on the Quick Start in the glassfish admin console, there's a hello sample that's pretty easy to set up and run. You'll find instructions there. The sample directory also contains a war file named: websocket-mozilla; so I guess its supposed to use websockets. Someone who's familiar with jsp should review the source code. All I can see is that it's using an http session. No mention of a websocket at all. It's a lot like the hello sample.

Determine that application is running under application server

Some code may be reused in various environments including Java EE Application server. Sometimes it is nice to know whether the code is running under application server and which application server is it.
I prefer to do it by checking some system property typical for the application server.
For example it may be
jboss.server.name for JBoss
catalina.base for Tomcat
Does somebody know appropriate property name for other servers?
Weblogic, Websphere, Oracle IAS, others?
It is very easy to check if you have the specific application server installed. Just add line
System.getProperties() to any JSP, Servlet, EJB and print the result.
I can do it myself but it will take a lot of time to install server and make it working.
I have read this discussion: How to determine type of Application Server an application is running on?
But I prefer to use system property. It is easier and absolutely portable solution. The code does not depend on any other API like Servlet, EJBContext or JMX.
JBoss AS sets a lot of diffrent system properties:
jboss.home.dir
jboss.server.name
You can check other properties using for example VisualVM or other tools.
I don't know other servers but I think you can find some kind of properties for each of them.
This is not a 'standard' way but what I did was to try to load a Class of the AppServer.
For WAS:
try{
Class cl = Thread.getContextClassLoader().loadClass("com.ibm.websphere.runtime.ServerName");
// found
}
// not Found
catch(Throwable)
{
}
// For Tomcat: "org.apache.catalina.xxx"
Etc.
Let me know what you think
//for Tomcat
try {
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("Catalina", "type", "Server");
StandardServer server = (StandardServer) mBeanServer.getAttribute(name,"managedResource");
if (server != null) {
//its a TOMCAT application server
}
} catch (Exception e) {
//its not a TOMCAT Application server
}
//for wildfly
try {
ObjectName http = new ObjectName("jboss.as:socket-binding-group=standard-sockets,socket- binding=http");
String jbossHttpAddress = (String) mBeanServer.getAttribute(http, "boundAddress");
int jbossHttpPort = (Integer) mBeanServer.getAttribute(http, "boundPort");
String url = jbossHttpAddress + ":" + jbossHttpPort;
if(jbossHttpAddress != null){
//its a JBOSS/WILDFLY Application server
}
} catch (Exception e) {
//its not a JBOSS/WILDFLY Application server
}

Categories

Resources