1

I try to generate random code name as licenseKey and check whether it is exist in database or not. If not exist, then display in my jsp page, if exist, continue generating the random code. I got the error "java.lang.StackOverflowError". How to solve this? Below is my code :

package com.raydar.hospital;
import com.raydar.hospital.DB_Connection;
import java.sql.*;

public class RandomCodeGenerator {


String licenseKey = "";

int noOfCAPSAlpha = 4;
int noOfDigits = 4;
int minLen = 8;
int maxLen = 8;

char[] code = RandomCode.generateCode(minLen, maxLen, noOfCAPSAlpha, noOfDigits);


public RandomCodeGenerator(){
}


public String getOutputCode() throws Exception{

    String result ="";

    result = isLicenseKeyExist();
    System.out.println("4 + " +result);

    if (result=="false"){

        System.out.println("1 + " +new String(code));

        licenseKey = new String(code);
    }

    else if (result=="true"){

            System.out.println("2 + " +new String(code));

            licenseKey = new String(code);

                isLicenseKeyExist ();         
        }           

    return licenseKey;
}



private String isLicenseKeyExist () throws Exception{
    String code = "";
    code = getOutputCode();

    Connection connection = null;
    Statement statement = null;
    ResultSet rs = null;
    String result="";
    System.out.println("3 + " +code);

    try{
    DB_Connection connect = new DB_Connection();

    connection = connect.getDBConnection();
    statement = connection.createStatement();
    rs = statement.executeQuery("SELECT licenseKey FROM hospital WHERE licenseKey = '" +code+ "'");
    if (rs.next()){    

    result = "true";

    }

    else{

        result = "false";

    }

    }catch (Exception e){
    System.out.println("Error retrieving data! "+e);

}

    return result;

}

}

Miss_Ann
  • 89
  • 1
  • 2
  • 12
  • 2
    Not sure for other but you should not compare String with `==` return unexpected result instead use `String.equals()` method see [How do I compare strings in Java?](http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java). Moreover you should use `Prepared Statement` to avoid `SQL Injection` See [Avoiding SQL injection in java](http://stackoverflow.com/questions/17391720/avoiding-sql-injection-in-java) – Smit Mar 24 '14 at 03:01

3 Answers3

3

You create a recursive loop where isLicenseKeyExist() calls getOutputCode(), but then getOutputCode() calls isLicenseKeyExist(). So eventually you run out of stack space, and get this exception.

Here,

public String getOutputCode() throws Exception{
    String result ="";
    result = isLicenseKeyExist();
   ...

}

private String isLicenseKeyExist () throws Exception{
    String code = "";
    code = getOutputCode();
...
}
TheLostMind
  • 35,966
  • 12
  • 68
  • 104
capturesteve
  • 373
  • 2
  • 10
0

@aween - @captureSteve has answered the first part of the question . So, straight to "I wan't to call this function" comment. See, if I understand your question correctly, you want to generate a key, and check if it is available in the DB using isLicenseKeyExist() . In such case, why don't you create the key first, then pass it to the isLicenseKeyExist(). Then this function will return true/false based on which you can decide what to do.

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
  • thanks. already change my code. in my if else statement, if result=="true", how to make sure it continue generating the code until no longer exist in database? – Miss_Ann Mar 24 '14 at 03:23
  • @aween - You could use a while loop. Check David Wallace's answer – TheLostMind Mar 24 '14 at 03:27
0

I think you want something like this. Remove the field called code from your class, and its initialiser, and put the call to RandomCode.generateCode inside your getOutputCode method like this. The reason is that you'll have to call it repeatedly if your code is already in the database.

public String getOutputCode() throws SQLException {
    String code;
    do {
        code = new String(RandomCode.generateCode(minLen, maxLen, noOfCAPSAlpha, noOfDigits));
    }
    while(licenceKeyExists(code));
    return code;
}
private boolean licenceKeyExists(String code) throws SQLException {
    try{
        DB_Connection connect = new DB_Connection();
        connection = connect.getDBConnection();
        statement = connection.createStatement();
        rs = statement.executeQuery("SELECT licenseKey FROM hospital WHERE licenseKey = '" +code+ "'");
        return rs.next();
    }
    finally {
        try {
            connection.close();
        } catch (SQLException ignored){}
    }
}
Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110
  • Thanks @David Wallace. is this code will continue generating another code if already exist in my database? – Miss_Ann Mar 24 '14 at 03:41
  • Yeah, that's what the do-while loop is for. – Dawood ibn Kareem Mar 24 '14 at 03:47
  • thanks @David Wallace. the boolean method should return true or false? sorry for my silly question :D – Miss_Ann Mar 24 '14 at 03:51
  • Yeah, a "boolean" is something that can either be true or false. It's better to use these than to use Strings, if the only values that you're likely to get are "true" and "false". – Dawood ibn Kareem Mar 24 '14 at 03:58
  • so in this method i tried using return true or return false, is it both also can? because i still can get my output code – Miss_Ann Mar 24 '14 at 04:07
  • i meant this method i should return it as true or false @David Wallace – Miss_Ann Mar 24 '14 at 04:14
  • I'm not quite sure what your earlier comment means; but because `rs.next()` returns true or false, the line `return rs.next();` will return whichever is appropriate. – Dawood ibn Kareem Mar 24 '14 at 04:14
  • because i got error licenceKeyExists(String code) must return a result of type boolean @David Wallace. so i must return true or false is it? – Miss_Ann Mar 24 '14 at 04:19
  • Really? Are you sure you pasted it exactly as I wrote it? Look, I have to go offline now for a few hours, but I will help you with this later. Or maybe someone else will. – Dawood ibn Kareem Mar 24 '14 at 04:28
  • yes @David Wallace, the return must be outside the try/catch. i tried put return rs.next(); outside the try/catch only then got no error. – Miss_Ann Mar 24 '14 at 04:30
  • Oh, so you've got another `catch` in there, before the `finally`? OK, fair call. I will fix up my answer, but I will show it throwing the `SQLException` on, rather than catching it, because I don't want to cloud the answer with error handling. – Dawood ibn Kareem Mar 24 '14 at 05:23