Does JVM cache url because of networkaddress.cache.ttl setting? - java

Oracle's documentation says following about cache ttl -
networkaddress.cache.ttl
Specified in java.security to indicate the caching policy for successful name lookups from the name service.. The value is specified as integer to indicate the number of seconds to cache the successful lookup.
How does this setting impact the way DNS gets resolved? I have two nodes behind geo load balancer to which I connect for a service. Now, if they switch to point to other two nodes and if the above setting is set to -1, would it still attempt to the earlier resolved DNS and attempt to go to the node that probably no longer exist? If I do not use security manager in that case does this setting have any value?
Thanks in advance.

Default behaviour of JVM is to cache forever(setting -1) if security manager is installed. So you have to explicitly set the ttl timeout so that reattempt for DNS resolution happens. You may set this property via security manager in your application startup (app level) or system level.
java.security.Security.setProperty("networkaddress.cache.ttl" , "10");
For system wide edit below file to include ttl to zero.
<JAVA_HOME>/jre/lib/security/java.security
networkaddress.cache.ttl=0
Without security manager:
Usually default value depends os & jvm type. AWS uses 60sec, Refer this
PS: System level settings always override app level settings.

Related

Equivalent property for websphere purge policy in tomcat server

There is a property called "Purge policy" in websphere datasource setting ,is there an equivalent property in tomcat that can be used.
As far as I can tell from their connection pool documentation, you could approximate the Purge Policy behavior with testOnReturn (or testOnBorrow), but this will incur additional overhead in that it will apply to every connection request, rather than in response to an observed stale connection. It looks like they give you a validationInterval property to cut down on some of the overhead, but again there appears to be a trade-off in that it could result in delaying the response to an identified stale connection if my understanding is correct.

How can I configure TCP keepAliveTimeout for DB2's JDBC Driver?

This page suggests I can tune the keepAliveTimeout value manually for DB2 with JDBC.
This list of driver properties that I've found doesn't mention this setting.
This other list of JDBC and SQLJ propeties mentions the keepAliveTimeOutsetting. However, it also says
Unless otherwise noted, all properties are in com.ibm.db2.jcc.DB2BaseDataSource.
How do I do that? As I understand it, these settings are distinct from the DB2 connect string settings, otherwise the aforementioned list would also mention the currentSchema setting.
Yet another page suggests I need a file called db2dsdriver.cfg but this does not seem to be applicable to JDBC according to this list.
How do I actually configure keepAliveTimeout for JDBC and check that it's active and set to whatever I've configured?
I see that you must specify keepAliveTimeout=0 in connection string and if you use 0 as value jdbc does't use internal value but it will use the operating systema value for interval time.
I found that here:
https://www.ibm.com/support/pages/keepalive-parameters-jdbc-driver
https://www.ibm.com/support/pages/tcpip-keepalive-settings-and-related-db2-registry-variables

Custom JVM Property is null in 8.5.5

We're migrating to WAS 8.5.5 and RAD 9. We have a legacy app that needs a custom property. We usually set it through the JVM custom properties at : Application servers > server1 > Process definition > Java Virtual Machine > Custom properties. It's always worked before. Yet our app is getting null back from this property now. Four sets of eyes have quadruple checked that it's spelled identically.
What to do? Is there a way to figure out why the value appears unset to the application? Is there an alternative way to get it into System.getProperty()?
This works fine in v8.5.5 and RAD 9. Just remember to restart the server after setting this property, since it is on the JVM level and WAS needs to be restarted to pick it up.
You may print your properties using:
Properties properties = System.getProperties();
System.out.println("Properties: " + properties);
System.out.println("myCustomProperty: " + System.getProperty("myCustomProperty"));

Clean DNS server in JVM

After my first post dealing with DNS,which is still not resolved: JVM and OS DNS Caching
,i am facing a new problem.
First here is my use case: i want to check if my private DNS is alive. If not i want to use a general DNS (e.g 8.8.8.8).
My private DNS (a bind9 on ubuntu with 192.168.1.188) as a specific record: test.testdnd.fr -> 192.168.1.100
So i thought i could do this:
if(InetAddress.getByAddress(my_dns_ip_in_byte).isReachable()){
System.setProperty("sun.net.spi.nameservice.provider.1", "dns,sun");
System.setProperty("sun.net.spi.nameservice.nameservers", 192.168.1.188);
}else{
System.setProperty("sun.net.spi.nameservice.provider.1", "dns,sun");
System.setProperty("sun.net.spi.nameservice.nameservers", "8.8.8.8");
}
InetAddress.getHostByAddress(test.testdnd.fr) -> unknow host exception
But if i only Do:
System.setProperty("sun.net.spi.nameservice.provider.1", "dns,sun");
System.setProperty("sun.net.spi.nameservice.nameservers", 192.168.1.188);
InetAddress.getHostByAddress(test.testdnd.fr) -> 192.168.1.100
So as soon as i called an InetAddress method before setting system.property, it seems that the system.property has no effect. Maybe because the JVM load the system DNS values when a InetAddress method is called even if it dont use DNS resolution.
Is that a standard behavior in the JVM or am i loosing something?
Any help is welcome,
The problem is that the nameservice providers are loaded only once in InetAddress and cached for further use. The loading happens in the static initializer of the class InetAddress. So once InetAddress is initialized, setting or changing the sun.net.spi.nameservice.provider properties will have no more effect.
The JVM only uses the DNS provider you set on lookups that fail using the system's default. You can see this in the documentation (http://docs.oracle.com/javase/7/docs/technotes/guides/net/properties.html), relevant excerpts:
By default, Java will use the system configured name lookup
mechanism
You can specify a comma separated list of IP addresses that point to the DNS servers you want to use
In JDK 7, providers are chained, which means that if a
lookup on a provider fails, the next provider in the list is consulted
to resolve the name.

What parameters for an NTLM authentication can be automatized , and how to do it with java?

I want to know what parameters can be automatized out of the 6 used during an NTLM authentication, which are:
"Username" - The one used to login on the Operating System's profile currently in use. -Already automatized, using System.getProperty("user.name")
"Password" - Same as the above. -Probably can't be automated, but i'm never sure till i try and ask...
"ProxyAddress" - Address of the proxy, to which the authentication is "handshaked to" in order to pass. -I already pseudo-automatized, but its fixed code, thus bad.
"ProxyPort" - The listening port on the proxy previously explained. -I already pseudo-automatized, but its fixed code, thus bad.
"Workstation" - My PC's ID in the local network or something...I'm currently using my machine's property ID, and its working, but i have no idea if its the correct value, or if there is a need for a value in the first place. -No idea how to automatize, but i know it's possible. NEED HELP
"Domain" - No idea which domain it refers to, thus no idea what value it should have...leaving it blank seems to be working... -No idea how to automatize, but i know it's possible. NEED HELP
EXTRA INFO: I'm using the HtmlClient library for the process, including authentication.
DefaultCredentialsProvider credentialProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider();
credentialProvider.addNTLMCredentials(username, password, proxyAddress, proxyPort, workstation, domain);
webClient.setUseInsecureSSL(true);
I'm sort of assuming that you're talking about Apache HTTPClient and HTLMUnit, but I'm basing that assumption off the method signatures in the code you provided, so I apologize if I'm mistaken.
For NTLM, this is the remote username, not necessarily the currently logged in user on the local host. I suspect that these are the same user in your scenario, but I did want to point that out. In that case, yes, using the user.name system property will provide the name of the currently logged in user:
System.getProperty("user.name");
on Windows, you can also use the USERNAME environment variable:
System.getEnv("USERNAME");
or you could use the com.sun.security.auth.module.NTSystem class:
new NTSystem.getName();
You cannot get the user's password. However, you may still be able to perform single signon where the user does not need to provide a password (more on that below.)
The Java mechanism for specifying HTTP proxies is using the http.proxyHost system property:
String proxyHost = System.getProperty("http.proxyHost");
Note that you should also check the http.nonProxyHosts system property.
Some JREs (Mac OS comes to mind immediately) will set these system properties based on the system proxy settings. If this is not set by your JRE, you will probably want to try to determine the proxy from another source. On Unix systems, you may wish to use the HTTP_PROXY environment variable. On Windows systems, you're likely best off using the ProxySelector class, as explained in this stackoverflow post.
Similar to the http.proxyHost system property, the Java mechanism is with the http.proxyPort system property:
int proxyPort = Integer.parseInt(System.getProperty("http.proxyPort"));
To reliably get your hostname on Unix, you should really call gethostname(2) via JNI or exec /usr/bin/hostname, unfortunately. On Windows, you may use the COMPUTERNAME environment variable:
System.getEnv("COMPUTERNAME");
You can get the domain name that the local machine is joined to, however (short of prompting the user), there's no way to automatically get the domain name of the machine you're authenticating to. Of course this is moot if your local workstation and the authentication target are on the same domain. Thus, on Windows, you can either use the USERDOMAIN environment variable:
System.getEnv("USERDOMAIN");
or you can use the NTSystem class:
new NTSystem().getDomain();
Whew.
As for implementing "single signon" (such that the user need not provide a password):
You may be able to perform single signon (without needing a password) by using the Java Kerberos functionality, however I was unsuccessful in this because Java requires explicit Kerberos configuration (and does not use the host's configuration) and it does not implement some ciphers required by Active Directory. (Or that's my understanding.)
You could also perform single signon with NTLM or SPNEGO (Kerberos) by using JNI to call InitializeSecurityContext and pass the resulting tokens in the WWW-Authenticate header.

Categories

Resources