[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

How to execute a static method twice

Posted on 2008-11-12
16
Medium Priority
?
403 Views
Last Modified: 2013-11-23
Hi all,
In the attached code, as you can see I call the method at.sendRequestString(), twice from main() method.
The first line in sendRequestString() method is Authenticator.setDefault(new MyAuthenticator());

Authenticator is an abstract class and setDefault is a static method in that class.

When I call sendRequestString() for the second time, Authenticator.setDefault(new MyAuthenticator()); is not executed. ie; Authenticator.setDefault gets executed once and only once.
Does this happen because that Authenticator.setDefault is a static method and it will be executed only once?
If yes, how can I make it work for the second time?
My simple Java code is attached. The username and password given in the code are just sample ones.
Please help with an appropriate solution.
Any help in this regard will be well appreciated with points.
Regards,
Sreejith

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;
import java.net.URL;
public class GetAuthenticatedData
{
	public String address;
	static String username;
	static String password;
	public GetAuthenticatedData(String address){
		this.address = address;
	}
	public String sendRequestString()
	{
		Authenticator.setDefault(new MyAuthenticator());//BEING STATIC METHOD, SET DEFAULT CALLED ONLY ONCE
	    String str = null;
	    try {
	        URL url = new URL(address);
	        BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
	        
	        while (( str = in.readLine()) != null) {
	        	return str;
	        }
	        in.close();
	    } catch (MalformedURLException e) {
	    	System.out.println("e1"+e);
	    } catch (IOException e) {
	    	System.out.println("e2"+e);
	    }
	    Authenticator.setDefault(null);
		return str;
	}
	public static void main(String args[]){
		username = "username1";
		password = "password1";
		GetAuthenticatedData at = new GetAuthenticatedData("https://" + username +":"+ password + "@www.mybooo.com/core/Dd002wW.php?data={action:'contacts',args:''}");
		System.out.println("value corresponding to username1 and password1"+at.sendRequestString());
		username = "username2";
		password = "password2";
		at = new GetAuthenticatedData("https://" + username +":"+ password + "@www.mybooo.com/core/Dd002wW.php?data={action:'contacts',args:''}");
		System.out.println("value corresponding to username2 and password2 "+at.sendRequestString());
	}
}
class MyAuthenticator extends Authenticator {
	public MyAuthenticator(){
		getPasswordAuthentication();
	}
		protected PasswordAuthentication getPasswordAuthentication() {
			PasswordAuthentication auth = new PasswordAuthentication(GetAuthenticatedData.username, GetAuthenticatedData.password.toCharArray());
	        System.out.println("Username"+auth.getUserName());
	        System.out.println("Password"+new String(auth.getPassword()));
			return auth;
	}
}

Open in new window

0
Comment
Question by:Sreejith22
  • 8
  • 4
  • 4
16 Comments
 
LVL 15

Expert Comment

by:quincydude
ID: 22947465
Hi, its not Authenticator.setDefault() method do not run twice but some part of code in it does. A static method will keep in memory until being destroyed so the variables in it will keep the same also the whole application cycle if you do not change them. So I think it's the coding of Authenticator.setDefault()  affect the behaviour. You should look at the source code or any documentation to look for the reason.

Quincy
0
 

Author Comment

by:Sreejith22
ID: 22947491
Hi quincydude,
Thanks.
Here is the Authenticator.setDefault() method.

Literally, I am seeking a solution, so that I can get out of this mess.
public synchronized static void setDefault(Authenticator a) {
	SecurityManager sm = System.getSecurityManager();
	if (sm != null) {
	    NetPermission setDefaultPermission
		= new NetPermission("setDefaultAuthenticator");
	    sm.checkPermission(setDefaultPermission);
	}
 
	theAuthenticator = a;
    }

Open in new window

0
 
LVL 15

Expert Comment

by:quincydude
ID: 22947528
I think it's System.getSecurityManager() that plays the trick.
If it get the SecurityManager, the whole piece of code do not execute.
You should find a method to reset it after your sendRequestString() finishes.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:Sreejith22
ID: 22947557
System class cannot be instantiated. Then how will I reset it?
0
 
LVL 15

Expert Comment

by:quincydude
ID: 22947584
Oops, sorry what I just say was completely wrong.
This module is just for checking if system has the rights to change the authenticator. If it do not have the rights, an exception will be thrown.
0
 

Author Comment

by:Sreejith22
ID: 22947663
Quincy,
So you say that this cannot be solved?
0
 
LVL 15

Expert Comment

by:quincydude
ID: 22947706
I just noticed you got multiple returns in the code but I m not sure if it's related to the problem, but you can test this
        public String sendRequestString()
        {
 
            Authenticator.setDefault(new MyAuthenticator());//BEING STATIC METHOD, SET DEFAULT CALLED ONLY ONCE
            String str = "";
			String aline = null;
            try {
                URL url = new URL(address);
                BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
                
                while (( aline = in.readLine()) != null) {
                       str += aline;
                }
                in.close();
            } catch (MalformedURLException e) {
                System.out.println("e1"+e);
            } catch (IOException e) {
                System.out.println("e2"+e);
            }
            Authenticator.setDefault(null);
            return str;
        }

Open in new window

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 22947965
As i mentioned earlier, you should try to reset the important elements (IOW the username and password) of the Authenticator, not the authenticator itself. You can use normal mutator methods to do this and then use the accessor methods to perform the significant method of the Authenticator below. If this doesn't work (you don't have control of when the Authenticator gets called, then use an API such as Apache HttpClient, which will give you more control over the authentication process
protected PasswordAuthentication getPasswordAuthentication() {
	....
	return new PasswordAuthentication(getCurrentUsername(), getCurrentPassword().toCharArray());
}

Open in new window

0
 

Author Comment

by:Sreejith22
ID: 22948562
Below given is the final implementation, by correctly taking into consideration, each of your suggestions and comments. Still the result is the same.

Though, password authentication works correctly for both the combinations, it still does not have any effect in general and the output obtained for second combination is the same as that of the first.
So, this implies that problem is concerned with setDefault rt?

Please help with solution.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;
import java.net.URL;
public class GetAuthenticatedData1
{
    public void execute(){
    try {
        URL url = new URL("https://www.mybooo.com/core/Dd002wW.php?data={action:'contacts',args:''}");
        BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
        String str;
        while ((str = in.readLine()) != null) {
        	System.out.println("string from server"+str);
        }
        in.close();
    } catch (MalformedURLException e) {
    	System.out.println(e);
    } catch (IOException e1) {
    	System.out.println(e1);
    }
    }
    public static void main(String args[]){
    	Authenticator.setDefault(new MyAuthenticator1());
    	MyAuthenticator1 at1 = new MyAuthenticator1();
    	at1.setCredentials("usr1","pwd1");
    	GetAuthenticatedData1 ad = new GetAuthenticatedData1();
    	ad.execute();
    	at1.setCredentials("usr2","pwd2");
    	ad.execute();
    }
}
class MyAuthenticator1 extends Authenticator {
	String username = "usr1";
    String password = "pwd1";
	public void setCredentials(String user, String pass){
    	username = user;
    	password = pass;
    	System.out.println("bb"+username+"pwd"+password);
    	getPasswordAuthentication();
    }
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(username, password.toCharArray());
    }
}

Open in new window

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 22948686
Put some debug in getPasswordAuthentication to make sure it's getting called and returning what you expect
0
 

Author Comment

by:Sreejith22
ID: 22948764
I changed the password authentication method to debug as follows.

>>  protected PasswordAuthentication getPasswordAuthentication() {
      PasswordAuthentication pa = new PasswordAuthentication(username, password.toCharArray());
      System.out.println("username in password authentication"+pa.getUserName());
          System.out.println("password in password authentication"+new String(pa.getPassword()));
        return pa;
    }

and correct username password combinations are obtained.

Below given is my complete output.

>>bb usr1 pwd pwd1
username in password authentication usr1
password in password authentication pwd1
username in password authentication usr1
password in password authentication pwd1
string from server{groups:['TestG','test','Group2'],contacts:[{usr:'test10',group:'TestG'},{usr:'rhar',group:'TestG'},{usr:'zapata31',group:''},{usr:'pertchiou',group:'Group2'},{usr:'bossone',group:''},{usr:'webmaster',group:'test'},{usr:'demo14',group:''}]}

bb usr2 pwd pwd2
username in password authentication usr2
password in password authentication pwd2
string from server{groups:['TestG','test','Group2'],contacts:[{usr:'test10',group:'TestG'},{usr:'rhar',group:'TestG'},{usr:'zapata31',group:''},{usr:'pertchiou',group:'Group2'},{usr:'bossone',group:''},{usr:'webmaster',group:'test'},{usr:'demo14',group:''}]}

As you can see, for the first time, password authentication is being called twice.
Anyway, the correct combinations ae being used.

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 22948986
You should probably inspect the session handling by the server itself. The only way to do that, insofar as it's possible at all, is to check out all headers between

a. the browser and the site
b your app and the site
0
 

Author Comment

by:Sreejith22
ID: 22949050
I checked the server and it gets usr1 pwd1 combination in the second call also. So this probably  has to get fixed from the code itself rt?
I was just asking the solution for that.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 22949252
>>I checked the server and it gets usr1 pwd1 combination in the second call also.

What about with the browser?
0
 

Accepted Solution

by:
Sreejith22 earned 0 total points
ID: 22973323
I solved this issue with the following code.
For future references, I attach the code.
Thanks everyone,
Sreejith
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
 
public class AuthenticationTest {
	public static void main(String[] args) throws IOException {
		System.out.println(getDocumentData("http://localhost/private/protected.php", "Looce", "robotchicken"));
		System.out.println(getDocumentData( "http://localhost/private/protected.php", "ecooL", "nekcihctobor"));
	}
 
	private static String getDocumentData(String url, String username, String password) throws IOException {
		HttpURLConnection http = null;
		InputStreamReader in = null;
		try {
			http = (HttpURLConnection) new URL(url).openConnection();
			http.setRequestProperty("Authorization", "Basic " + Base64Coder.encodeString(username + ":" + password));
			http.connect();
			in = new InputStreamReader(http.getInputStream(), "utf-8");
		} catch (MalformedURLException e) {
			System.err.println("This shouldn't be happening");
		}
		char[] buf = new char[1024];
		StringBuilder document = new StringBuilder();
		int read;
		while ((read = in.read(buf)) > 0)
			document.append(buf, 0, read);
		return document.toString();
	}
}

Open in new window

0
 

Author Comment

by:Sreejith22
ID: 22973329
For the above code tp work, you need to have the following code also.

http://www.source-code.biz/snippets/java/Base64Coder.java.txt

Sun's implementation of HttpURLConnection seems to keep a cache of previous PasswordAuthentication objects returned by an Authenticator. The workaround was to simply fudge an Authorization header.

MyAuthenticator is not needed anymore, nor are calls to setDefault.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
A solution for Fortify Path Manipulation.
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
Suggested Courses
Course of the Month18 days, 16 hours left to enroll

834 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question