cancel
Showing results for 
Search instead for 
Did you mean: 

java.lang.UnsatisfiedLinkError when implementing SS with third party

Former Member
0 Kudos

Hi Everyone,

Using the example provided by SAP I am trying to implement SSO between SAP EP and a third party application. When I run my code I get a java.lang.UnsatisfiedLinkError error. Not sure what the problem is. I have downloaded the latest version the sapsecu.dll and sapssoext.dll from the SAP Service Marketplace. I have included both these files in the my C:Windowssystem32 directory. I also, confirmed that this directory (C:Windowssystem32) is in my path.

I get the following exception


java.lang.UnsatisfiedLinkError: init
at com.sap.CookieReader.init(Native Method)
at com.sap.CookieReader.main(CookieReader.java:358)
Exception in thread "main"

Below is my code:



public class CookieReader {

/////////////////////////////

  static Hashtable theCookies = new Hashtable();
  public static java.security.cert.X509Certificate[] certificates = null;
  public static Socket clientSocket = null;
  public static String SSO_COOKIE = "";
  public static final int ISSUER_CERT_SUBJECT = 0;
  public static final int ISSUER_CERT_ISSUER = 1;
  public static final int ISSUER_CERT_SERIALNO = 2;
  private static boolean initialized = false;
  public static String SECLIBRARY ;
  public static String SSO2TICKETLIBRARY = "sapssoext";
  
  	static 
  	{
	  	if (System.getProperty("os.name").startsWith("Win")) 
	  	{
	  		SECLIBRARY = "sapsecu.dll";
	  	} 
	  	else 
	  	{
	  		SECLIBRARY = "libsapsecu.so";
		}
		try 
		{
			System.loadLibrary(SSO2TICKETLIBRARY);
			System.out.println("SAPSSOEXT loaded.");
		} 
		catch (Throwable e) 
		{
			System.out.println ("Error during initialization of SSO2TICKET:n" + e.getMessage());
		}
		System.out.println("static part ends.n");
	}


	/**
	* Initialization
	*
	* @param seclib location of ssf-implemenation
	*
	* @return true/false whether initailisation was ok
	*/
	private static native synchronized boolean init(String seclib);
	/**
	* Returns internal version.
	*
	* @return version
	*/
	public static native synchronized String getVersion();
	/**
	* eval ticket
	*
	* @param ticket the ticket
	* @param pab location of pab
	* @param pab_password password for access the pab
	*
	* @return [0] = (String)user, [1] = (String)sysid, [2] = (String)client , [3] =
	(byte[])certificate
	*
	*/
	public static native synchronized Object[] evalLogonTicket(String ticket, 
		String pab, String pab_password) throws Exception;
	/**
	* Parse certificate
	* @param cert Certificate received from evalLogonTicket
	* @param info_id One of the requst id´s
	*
	* @return Info sring from certificate
	*/
	
	public static native synchronized String parseCertificate(byte[] cert,int info_id);
	
			//			   print the parameters from ticket
	static void PrintResults(String user, String sysid, 
		String client, String subject, String issuer, String ticket)
	{
		System.out.println("***********************************************");
		System.out.println(" Output of program:");
		System.out.println("***********************************************");
		System.out.println("n");
		System.out.println("The ticketnn" + ticket + "n");
		System.out.println("was successfully validated.");
		System.out.println("User : " + user);
		System.out.println("Ident of ticket issuing system:");
		System.out.println("Sysid : " + sysid);
		System.out.println("Client : " + client);
		System.out.println("Certificate data of issuing system:");
		System.out.println("Subject : " + subject);
		System.out.println("Issuer : " + issuer);
		System.out.println("n");
	}
	

	//			   read the ticket string from a File
	public static String getTicket(String filename) throws FileNotFoundException
	{
		try 
		{
			BufferedReader in = new BufferedReader(new FileReader(filename));
			String str;
			StringBuffer strBuffer = new StringBuffer();
			while ((str = in.readLine()) != null) 
			{
				strBuffer.append(str);
			}
			in.close();
			return strBuffer.toString();
		}
		catch (Exception e)
		{
		//			   Let the user know what went wrong.
			System.out.println("The file could not be read:");
			System.out.println(e.getMessage());
			throw new FileNotFoundException("File "+ filename +" could not be read");
		}
	}
	

//			   parse the arguments for an option
	static String getCommandParam(String[] args, String option)
	{
		for(int i=0; i<args.length; i++)
		{
			if(args<i>.equals(option) && args.length > i+1)
			{
				return args[i+1];
			}
		}
		return null;
	}
//	   print help to console
	static void PrintHelp()
	{
		System.out.println(" java SSO2Ticket -i <ticket_file> [-L <SSF_LIB>]");
		System.out.println(" [-p <file containing public key>]");
	}
//	   get the full path to a file
	static String getFullFilePath(String filename)throws FileNotFoundException
	{
		if(filename==null)
		return null;
		String path;
		File file = new File(filename);
		if( file.getAbsolutePath().toLowerCase().indexOf(".pse") > 0 )
		{
			path = file.getAbsolutePath();
		}
		else
		{
			path = file.getAbsolutePath() + ".pse";
		}
		if( ! new File(path).exists() )
			throw new FileNotFoundException("File "+ filename +" does not exists");
		return path;
	}
		

   /**
	* Send the Hashtable (theCookies) as cookies, and write them to
	*  the specified URLconnection
	*
	* @param   urlConn  The connection to write the cookies to.
	* @param   printCookies  Print or not the action taken.
	*
	* @return  The urlConn with the all the cookies in it.
   */
   public URLConnection writeCookies
	   (URLConnection urlConn, boolean printCookies){
	 String cookieString = "";
	 Enumeration keys = theCookies.keys();
	 while (keys.hasMoreElements()) {
	   String key = (String)keys.nextElement();
	   cookieString += key + "=" + theCookies.get(key);
	   if (keys.hasMoreElements())
		  cookieString += "; ";
	   }
	 urlConn.setRequestProperty("Cookie", cookieString);
	 if (printCookies)
		System.out.println("Wrote cookies:n   " + cookieString);
	 return urlConn;
	 }

   /**
	* Read cookies from a specified URLConnection, and insert them
	*   to the Hashtable
	*  The hashtable represents the Cookies.
	*
	* @param   urlConn  the connection to read from
	* @param   printCookies  Print the cookies or not, for debugging
	* @param   reset  Clean the Hashtable or not
   */
   public void readCookies(URLConnection urlConn, boolean printCookies,
					   boolean reset){
	 if (reset)
		theCookies.clear();
	 int i=1;
	 String hdrKey;
	 String hdrString;
	 String aCookie;
	 while ((hdrKey = urlConn.getHeaderFieldKey(i)) != null) {
	   if (hdrKey.equals("Set-Cookie")) {
		  hdrString = urlConn.getHeaderField(i);
		  StringTokenizer st = new StringTokenizer(hdrString,",");
		  while (st.hasMoreTokens()) {
			String s = st.nextToken();
			aCookie = s.substring(0, s.indexOf(";"));
			// aCookie = hdrString.substring(0, s.indexOf(";"));
			int j = aCookie.indexOf("=");
			if (j != -1) {
			   if (!theCookies.containsKey(aCookie.substring(0, j))){
				 // if the Cookie do not already exist then when keep it,
				 // you may want to add some logic to update the stored Cookie instead.
				 // thanks to rwhelan
				 theCookies.put(aCookie.substring(0, j),aCookie.substring(j + 1));
				 if (printCookies){
					System.out.println("Reading Key: " + aCookie.substring(0, j));
					System.out.println("        Val: " + aCookie.substring(j + 1));
					}
				 }
			   }
			}
		}
		i++;
	   }
	}

   /**
	* Display all the cookies currently in the HashTable
	*
   */
   	public void viewAllCookies() 
   	{
		 System.out.println("All Cookies are:");
		 Enumeration keys = theCookies.keys();
		 String key;
		 while (keys.hasMoreElements())
		 {
		 	key = (String) keys.nextElement();
		 	System.out.println("The value of key is " + key);
		 		if(key.toString().equals("MYSAPSSO2"))
			 	{
					SSO_COOKIE = (String)theCookies.get(key);
		 		}
		 }
	}

  	public static void main(String[] args) throws Exception
	{
		CookieReader cr = new CookieReader();
	 	URL sa;
	 	URLConnection urlConn;
		String keys;
		try
		{
			System.out.println("Creating connection");	
	 		sa = new URL("http://localhost:50100/irj/portal?login_submit=on&login_do_redirect=1&no_cert_storing=on&j_user=myousuf&j_password=mani1982&j_authscheme=default&uidPasswordLogon=Log+on");
//	 		
			urlConn = sa.openConnection();
			System.out.println("Created Connection --- All set");	
			cr.readCookies(urlConn, true, false);
			cr.viewAllCookies();	
			System.out.println("The value of SSO_COOKIE = " + SSO_COOKIE);
		}	
		catch(Exception e)
	 	{ 
	 		System.out.println(e.getMessage());
 		}
 		try
 		{
			 	byte[] certificate;
			 	String ticket;
			 	String pab;
			 	String ssf_library;
		 		System.out.println("Start SSO2TICKET main");
		 		System.out.println("-------------- test version --------------");
		 		//String version = CookieReader.getVersion();
				ticket = SSO_COOKIE;
				//pab = "verify.pse";
				ssf_library = getCommandParam(args,"-L");
				//pab = getFullFilePath("verify.pse");
				pab = getFullFilePath(getCommandParam(args,"-p"));
				System.out.println("ssf_library = " + ssf_library);
				System.out.println("Public Access Key Path = " + pab);
				if(!init(ssf_library)) 
				{
					System.out.println ("Could not load library: " + ssf_library);
					return;
				}
				Object o[] = evalLogonTicket(ticket, pab!=null?pab:"SAPdefault" , "password");
				PrintResults((String)o[0],(String)o[1],
							(String)o[2],
							parseCertificate((byte[])o[3],ISSUER_CERT_SUBJECT), 
							parseCertificate((byte[])o[3],ISSUER_CERT_ISSUER),ticket);
 		}
 		catch(Exception e)
 		{
 			System.out.println(e.getMessage());
 		} 	
//	 		
//	 	}
//
//	 	
	 	
	 }
}

Accepted Solutions (1)

Accepted Solutions (1)

0 Kudos

Hi MOY,

What is the version for the JDK you are using?

Best regards,

Sudhi

Former Member
0 Kudos

Hi Sudhi,

Thanks for the reply, but now I have it working. Not sure what the problem was. I created a new project and pasted my old code step by step and it worked. Maybe it was eclipse acting crazy. Btw...I am using JDK 1.4....

MOY

Answers (3)

Answers (3)

0 Kudos

One more observation to close the thread!

The wrapper class provided by SAP must be in the package com.mysap.sso. This package has been hardcoded in the DLLs of the native library and the calls to the native methods should start from this package name. Irrespective of the version, whether it is JDK 1.4 or 1.5.x the code works if the wrapper class is in the com.mysap.sso package! Hope this helps many of them who have issues with the Unsatisfied Link error!

Former Member
0 Kudos

That hint regarding the packet just saved my life

Thanks!

0 Kudos

I had the same error with JDK 1.5 and I downgraded it to 1.4.x and got it to work. The ket part is that the native method of SAPSSOEXT should initialize the SAPSECU.dll library otherwise the code will not work properly and since the native methods are called by the JVM directly it might be an issue with the version.

Good to know that it works now!

Best regards,

Sudhi

Former Member
0 Kudos

The SAPSSOEXT.dll does get loaded successfully. Not sure why get an error when try to sapsecu.dll. Both these dlls exist is the c:\windows\system32 directory.

Any help on this would be really appreciated!

Thanks

MOY