I have trouble connecting to a JMX Service URL having an IPv6 address through jconsole. I tried
service:jmx:rmi:///jndi/rmi://[fd02:c9e3:a6c0:4306:0:0:0:27]:5500/jmx
and I get
Connection did not succeed to ..
As for some background,
I am running the jconsole from my Windows 7 box and connect to the jmx server on linux.
the jmx server is a dual stacked Redhat linux box and I am able to connect through the jconsole using the IPv4 address.
Not sure if this is relevant, the host I am trying to connect to has 2 network interfaces and one of them is used for management purposes only.
OK, I added the below condition to wrap the server host address in square brackets.
if ( aHost instanceof Inet4Address ) {
this.hostAddress = aHost.getHostAddress();
}
else if ( aHost instanceof Inet6Address ) {
this.hostAddress = "[" + aHost.getHostAddress() + "]";
}
else {
throw someException();
}
.............some other stuff.................
registry = LocateRegistry.getRegistry( this.hostAddress, ... );
In fact, the host address is specified as a name value pair in a properties file. Hence I could have done like below but it didn't work for other reasons.
.properties file
hostName = [fd02:c9e3:a6c0:4306:0:0:0:27]
Related
So I'm currently hosting a service which utilizes Oracle's Interoperable Naming Service (INS) according to tutorial listed below. This service deploys a servant on one machine and registers it with the INS, we'll call this machine A.
Properties properties = System.getProperties( );
properties.put( "com.sun.CORBA.POA.ORBPersistentServerPort",
Integer.toString(1060);
ORB orb = ORB.init( args, properties );
ServiceImpl servant = new ServiceImpl( );
POA rootPOA = POAHelper.narrow( orb.resolve_initial_references( "RootPOA" ));
rootPOA.the_POAManager().activate();
rootPOA.activate_object( servant );
((com.sun.corba.se.impl.orb.ORBImpl) orb).
register_initial_reference("PingService",
rootPOA.servant_to_reference(servant));
System.out.println( "INS Server is Ready...");
orb.run();
https://docs.oracle.com/javase/8/docs/technotes/guides/idl/INStutorial.html
When I use a client on the same machine according to the tutorial, everything works just fine. However, when I attempt to do a lookup over LAN, when the INS Server is hosted on Machine A and the client is on Machine B I get an error when narrowing the reference.
String[] argv = new String[]{"-ORBInitRef",
"PingService=corbaloc:iiop:1.2#"
+ ORBIP + ":" + ORBPort + "/PingService"};
ORB orb = ORB.init( argv, null );
org.omg.CORBA.Object object = orb.resolve_initial_references(
"PingService" );
Service fileRef = ServiceHelper.narrow( object ); // <----- error
I set the server as 192.168.0.XXX and it is accessible by machine B, and get error somewhere along these lines. AFAIK the connection is being made to the naming service and the object located in the service, but when it tries to look up the object it uses an incorrect interface on machine A. Then the error is returned to machine B.
com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl <init>
WARNING "IOP00410201: (COMM_FAILURE)Connection failure: socketType: IIOP_CLEAR_TEXT; hostname: 127.0.1.1; port:1060"
org.omg.CORBA.COMM_FAILURE: vmcid: SUN minor code: 201 completed: No
connectFailure
So my question is, is there a way to specify exactly which interface the naming service can use when it does the lookup? I tried on both a Windows host and a Linux host. The linux host used an iface which wasn't listed but was in the /etc/hosts file and the Windows host used an IP of the last interface listed in ipconfig (a 172.xx.. IP). Tested both on vbox with bridge enabled. Is there an effective way to specify the network interface? My requirement is for the server and client to exist independently on the same LAN. Setting the ORBInitialHost property on the server didn't do anything.
the problem here is that the client machine is searching for the server locally this why it's writing Connection failure: socketType: IIOP_CLEAR_TEXT; hostname: 127.0.1.1; port:1060
So in the client code instead of initializing the properties like this :
String[] argv = new String[]{"-ORBInitRef", "PingService=corbaloc:iiop:1.2#"
+ ORBIP + ":" + ORBPort + "/PingService"};
ORB orb = ORB.init( argv, null );
try initializing it like this :
Properties props = new Properties();
props.put("org.omg.CORBA.ORBInitialHost",ORBIP);
props.put("org.omg.CORBA.ORBInitialPort","1060");
ORB orb = ORB.init(args,props);
in the ORBIP variable put the server IP address in the LAN .
you tried the ORBInitialHost property on the server but it doesn't do anything because he's running locally . this property must be used in the client side to know the exact hosting point of the server.
Once again i require some small help on how i can make use of Inet6Address on java.
As i develop a application on getting IPv4 address but now i wanna extend it to IPv6. And it seem that i cant get a IPv6 address and it keep get IPv4 address.
ANd i try to import java.net.Inet6Address;
With the existing code that i have which is show below.
public SocketAddress getInetAddress(){
return channel.getRemote();
}
The channel is using the netty project.
How can i do with Inet6Address?
As i found on this web
http://docs.oracle.com/javase/1.4.2/docs/api/java/net/Inet6Address.html
public InetSocketAddress getInetAddress(){
Inet6Address ipv6 = (Inet6Address)channel.getRemoteAddress.**getAddress();**
return channel.getRemote();
}
Can i also ask if the .getAddress() cant be use, Can anyone help me on this issues?
Like do i need to download a jar file to work on this?
The version of java i am using is java 6.
From Swift
if you are ok - try to use
Java-ipv6
what is the type of your channel? never used 'netty', but in sun's nio world, assuming sa is an instance of SocketAddress, just use sa.getAddress(). if sa is representing a socket on IPv4 address, you will get an instance of Inet4Address, or a Inet6Address when it is a socket on IPv6 address.
add some IPv6 bind code:
InetAddress[] addresses = InetAddress.getAllByName("localhost");
Inet6Address add6 = null;
for(InetAddress add : addresses) {
if (add instanceof Inet6Address) {
add6 = add;
break;
}
}
if (add6==null)
throw new RuntimeException("no IPv6 local address found!");
InetSocketAddress sa=new InetSocketAddress(add6, port);
...
I'm having the following problem:
When I try to createTcpServer with my external IP address (the PC's IP and not my local IP = the one we see as an output after running ipconfig in cmd.exe) the following error occurs:
Error with Server: Exception opening port "9092" (port may be in use), cause: "java.net.BindException: Cannot assign requested address: JVM_Bind" [90061-169]
However, the port is not in use. I've checked that using netstat -a -n .
I have enabled my external IP and I have disabled the firewall from the router. My external IP can now be pinged.
Please help me.
Update: Here is my code to start the tcp server.
package businessApp;
import org.h2.tools.Server; //imports the server utility
public class startTcpServerForH2 {
Server server; //the server's instance variable
private static final String SERVER_IP = "192.168.1.101"; //fixed IP of the server
private static final String SERVER_PORT = "9092"; //fixed port the server is listening to
public void tcpServer() { //method responsible to create the tcp server
optionPane optPane = new optionPane(); //option pane for debugging purposes, shows the server's status
try { //catches any server related errors, if the connection is broken etc.
//server uses the IP and port defined earlier, allows other computers in the LAN to connect and implements the secure socket layer (SSL) feature
server = Server.createTcpServer( //create tcp server
new String[] { "-tcpPort" , SERVER_PORT , "-tcpAllowOthers" , "-tcpSSL" }).start();
System.out.println(server.getStatus()); //prints out the server's status
optPane.checkServerStatus(server.getStatus()); //prints out the server's status on the option pane as well
} catch(Exception ex){
System.out.println("Error with Server: " + ex.getMessage());
}
}
public static void main(String[] args){
startTcpServerForH2 tcpServ = new startTcpServerForH2(); //create a new server object
tcpServ.tcpServer(); //starts the tcp server
}
}
Second Update: here is the h2Connection code.
package businessApp;
import java.sql.*; //imports sql features
//Class responsible for connection with H2 Database Engine
public class h2Connection {
Connection conn; //connection variable
DatabaseMetaData dbmd; /** Metadata variable which include methods such as the following:
* 1) Database Product Name
* 2) Database Product Version
* 3) URL where the database files are located (in TCP mode)
*/
Statement stm; //statements variable
ResultSet rst; //result sets variable
private static final String SERVER_IP = "..."; //here I enter my WAN_IP
private static final String SERVER_PORT = "9092";
public Connection connectionToH2(Connection connt) {
optionPane optPane = new optionPane(); //create new option pane object
String outputConn = null; //declare & initialize string which will hold important messages
try {
Class.forName("org.h2.Driver"); //Driver's name
/** The String URL is pertained of the following:
* 1) jdbc which java implements so that it can take advantage of the SQL features
* 2) Which Database Engine will be used
* 3) URL where the files will be stored (as this is a TCP connection)
* 4) Schema: businessApp
* 5) Auto server is true means that other computers can connect with the same databse at any time
* 6) Port number of the server is also defined
*/
String url = "jdbc:h2:tcp://" + SERVER_IP + ":" + SERVER_PORT + "/C:/Databases/businessApp;IFEXISTS=TRUE";
System.out.println(url); //prints out the url the database files are located as well as the h2 features used (SSL)
connt = DriverManager.getConnection(url, "sa", ""); //Driver Manager defines the username & password of the database
System.out.println(connt.getCatalog()); //prints out the database schema
optPane.checkServerStatus(connt.getCatalog()); //prints out the database schema on the option pane as well
connt.setAutoCommit(false); //set AutoCommit to false to control commit actions manually
//outputs H2 version and the URL of the database files which H2 is reading from, for confirmation
dbmd = connt.getMetaData(); //get MetaData to confirm connection
outputConn = "Connection to "+dbmd.getDatabaseProductName()+" "+
dbmd.getDatabaseProductVersion()+ " with the URL " + dbmd.getURL()+" was successful.\n";
System.out.println(outputConn); //outputs the message on the system (NetBeans compiler)
optPane.checkH2Connection(outputConn); //outputs the message on top of the frame
} catch (ClassNotFoundException ex){ //In case there is an error for creating the class for the Driver to be used
System.out.println("Error creating class: " + ex.getMessage());
} catch(SQLException ex){ //Any error associated with the Database Engine
System.out.println("SQL error: " + ex.getMessage());
optPane.checkServerStatus("SQL error: " + ex.getMessage());
}
return connt; //As the method is not void, a connection variable must be returned
}
}
When I want to connect to the h2 database, I make a new h2Connection object and use it to connect. I have followed the H2 manual word by word. What more do you need?
As suggested in the command line help shown below, Protection against Remote Access advises the following:
By default this database does not allow connections from other machines when starting the H2 Console, the TCP server, or the PG server. Remote access can be enabled using the command line options -webAllowOthers, -tcpAllowOthers, -pgAllowOthers.
See the documentation for important caveats regarding these options.
Addendum: Works for me, as long as I restart the Server after opening the firewall; you don't need the setProperty() line at all; the LAN IP to which your WAN_IP forwards port 9092 should be your host IP address; then you can open a shell via your WAN_IP:
java -cp h2.jar org.h2.tools.Shell -url
jdbc:h2:tcp://WAN_IP/~/path/to/test;ifexists=true"
Command line help:
$ java -cp .:/opt/h2/bin/h2.jar org.h2.tools.Shell -?
Interactive command line tool to access a database using JDBC.
Usage: java org.h2.tools.Shell
Options are case sensitive. Supported options are:
[-help] or [-?] Print the list of options
[-url ""] The database URL (jdbc:h2:...)
[-user ] The user name
[-password ] The password
[-driver ] The JDBC driver class to use (not required in most cases)
[-sql ""] Execute the SQL statements and exit
[-properties ""] Load the server properties from this directory
If special characters don't work as expected, you may need to use
-Dfile.encoding=UTF-8 (Mac OS X) or CP850 (Windows).
See also http://h2database.com/javadoc/org/h2/tools/Shell.html
$ java -cp /opt/h2/bin/h2.jar org.h2.tools.Server -?
Starts the H2 Console (web-) server, TCP, and PG server.
Usage: java org.h2.tools.Server
When running without options, -tcp, -web, -browser and -pg are started.
Options are case sensitive. Supported options are:
[-help] or [-?] Print the list of options
[-web] Start the web server with the H2 Console
[-webAllowOthers] Allow other computers to connect - see below
[-webDaemon] Use a daemon thread
[-webPort ] The port (default: 8082)
[-webSSL] Use encrypted (HTTPS) connections
[-browser] Start a browser connecting to the web server
[-tcp] Start the TCP server
[-tcpAllowOthers] Allow other computers to connect - see below
[-tcpDaemon] Use a daemon thread
[-tcpPort ] The port (default: 9092)
[-tcpSSL] Use encrypted (SSL) connections
[-tcpPassword ] The password for shutting down a TCP server
[-tcpShutdown ""] Stop the TCP server; example: tcp://localhost
[-tcpShutdownForce] Do not wait until all connections are closed
[-pg] Start the PG server
[-pgAllowOthers] Allow other computers to connect - see below
[-pgDaemon] Use a daemon thread
[-pgPort ] The port (default: 5435)
[-properties ""] Server properties (default: ~, disable: null)
[-baseDir ] The base directory for H2 databases (all servers)
[-ifExists] Only existing databases may be opened (all servers)
[-trace] Print additional trace information (all servers)
The options -xAllowOthers are potentially risky.
For details, see Advanced Topics / Protection against Remote Access.
See also http://h2database.com/javadoc/org/h2/tools/Server.html
8 months ago I used this stack overflow post to automatically use a proxy server in a Java project. It worked beautifully.
Here is the code I came up with at the time:
System.setProperty("java.net.useSystemProxies", "true");
List<Proxy> proxyServers = null;
try {
proxyServers = ProxySelector.getDefault().select(new URI("http://www.twitter.com"));
} catch (URISyntaxException e) {
System.out.println("Error using system proxy");
}
if (proxyServers != null) {
for (Iterator<Proxy> iter = proxyServers.iterator(); iter.hasNext();) {
Proxy proxy = iter.next();
System.out.println("Found Proxy: " + proxy);
InetSocketAddress addr = (InetSocketAddress) proxy.address();
if (addr == null) {
System.out.println("No Proxy");
} else {
System.setProperty("http.proxyHost", addr.getHostName());
System.setProperty("http.proxyPort", Integer.toString(addr.getPort()));
System.out.println("proxy hostname : " + addr.getHostName());
System.out.println("proxy port : " + addr.getPort());
}
}
}
I tried adding this exact same code to another project recently and I get different results. I have my computer setup to use a test proxy server and ran both projects to compare the results. If I run the project from 8 months ago the following is printed out:
Found Proxy: HTTP # 192.168.1.100:8000
proxy hostname : 192.168.1.100
proxy port : 8000
If I run my current project on the same machine with the same Proxy server set up, the following is printed out.
Found Proxy: DIRECT
No Proxy
The only proxy found is a "Direct" and proxy.address() is null.
What would cause this to find the proxy settings in one case but not the other?
Edit:
I fixed this, by moving the code sooner in the startup process, but I don't know why this fixed it.
Probably due to this sentence in http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html#Proxies
java.net.useSystemProxies (default: false) On recent Windows systems
and on Gnome 2.x systems it is possible to tell the java.net stack,
setting this property to true, to use the system proxy settings
(both these systems let you set proxies globally through their user
interface). Note that this property is checked only once at startup.
You can guarantee it working if you put the property in the java command: java -Djava.net.useSystemProxies=true yourclass
Regards
If you will use the code along with secure page, it will not consider the proxy hence it would display Direct and No Proxy.
Try the below code:
proxyServers = ProxySelector.getDefault().select(new URI("http://www.twitter.com"));
proxyServers = ProxySelector.getDefault().select(new URI("https://www.twitter.com"));
you will get the difference.
I have a Android application which consumes a webservice on a local network. There's a config screen where the user inform the server IP address, which is running Apache Tomcat.
I'm looking for a way to auto-detect the server based on the current connected wi-fi network.
i.e: The smartphone's IP is 10.1.1.90 and the server IP is 10.1.1.254.
Is there a way to achieve this? I'm thinking on using ping, but I don't know if is a good ideia.
The way I understand it, you need to discover IP of your tomcat server and connect it using your client.
I am assuming , both the server and client is in your control.
One simple way can be to use jGroups Cluster.
You can make your tomcat discoverable
Client can discover it using the name of the cluster you have provided .Refer the JChannel API that Jgroups uses
I simulated it making following server class
public class TomcatServer {
JChannel channel;
private void start() throws Exception {
channel = new JChannel(); // use the default config, udp.xml
channel.connect("TomcatCluster");
}
public static void main(String[] args) throws Exception {
new TomcatServer().start();
}
}
The simulated client class
public class MobileApp extends ReceiverAdapter {
JChannel channel;
private void start() throws Exception {
channel = new JChannel(); // use the default config, udp.xml
channel.setReceiver(this);
channel.connect("TomcatCluster");
channel.close();
}
public static void main(String args[]) throws Exception {
new MobileApp().start();
}
The client will provide you following information
GMS: address=MACHINENAME-47879, cluster=TomcatCluster, physical address=xxxxx:0:xxx:xxxx:xxxx:xxxx:xxx:xxxx:xxxx
** view: [MACHINENAME-31239|1] [MACHINENAME-31239, MACHINENAME-47879]
Where MACHINENAME-47879 is the client machine and port & MACHINENAME-31239 is the tomcat server name and port
Do you want to detect "a tomcat server" or "your tomcat server" ?
I mean, do you have any way to custom your server ? If it's the case, then you could create a very simple test page on your server (say a "Hello" JSP page), which your Android application could look for.
If your Android gets a "Hello" result with a GET request on http://<tomcat_ip>/hello.jsp, then you may assume that the tomcat is online.
If you can't add this test page, then you can test any page which the server is supposed to serve. (even a 404 page which sometimes is not configured well, and shows the tomcat version...)
Tomcat response headers can contain the xpoweredBy field that would advertise Tomcat if enabled. However it is most often disabled due security considerations, and even disabled by default. You however could re-enable it if you need to auto-detect exactly your Tomcat servers. From the other side, indeed, if you can place a web page on your server, you can simply place a marking page with the agreed signature.
If the server IP is unknown, I would propose the following ways to detect the server on the network:
The most straightforward way is to do the breadcast ping (ping -b broadcast_address where breadcast address can be computed here, for instance). All network devices that are configured so would reply, then verify as explained above which one is the server. However pinging broadcast address requires a rooted phone. Also the router may not support.
Your DHCP service (most likely your router) can often be configured to issue always the same IP address for the same MAC address of your server network card.
If the server is a desktop computer or laptop, it could show its address as QR code on display. It is possible for a smartphone to scan the code from the screen, and this is way easier than to enter IP address through the touchscreen. QR code can also include auto-generated password for extra security.
If there is wireless router with the possible login where both server and client are connected, the internal pages of that router often contain the relevant IP addresses. You would need to implement logging into the router and doing some screen scrapping.
I made an Android app which used a local server in the WLAN. I made the terminal (the phone) broadcast it's own IP address, which the server then picked up.
I used MultiCast class on the phone, which added the ip-address of itself to the payload. The server always has a thread in multicast read class that obains the payload of the packet (which is the terminals ip-address). Set the terminal in datagram read state and send the servers ip-address to terminal.
Maybe are better ways, but a great way to get the ip-addresses of unknown terminals in the network.
The way i had resolved this problem is with the use of enumerations.
public String getLocalIpAddress()
{
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
return inetAddress.getHostAddress().toString();
}
}
}
} catch (Exception ex) {
}
return null;
}
}