Cannot reach the web service from an other pc - java

I simply publish a web service with the following code in Java:
String dbAccessAddress = "http://127.0.0.1:8024/SmartService";
try {
if (ep != null && ep.isPublished() == false) {
ep = Endpoint.publish(dbAccessAddress, new DbAccess());
logger.info("DbAccess started: " + dbAccessAddress);
}
} catch (Exception ex) {
logger.error("DbAccess failed(" + dbAccessAddress + ")", ex, false);
}
This service works perfectly on localhost but when I try to reach the service from an other computer within the local network, i can not connect to it. Timeout occurs.
I also tried with the browser by writing the service wsdl URL but it can not reach the service. Only works locally.
What is the problem?

The address 127.0.0.1 is reserved for the localhost, this means only local connections are possible. You will have to use a ip address from your local network or simply bind to all interfaces, if you want to your service to be accessible in the local network.

Related

Cannot Get DNS Requests via Java Code in Windows 10 and DLINK DIR-615 router

So I am working on a software that will monitor(and may alter by acting as a Forrowder) all the DNS requests made by my router.
What I did?
So for first I wrote a Java code that can listens to a specific port and prints all the requests to the console[For now I just want to test with the requests].
The code is:
import java.net.*;
import java.io.*;
public class PortLogger{
public static void main(String[] args) {
LoggerServer loggerServer = new LoggerServer(53);
loggerServer.start();
}
}
class LoggerServer extends Thread{
private int port;
public LoggerServer(int port){
this.port = port;
}
#Override
public void run(){
try{
int id = 1;
ServerSocket server = new ServerSocket(port);
System.out.println("Server Listening at port " + port);
Socket client;
while(true){
client = server.accept();
ClientHandler clientHandler = new ClientHandler(client, id++);
clientHandler.start();
}
}catch(Exception ex){
System.out.println("Exception at Server : 1 :: EX = " + ex);
}
}
}
class ClientHandler extends Thread{
private Socket client;
private int id;
public ClientHandler(Socket client, int id){
this.client = client;
this.id = id;
}
#Override
public void run(){
try {
String data = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
while(true){
data = reader.readLine();
if(data.length() > 0){
System.out.println("Client : " + id + " :: " + data);
}
}
}catch(Exception ex){
System.out.println("Exception at Client : " + id + " :: EX = " + ex);
}
}
}
The sole propose of this code for now is to Show me all the requests made to the server.
I know that I also have to change the DNS Server in my router for this.
So, for that I first tried by going to internet setup and put the local IP of my computer as DNS server.
But it was showing :
DNS IP and LAN IP must be on different networks!
But I found another way to do it.
It is as follows:
I went to the setup wizard of the router and the set the DNS Server to the same IP.
Surprisingly this worked!
[I have no idea whether this is a bug in the D-Link Firmware or not.
I have also added an exception to allow all request both inbound and outbound to port 53.
What is the problem?
So now the problem is that even after successfully changing the DNS to my servers. There seemed to be no requests at all to the console. I tried a lot but nothing.
I checked that the program was working fine by voluntarily sending request to it using telnet?
Now am I doing anything wrong or there is some bug with the router(its is a old one).
NOTE: The black lines on the images are just to hide my public IP address nothing special.
EDIT: I tried a few more times then found that websites were not opening when I changed the DNS in my router but still nothing in the console!
While it is difficult to give you a complete answer why your application doesn't work I can suggest some ways to investigate:
Port 53 is a privileged port. This means on Linux binding to that port requires root privileges and the application will throw an exception due to 'permission denied' if executed as a 'normal' user. As you are using Windows I don't know what it does if you try to bind as a 'normal' user, or you might be executing as an Admin user (or whatever the equivalent of 'root' is in Windows) and you don't know it. It might even just silently fail i.e. appear to bind when in fact it hasn't and no data is passed through you your application. As an aside, defaulting to 'root' as the default execution user in Linux is not the norm because it's insecure and most Linux distributions if not all do not allow this by default i.e. you can have this but you have to tell the distribution this is what you intend during installation. I'll let you come to your own conclusions what stance Windows takes for making users 'admin'...
In a scenario such as this if it were me I would immediately go to some networking tools to see what is happening. On Linux this is tcpdump or Wireshark. You can also get Wireshark for Windows as it's a GUI application. This will let you monitor and filter network traffic and so will be independent of your application. You can filter by source or destination address and/or port number.
I would leave the DNS setting alone in the router and change the DNS settings in one machine first, call it the test client, and set its DNS address to the machine where your application is running. Using tcpdump or Wireshark you can then make requests on your test_client e.g. browser requests and see the resulting network traffic.
You never mentioned if after changing your router's DNS settings all browser requests from clients fail. This is what I would expect to see if your router can no longer get a name resolution. However there maybe some DNS caching going on in your clients so you may appear to get successful DNS requests on your test_client. Again look at network traffic or use a Linux client which will provide you with much better networking tools.

How to determine if tests are running local or on the remote server

According to this tutorial, I am able to upload files on the website while running my tests locally and on the remote server.
As in the tutorial is:
For those of you doing this locally, all you need to do is use the
sendKeys command to type the local path of the file in any file field.
This works like a charm in all drivers. When moving this test to a
remote server (such as, for example, our Selenium 2 Cloud), all you
need to do is use the setFileDetector method to let WebDriver know
that you’re uploading files from your local computer to a remote
server instead of just typing a path.
on the remote server I have to use:
driver.setFileDetector(new LocalFileDetector());
...
upload.sendKeys("/Path/to/image.jpg");
and local just:
upload.sendKeys("/Path/to/image.jpg");
And this all works fine. Only the problem is, that there is no information how to determine if my tests are running local or on the remote server.
I have tried to determine instance of the webDriver:
WebDriver proxiedWebDriver = ((WebDriverFacade) getDriver()).getProxiedDriver();
if (proxiedWebDriver instanceof RemoteWebDriver) {
((RemoteWebDriver)proxiedWebDriver).setFileDetector(new LocalFileDetector());
}
but it seems like both(local and remote) cases are using RemoteWebDriver while running, because in every case I'm passing if condition.
How can I determine if my tests are running local or remote?
To get the address of the remote server you can use HttpCommandExecutor like this:
HttpCommandExecutor ce = (HttpCommandExecutor) ((RemoteWebDriver)driver).getCommandExecutor();
String remoteAddress = ce.getAddressOfRemoteServer().toString();
String localAddress = null;
try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress("google.com", 80));
localAddress = socket.getLocalAddress().getHostAddress();
} catch (IOException e) {
e.printStackTrace();
}
if (remoteAddress.contains("localhost") || remoteAddress.contains(localAddress)) System.out.println("Local machine");
else System.out.println("Remote machine");
The above code gets the Remote Server address (HUB) and compares it with your public IP address. It should give you the information if you are running local or remote server

Java RMI call slow first time

I'm working on a personal project for school where I have to user RMI to communicate between server and client.
Project info
The goal of my project is to retrieve stock info (from NYSE) for each day on the server at a specific time (after NYSE is closed). Each stock object is saved in a database. The information is retrieved over http and has nothing to do with RMI.
For the client it is also possible to fetch the stocks. When a user wants to fetch the stock object for the current day, it is directly fetched from the 3th party service. When a user, for example, wants to fetch Google's stock from last month, it is requested on the server over RMI. The server will the look for the stock object in the database and retrieve a Stock object and send it to the client.
Problem
When I start the client application, I have to login. The client will create a User object containing the username and password.
When I press the login button, it will take around 2 minutes before the main screen will be shown.
Below the source code where I setup the RMI connection.
Server (main.java)
public static void main(String[] args) throws UnknownHostException {
InetAddress IP= InetAddress.getLocalHost();
System.out.println("IP of my system is := "+IP.getHostAddress());
if(args.length == 1 && args[0].toLowerCase().equals("local")) {
System.out.println("Running on localhost");
System.setProperty("java.rmi.server.hostname", IP.getHostAddress());
} else {
System.out.println("rmi hostname is set to 37.97.223.70");
System.setProperty("java.rmi.server.hostname", "37.97.223.70");
}
try {
Registry reg = LocateRegistry.createRegistry(1099);
StockAppServer server = StockAppServer.getInstance();
reg.rebind("StockApp", server);
System.out.println("StockApp bound for StockAppServer object.");
} catch (RemoteException e) {
e.printStackTrace();
}
}
Based on the arguments that are passed to the application when it starts, I set the RMI hostname to my current IP address, or to the remote server address. The remote server address is a static IP, so this won't change.
Server (StockAppServer.java)
This class implements the interfaces that is used by the client to call methods on the server. So this class extends UnicastRemoteObject. When I start the server, registerStockTask() will be called. This method will fetch the ticker symbols (What are ticker symbols?) and then schedule a task to fetch all stock objects at a specific time.
private static StockAppServer _instance;
private List<User> loggedInUsers;
private List<Group> activeGroups;
private List<Notification> registeredNotifications;
private StockAppServer() throws IOException {
_instance = this;
this.loggedInUsers = new ArrayList<>();
this.activeGroups = new ArrayList<>();
this.registeredNotifications = new ArrayList<>();
this.registerStockTask();
clearActiveGroups();
checkForCompletedNotifications();
// Start the restful framework to allow incoming connections from the NodeJS server to manage new notification
Router.getInstance();
}
public static StockAppServer getInstance() {
try{
return _instance == null ? new StockAppServer() : _instance;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Client (main.java)
public static void main(String[] arguments) throws Exception {
args = arguments;
Application.launch();
}
#Override
public void start(Stage primaryStage) throws Exception {
InetAddress IP= InetAddress.getLocalHost();
System.out.println("IP of my system is := "+IP.getHostAddress());
if(args.length == 1 && args[0].toLowerCase().equals("local")) {
// Program started with local command, expect that server is running on local host
reg = LocateRegistry.getRegistry(IP.getHostAddress(), 1099);
System.out.println("Attempting to connect to RMI server over 127.0.0.1");
} else {
// Program started without additional commands. Except that "the server" is available;
reg = LocateRegistry.getRegistry("37.97.223.70", 1099);
System.out.println("Attempting to connect to RMI server over 37.97.223.70");
}
try {
StockApp.getInstance().setServerInterfaces((IStockSend) reg.lookup("StockApp"), (IUserHandling) reg.lookup("StockApp"));
} catch(RemoteException e) {
AlertMessage.showException("Unable to connect to server.", e);
} catch (NotBoundException e) {
AlertMessage.showException("No server has been found with the name \"StockApp\" on the remote host.\nPlease try again later", e);
}
LoginController.showMenu();
//FileNotFoundException e = new FileNotFoundException("Couldn't find file blabla.txt");
//AlertMessage.showException("Something went wrong. Please try again later.", e);
}
How I tried to solve my problem
When I test my applications local, there is no problem. The login method will be finished within a few milliseconds and I will be represented the main screen.
I started by turning of my firewall on my macbook. No result, login method still takes around 2 seconds.
I turned off the firewall om my Ubuntu server. No result, both firewalls on server and macbook are turned off. Login method still takes around 2 seconds.
On the server runs (thanks to jenkins) another (unrelated) program. This program uses sockets instead of RMI. When this program is not running, the login method still takes around 2 minutes.
In StockAppServer.java, I called the following method:
super(1099);
This has the same outcome as the above steps I took.
I don't know what else I can try to solve my problem.
I tried to give as much code as possible for the RMI part. I you need any other source code, just ask and I can update this question. Also, the source code is available via github: https://github.com/juleskreutzer/GSO-Maatwerk. Make sure to run the program with -remote param.
Update 1 (9-1-2017)
As yanys requested in the comments, I should run the following command:
dscacheutil -q host -a name localhost
this returns the following output:
Mac:
name: localhost
ip_address: 127.0.0.1
Ubuntu:
dscacheutil: command not found
Update 2 (9-1-2017)
I checked with the provider of my VPS where I run the java server on. On their side everything should be OK. According to them, it shouldn't be a dns problem. After some research, I found out that RMI uses both DNS and reverse DNS. It this case, reverse DNS was the issue. Please see my answer on how I solved my problem.
As EJP pointed out in the comments on the question, it was an DNS problem.
I contacted the support of my hosting provider to see if I had some wrong settings. They helped me a lot in solving this problem.
First we tested the speed of my VPS, this is around 1000mbit download and upload speed. After we checked this, they said there was nothing wrong on their side.
After doing some research, I found out that RMI uses both DNS and Reverse DNS. The problem was that I didn't setup the reverse DNS on my server. I already have a domain name to use for reverse DNS.
I than did the following:
Create a A-record on my website that points to the IP address of the server. I named it vps.mydomain.com
Add the reverse DNS in the control panel of my server
Change the hostname of my server to vps.mydomain.com*
*My server runs Ubuntu 16.04, on ubuntu machines with systemd, you can use the command
sudo hostnamectl set-hostname new-name
to change the hostname

isLocalHost(String hostNameOrIpAddress) in Java

I want to write a ContainerRequestFilter for a Jersey webapp that will filter out all remote calls.
So only requests from same machine (where webapp is running) are allowed.
I get a context object of type ContainerRequestContext where I get the host name via ctx.getUriInfo().getRequestUri().getHost().
How can I check if this host name (in form of IPv4, IPv6 or domain name) is an address of the local machine?
I'd go with something like this, once you stripped the host name from the request. It should work with inputs like localhost and such as well.
public boolean isLocalAddress(String domain) {
try {
InetAddress address = InetAddress.getByName(domain);
return address.isAnyLocalAddress()
|| address.isLoopbackAddress()
|| NetworkInterface.getByInetAddress(address) != null;
} catch (UnknownHostException | SocketException e) {
// ignore
}
return false;
}
But please keep in mind, as it's not straightforward to determine if a request is originated from a local client, and there is also performance implications, I'd suggest to bind the container's listen address only to a locally accessible interface (127.0.0.1, ::1), or implement some sort of authentication. This approach - where you trying to determine this info from the request is also insecure.

Obtain information about jboss

How would one find out the jboss port programatically within application/war that is deployed on that jboss server? Using Java
It is a web service running, we don't have any user interface
I am assuming you want the HTTP port.
JBoss publishes a Tomcat connector MBean for each web listener. The naming convention of the mbeans' ObjectNames is:
Domain: jboss.web
Attributes:
address: The binding address
port: The listening port
type: connector
The trick is, without making any assumptions about the bind address or port (the bind address could be 127.0.0.1, or 0.0.0.0 or a host name), finding the correct MBean. To do this, you can use a JMX Query that specifies:
The known domain name: jboss.web
The known type: connector
A wild card for the address: *****
A wild card for the port: *****
An attribute value expression that specifies you are looking for the HTTP/1.1 protocol port (as opposed to the AJP port): Query.match(Query.attr("protocol"), Query.value("HTTP/1.1"))
Once you have an MBeanServerConnection to the JBoss MBeanServer, this statement will return the correct port:
String port = server.queryNames(
new ObjectName("jboss.web:type=Connector,address=*,port=*"),
Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")))
.iterator().next().getKeyProperty("port");
If you are attempting to determine the port from code running inside the JBoss JVM, acquiring the MBeanServerConnection is trivial since you can make a static call to org.jboss.mx.util.MBeanServerLocator.locateJBoss().
Here is an example of a simple JSP to print the HTTP port number:
<%#page contentType="text/html" import="java.util.*,org.jboss.mx.util.*,javax.management.*" %>
<html><head><title>JBoss Web Server Port</title></head><body>
<%
try {
MBeanServerConnection server = MBeanServerLocator.locateJBoss();
String port = server.queryNames(
new ObjectName("jboss.web:type=Connector,address=*,port=*"),
Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")))
.iterator().next().getKeyProperty("port");
out.println("<p>Port:" + port + "</p>");
} catch (Exception e) {
e.printStackTrace(System.err);
}
%></body></html>
If you need to acquire this remotely, you need to use the JBoss client RMIAdaptor. The reference provided by Nayan Wadekar is a good example of how to do this.
If your JBoss server has a org.jboss.mx.remoting.service.JMXConnectorServerService deployed or you are running JBoss using the platform MBeanServer, you can also use the native JMX remoting. Here's a Groovy example of that:
import javax.management.*;
import javax.management.remote.*;
conn = null;
try {
url = new JMXServiceURL("service:jmx:rmi://njw810/jndi/rmi://njw810:1090/jmxconnector");
conn = JMXConnectorFactory.connect(url);
server = conn.getMBeanServerConnection();
objectName = new ObjectName("jboss.web:type=Connector,address=*,port=*"); // HTTP/1.1
println server.queryNames(objectName, Query.match(Query.attr("protocol"), Query.value("HTTP/1.1"))).iterator().next().getKeyProperty("port");
} finally {
try { conn.close(); println "Connection Closed"; } catch (Exception e) {}
}

Categories