InetAddress.getLocalHost() fails intermittently - java

I am debugging an application which is failing to bootup with the UnknownHostException exception while it's trying to fetch the hostname. So to reproduce this I setup the machine and manually turned off all the DNS resolutions and ran the same application.
Remove the hostname and localhost entries from /etc/hosts.
Remove the host to IP mapping from my DNS server.
I was able to successfully reproduce and it fails with the same exception.
InetAddress local;
try {
local = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
throw new MalformedURLException("Local host name unknown: " +
e);
}
However in the same machine I wrote a simple Java code to do the same resolution but I don't see the issue when I run my script.
Here is what I am running
import java.net.InetAddress;
import java.net.UnknownHostException;
public class TestDNSResolution {
public static void main(String[] args) throws UnknownHostException {
try {
InetAddress inetAddress;
inetAddress = InetAddress.getLocalHost();
System.out.printf("inetAddress: %s", inetAddress);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
Output:
$ java TestDNSResolution
inetAddress: ****<actualhostname>****/10.1.6.109
I was actually expecting this to throw an exception.
Any pointers on what I am missing or anyways I can make this fail from the Java code?

Related

SSHJ is not able to connect remote Linux server throws UserAuthException: Exhausted available authentication methods

I am trying to run the following Java code using sshj :-
public static void main(String[] args) throws IOException {
SSHClient ssh = new SSHClient();
ssh.loadKnownHosts();
ssh.connect("host", port);
try {
ssh.authPassword("user", "passwd");
ssh.useCompression();
final String src = System.getProperty("user.home") + File.separator + "test_file";
ssh.newSCPFileTransfer().upload(new FileSystemFile(src), "/tmp/");
} finally {
ssh.disconnect();
ssh.close();
}
}
But it is throwing exception -
Exception in thread "main" net.schmizz.sshj.userauth.UserAuthException: Exhausted available authentication methods
at net.schmizz.sshj.SSHClient.auth(SSHClient.java:231)
at net.schmizz.sshj.SSHClient.auth(SSHClient.java:206)
at net.schmizz.sshj.SSHClient.authPassword(SSHClient.java:292)
at net.schmizz.sshj.SSHClient.authPassword(SSHClient.java:262)
at net.schmizz.sshj.SSHClient.authPassword(SSHClient.java:246)
at sample.SCPUpload.main(SCPUpload.java:17)
I can connect the host using same credentials via Putty. I am using JDK "1.8.0_151". What is wrong here?
Typically it means that either your password is wrong, or you're not allowed to connect using the 'password' authentication method.

ssl jdbc connection keystore not found

I wish to use jdbc to connect to a remote mysql database that has recently been secured via ssl. I found a simple example java program to test the connection. The connection fails and complains that the keystore file can not be found. I verify that the keystore is indeed where I say it is in the code. At least I think I do. The test application looks like this:
import java.io.File;
import java.sql.*;
public class TestMySQLSSL {
public static void main (String[] args)
{
Connection con = null;
System.getProperties().setProperty("javax.net.debug","all");
System.getProperties().setProperty("javax.net.ssl.keyStore","c:\\LiferayStuff\\bundles\\liferay-portal-6.0.6\\tomcat-6.0.29\\jrel.6.0_20\\keystore");
System.getProperties().setProperty("javax.net.ssl.keyStorePassword","####");
System.getProperties().setProperty("javax.net.ssl.trustStore","c:\\LiferayStuff\\bundles\\liferay-portal-6.0.6\\tomcat-6.0.29\\jrel.6.0_20\\truststore");
System.getProperties().setProperty("javax.net.ssl.trustStorePassword","####");
try
{
String url = "jdbc:mysql://xxx.xxx.xxx.xxx:3306/isc"+
"?verifyServerCertificate=true"+
"&useSSL=true"+
"&requireSSL=true";
String user = "*******";
String password = "******";
Class dbDriver = Class.forName("com.mysql.jdbc.Driver");
boolean filelives;
filelives = new File("c:/LiferayStuff/bundles/liferay-portal-6.0.6/tomcat-6.0.29/jre1.6.0_20/keystore").exists();
System.out.println("keystore " + filelives);
con = DriverManager.getConnection(url, user, password);
}
catch (Exception ex)
{
ex.printStackTrace();
}
finally
{
if (con != null)
{
try
{
con.close();
}
catch (Exception e){}
}
}
}
}
the first bit of the output I get looks like this:
keystore true
keyStore is : c:/LiferayStuff/bundles/liferay-portal-6.0.6/tomcat-6.0.29/jrel.6.0_20/keystore
keyStore type is : jks
keyStore provider is :
default context init failed:java.security.PrivilegedActionException:java.io.FileNotFoundException: c:\LiferayStuff\bundles\liferay-portal-6.0.6\tomcat-6.0.29\jrel.6.0_20\keystore (The system cannot find the path specified)
com.mysql.jdbc.CommunicationsException: Communications link failure due to underlyingexception:
** BEGIN NESTED EXCEPTION **
com.mysql.jdbc.CommunicationsException
MESSAGE: Communications link failure due to underlying exception:
** BEGIN NESTED EXCEPTION **
The keystore file is there but I suspect there may be something wrong with it. I am running the application on windows. Are there perhaps permission issues with the file? Any help would be appreciated.
Regards,
Dave Semeraro
It turns out the database admin had blocked all but a single ip access to the server. Once my IP was added I was able to get the code above to work. Sorry for wasting everyone's time.

Fatal Exception re WAS AdminClient

I'm attempting to monitor a Websphere 7 ennvironment using MBeans, but running into numerous problems. First, I receive the following exception when using the code posted below:
com.ibm.websphere.management.exception.ConnectorException: Could not
create RMI Connector to connect to host localhost at port 2809
Here is the code generating the exception:
import java.util.Properties;
import com.ibm.websphere.management.AdminClient;
import com.ibm.websphere.management.AdminClientFactory;
public class JustAdminClient {
private AdminClient adminClient;
private void initialize() throws Exception {
try {
// Initialize the AdminClient.
Properties adminProps = new Properties();
adminProps.setProperty("type", AdminClient.CONNECTOR_TYPE_RMI);
adminProps.setProperty(AdminClient.CONNECTOR_SECURITY_ENABLED, "false");
adminProps.setProperty(AdminClient.CONNECTOR_HOST, "localhost");
adminProps.setProperty(AdminClient.CONNECTOR_PORT, "2809");
adminClient = AdminClientFactory.createAdminClient(adminProps);
} catch (Exception ex) {
ex.printStackTrace(System.out);
throw ex;
}
} // end method
/**
* #param args
*/
public static void main(String[] args) {
JustAdminClient adClient = new JustAdminClient();
try {
adClient.initialize();
} catch (Exception e) {
e.printStackTrace();
}
} // end main
} // end class
Second, I'm running WAS standalone with security disabled. Do I need to configure any self-signed certs?
My security.xml shows:
<security:Security xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
xmlns:orb.securityprotocol="http://www.ibm.com/websphere/appserver/schemas/5.0/orb.securityprotocol.xmi"
xmlns:security="http://www.ibm.com/websphere/appserver/schemas/5.0/security.xmi" xmi:id="Security_1"
useLocalSecurityServer="true" useDomainQualifiedUserNames="false"
issuePermissionWarning="true" activeProtocol="BOTH"
enforceJava2Security="false" enforceFineGrainedJCASecurity="false"
appEnabled="true" dynamicallyUpdateSSLConfig="true"
allowBasicAuth="true" activeAuthMechanism="LTPA_1"
activeUserRegistry="LocalOSUserRegistry" enabled="false" cacheTimeout="600"
defaultSSLSettings="SSLConfig_RXCW510MONNode01_1" adminPreferredAuthMech="RSAToken_1">
per the link: http://www-01.ibm.com/support/docview.wss?uid=swg21295051
Note, I can contact port 2809 two ways, via WSadamin and a Java prog containing the following:
private void connect(String host,String port) throws Exception
{
String jndiPath="/WsnAdminNameService#JMXConnector";
JMXServiceURL url = new JMXServiceURL("service:jmx:iiop://"+host+"/jndi/corbaname:iiop:"+host+":"+port+jndiPath);
System.out.println("URL = " + url);
//JMXServiceURL url = new JMXServiceURL("service:jmx:iiop://192.168.0.175:9100/jndi/JMXConnector");
Hashtable h = new Hashtable();
//Specify the user ID and password for the server if security is enabled on server.
//Establish the JMX connection.
System.out.println("Before JMXConnector");
JMXConnector jmxc = JMXConnectorFactory.connect(url, h);
//Get the MBean server connection instance.
System.out.println("Before getMBeanServerConnection");
mbsc = jmxc.getMBeanServerConnection();
System.out.println("Connected to Application Server");
} // end method
Any ideas? I'm lost and apologize for the long thread, but better to see the info upfront.
Resolved my problem using the follwoing example code snippet and notations. Note, pay particular attention to thrown exception and messages re: mssing classes; i.e. focusing on the message "could not create" message may mislead you
requires the following jar files:
%WAS_HOME%\runtimes\com.ibm.jaxws.thinclient_7.0.0.jar
%WAS_HOME%\plugins\com.ibm.ws.runtime.jar
%WAS_HOME%\plugins\deploytool\itp\com.ibm.websphere.v7_7.0.0.v20080817\wasJars\com.ibm.ws.admin.core.jar
%WAS_HOME%\runtimes\com.ibm.ws.admin.client_7.0.0.jar requires
CONNECTOR_TYPE_SOAP. CONNECTOR_TYPE_RMI fails to connect; maybe a jar issue based on the stack trace messages
public class JMXAdminClientSimple {
`private AdminClient adminClient;
private ObjectName nodeagent = null;
public void initialize() throws Exception {
try {
// Initialize the AdminClient.
Properties props = new Properties();
props.setProperty(AdminClient.CONNECTOR_HOST, "localhost");
props.setProperty(AdminClient.CONNECTOR_PORT, "8880");
props.setProperty(AdminClient.CONNECTOR_TYPE, AdminClient.CONNECTOR_TYPE_SOAP);
props.setProperty(AdminClient.CONNECTOR_SECURITY_ENABLED, "false");
props.setProperty(AdminClient.USERNAME, "");
props.setProperty(AdminClient.PASSWORD, "");
adminClient = AdminClientFactory.createAdminClient(props);
} catch (Exception ex) {
ex.printStackTrace(System.out);
throw ex;
}
}`
To use the AdminClient API with security disabled on a Sun/Oracle JRE, you need the following JARs in the classpath:
runtimes/com.ibm.ws.admin.client_7.0.0.jar
runtimes/com.ibm.ws.ejb.thinclient_7.0.0.jar
runtimes/com.ibm.ws.orb_7.0.0.jar
With these JARs, RMI should also work.

FTP exception 501 "pathname" more than 8 characters

I am trying to access a file via a URI using the FTP protocol. For obvious security reasons I had to make some changes but this is where the problems seem to be coming from.
My URI is as follows:
ftp://user:pasword#host.net/u/Bigpathname/XYZ/ABC/BigPathname/bigpathname/xyz/abc/MY_LOG.LOG
And I see this exception:
sun.net.ftp.FtpProtocolException: CWD Bigpathname:501 A qualifier in "Bigpathname" is more than 8 characters
This is really confusing as I can access the file from a Windows 7 command line with the CD command just fine. Both one directory at a time and as a full path.
I found one article mentioning that MVS file names must be 8 or fewer characters but this does not explain how I can get to these same files from my command line! They do exist there is data there that I can download manual but I can not get there via a URI in Java.
PS I use .toURL().openStream() to get files on my local machine just fine, it only fails when I try to get them from my server.
EDIT October 1st
I am able to access files on the MVS host using FileZilla and the basic FTP client from the Windows 7 command line - but I still cannot get them from a URI/URL. I downloaded a very basic Java built FTP client and tried accessing the same file in my program from there and the path works but because my file name has a dot in it "MY_LOG.LOG" I am getting File does not exist 501 Invalid data set name "MY_LOG.LOG". Use MVS Dsname conventions. I am utterly perplexed by this...
EDIT Ocotober 1st afternoon :)
OK I finally got it to work with a FTP client in my Java code - but I still want to use the URL class as I have logs on both local and remote machines. Is there a way to encode a URL string so that it can retrieve a file from a remote machine with the FTP protocol? I am not sure how it works in the Java URL class but in the FTP client I had to use the CWD and then the RETR command.
If I can do this then I have one solution for getting all my logs, otherwise I will have to detect if it is a file or ftp URL and then behave differently. Not the end of the world but not what I want...
The code that tries to get the file with just a URL is as follows: (sysc is a valid host)
void testFTP()
{
String ftp = "ftp://user:pword#sysc/u/Xxxxxxxxxx/ICS/YT7/XxxxxXxxxxxxx/xxxxxxxxx/logs/xxxxxxxx/XX_YT.LOG";
try
{
URI uri = new URI(ftp);
URL ftpFile = uri.toURL();
BufferedReader in = new BufferedReader(new InputStreamReader(ftpFile.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
In this case I think the problem is also Server Related, It all works fine for me with Filezilla Server except when the filename length(including directories) exceeds 255 chars but if you want to use the URL class with another FTP you must override or implement your own URLStreamHandlerFactory.
URL.setURLStreamHandlerFactory(...);
I haven't found any for my favorite java FTP Client witch is Apache one so I have developed one but may need a few touch ups.
package net.custom.streamhandler.apacheftp;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
public class ApacheURLStreamHandlerFactory implements URLStreamHandlerFactory {
public URLStreamHandler createURLStreamHandler(String protocol) {
//this will only override the chosen protocol
if ( protocol.equalsIgnoreCase("ftp") )
return new CustomHandler();
else
return null;
}
}
class CustomHandler extends URLStreamHandler {
protected URLConnection openConnection(URL url)
throws IOException {
return new CustomURLConnection(url);
}
}
class CustomURLConnection extends URLConnection {
int reply;
FTPClient ftp = new FTPClient();
InputStream in;
static int defaultPort = 21;
static String defaultPath = "/";
CustomURLConnection ( URL url)
throws IOException {
super( url );
}
synchronized public void connect() throws IOException {
try {
int port;
if ((port = url.getPort()) == -1 )
port = defaultPort;
ftp.connect(url.getHost(), port);
String login = "anonymous";
String password = "";
if(url.getAuthority().indexOf(':')>-1 &&
url.getAuthority().indexOf('#')>-1){
String []auxArray = url.getAuthority().replaceAll("#", ":").split(":");
login = auxArray[0];
password = auxArray[1];
}
ftp.login(login, password);
reply = ftp.getReplyCode();
if (FTPReply.isPositiveCompletion(reply)) {
System.out.println("Connected Apache Success");
} else {
System.out.println("Connection Apache Failed");
ftp.disconnect();
}
in = ftp.retrieveFileStream(url.getFile());
} catch (SocketException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
connected = true;
}
synchronized public InputStream getInputStream()
throws IOException {
if (!connected)
connect();
return ( in );
}
}
*Keep in mind that you can implement new ways to handle different protocols for the java.net.URL this way.
Your code...
...
{
String ftp = "ftp://user:pword#sysc/u/Xxxxxxxxxx/ICS/YT7/XxxxxXxxxxxxx/xxxxxxxxx/logs/xxxxxxxx/XX_YT.LOG";
try
{
URL.setURLStreamHandlerFactory(new ApacheURLStreamHandlerFactory());
...
G'Bye
**(To err is human, to forgive is divine)
Try using the short name for the path. Something like /U/BIGPAT~1/XYZ/ABC/BIGPAT~1/BIGPAT~1/XYZ/ABC/MY_LOG.LOG
You can find the short name for any directory longer than 8 characters with dir /x.
FTP clients are notoriously difficult to write given the variation of (and bugs in) server implementations.
I'm betting that MVS is not completely supported by sun.net.ftp.FtpClient, which is the class used under the hood when you call URL.openStream on an FTP URL.
The Apache Commons Net library should support MVS, but it sounds like you already found a working client.
Have you considered using an RMI for transporting the files that way you can give a direct path to the file as a parameter without the use of ftp then have the file sent back in a byte array.

Java RMI ServerException - java.lang.ClassNotFoundException: org.prog.rmi.RmiServer_Stub

I have inherited some Java RMI client/server code, and while it runs fine on one machine, I haven't been able to get it to run in my dev environment.
The problem is when I run the server using the following java.exe -Djava.security.policy=conf\server.policy -SRC;. -Djava.library.path=. org.prog.rmi.RmiServer
I get the following error:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: org.prog.rmi.RmiServer_Stub (no security manager: RMI class loader disabled)
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:396)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:250)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
...
My server.policy file is
grant {
permission java.security.AllPermission;
};
And my java code:
package org.prog.rmi;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.registry.*;
public class RmiServer extends UnicastRemoteObject
implements RmiServerIntf {
private BatchApi bapi;
private String iniFileLocation;
private String layoutOption;
private int addressCount = 0;
private RefInt apiHandle = new RefInt();
public RmiServer(String iniFileLocation,String layoutOption) throws RemoteException
{ super();
this.iniFileLocation = iniFileLocation;
this.layoutOption = layoutOption;
initAPI();
startupAPI();
openAPI();
}
public static void main(String args[])
{
System.out.println("RMI server started");
// Create and install a security manager
if (System.getSecurityManager() == null)
{
System.setSecurityManager(new RMISecurityManager());
System.out.println("Security manager installed.");
}
else
System.out.println("Security manager already exists.");
try //special exception handler for registry creation
{
LocateRegistry.createRegistry(1099);
System.out.println("java RMI registry created.");
}
catch (RemoteException e)
{
//do nothing, error means registry already exists
System.out.println("java RMI registry already exists.");
}
try
{
//Instantiate RmiServer
for (String arg: args){
System.out.println(arg);
}
RmiServer obj = new RmiServer(args[0],args[1]);
// Bind this object instance to the name "RmiServer"
Naming.rebind("//127.0.0.1/RmiServer", obj);
System.out.println("PeerServer bound in registry");
}
catch (Exception e)
{
System.err.println("RMI server exception:");
e.printStackTrace();
}
}
}
I've seen solutions relating to the java.rmi.server.codebase but didn't have any luck setting this either
You haven't regenerated the stub with rmic, or the Registry doesn't have access to it via its classpath.
After some further investigation and following RMI tutorials it appeared that there was a problem with the RMI registration server on port 1099.
When I stared the RMI registration server on another port (e.g. 2005) and changed these lines of code
LocateRegistry.createRegistry(2005);
and
Naming.rebind("//127.0.0.1:2055/RmiServer", obj);
This ran sucessfully without errors and my client was able to connect.
I hope this answer helps others with this error. Let me know if anyone needs any more detailed information.

Categories

Resources