Related
After I upgraded the Firestore android sdk from v20.1.0 to v21.6.0, my Firestore queries are not working as expected.
If I make a simple get() query or a snapshotListener query (realtime) on a single document, the query works once (or twice) then stops working or getting updates (if realtime query), the onEvent() method wouldn't be triggered.
After deep investigation and multiple tests, we (my work team) found that what causes this is that our documents, each, contain a large Map field with at least 5 levels of multi key-value pairs.
Our map field is called "items", when we tried to remove it from the document, the realtime query works perfectly as expected.
P.S: we tried to check the size of the documents, the average was between 6k bytes and 5k bytes, and Firestore allows 1Mb (1M bytes) as a maximum document size.
To reproduce the bug, follow below steps :
Add this line into your project gradle file :
dependencies {
classpath 'com.google.gms:google-services:4.3.3'
}
Add those two lines into the module:app gradle file :
dependencies {
implementation 'com.google.firebase:firebase-firestore:21.6.0'
implementation 'com.google.code.gson:gson:2.8.6'
}
Add this code to create and write a copy of my document into
firestore :
private void createAndWriteDocument() {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat("MMM d, yyyy HH:mm:ss");
gson = gsonBuilder.create();
FirebaseFirestore.getInstance()
.collection(COLLECTION_ORDERS)
.document("ZYaJKmQF9n1RknziD1tj")
.set(gson.fromJson(jsonOrder2, FireStoreOrder.class));
}
private final String jsonOrder2 = "{\n" +
" \"app_name\":\"Firestore-Sample\",\n" +
" \"app_version\":\"1.0.0\",\n" +
" \"canceled_at\":\"Sep 4, 2020 15:12:34\",\n" +
" \"comments_count\":4,\n" +
" \"countryID\":\"fr\",\n" +
" \"created_at\":\"Sep 4, 2020 12:21:55\",\n" +
" \"currency\":\"EUR\",\n" +
" \"delivered_at\":\"Sep 4, 2020 15:11:30\",\n" +
" \"delivery_agent_id\":\"1rvlTtfJKNVPVxZ2mp4T2CcI1Fj2\",\n" +
" \"delivery_assignment_status\":\"accepted\",\n" +
" \"delivery_fee\":5.0,\n" +
" \"distance\":3.2547,\n" +
" \"hearts_count\":0,\n" +
" \"in_progress_at\":\"Sep 4, 2020 15:06:51\",\n" +
" \"is_friends\":false,\n" +
" \"is_private\":false,\n" +
" \"is_public\":true,\n" +
" \"is_visible\":true,\n" +
" \"items\":{\n" +
" \"-MGNqMoKy8YovI11-QUK\":{\n" +
" \"category_id\":\"-LlbKEnwkC4KZtJyN691\",\n" +
" \"discount_price\":0.0,\n" +
" \"extras\":{\n" +
" \"-M1-qhcXr8tp5KpnLp9p\":{\n" +
" \"max\":10,\n" +
" \"name\":\"Chèvre\",\n" +
" \"price\":0.6,\n" +
" \"quantity\":5,\n" +
" \"row\":6\n" +
" },\n" +
" \"-M1-rHnm7Xzjo7rE73Pk\":{\n" +
" \"max\":10,\n" +
" \"name\":\"Vache kiri\",\n" +
" \"price\":0.6,\n" +
" \"quantity\":7,\n" +
" \"row\":4\n" +
" },\n" +
" \"-M1-me-3qKOqWzul67Sr\":{\n" +
" \"is_sub_extra\":true,\n" +
" \"max\":3,\n" +
" \"name\":\"Crispy Tenders\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":1,\n" +
" \"row\":0\n" +
" },\n" +
" \"-M1-mKvK76SYLJBf3zh-\":{\n" +
" \"is_sub_extra\":true,\n" +
" \"max\":3,\n" +
" \"name\":\"Escalope de Poulet\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":2,\n" +
" \"row\":0\n" +
" },\n" +
" \"-M1-rNaEFCyHlf9WIOaH\":{\n" +
" \"max\":10,\n" +
" \"name\":\"Raclette\",\n" +
" \"price\":0.6,\n" +
" \"quantity\":4,\n" +
" \"row\":5\n" +
" }\n" +
" },\n" +
" \"extras_title\":\"Suppléments\",\n" +
" \"ingredients\":{\n" +
" \"-MEYbO7SlOBFWUVzcvg6\":{\n" +
" \"description\":\"Ingredients description\",\n" +
" \"name\":\"Cheddar\",\n" +
" \"row\":0\n" +
" },\n" +
" \"-MEYbLvKvqPu3YZPPAjo\":{\n" +
" \"description\":\"Ingredients description\",\n" +
" \"name\":\"Laitus\",\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"ingredients_title\":\"Ingrédients : Décocher pour enlever\",\n" +
" \"itemPrice\":0.0,\n" +
" \"main_image\":{\n" +
" \"ref\":\"/ZKRBeLgCauXKZ15rfRcuQTY2S1k1/-LlXe_ZbTQytlKujrhLF/products/1582717663739.jpg\",\n" +
" \"url\":\"https://firebasestorage.googleapis.com/v0/b/urban-food-a9a70.appspot.com/o/ZKRBeLgCauXKZ15rfRcuQTY2S1k1%2F-LlXe_ZbTQytlKujrhLF%2Fproducts%2F1582717663739.jpg?alt\\u003dmedia\\u0026token\\u003d1bbfd8a0-be5a-44c2-8dd9-d5a7dacf2243\"\n" +
" },\n" +
" \"max_extras\":30,\n" +
" \"name\":\"Tacos\",\n" +
" \"options\":{\n" +
" \"-LlfWYJR_zKtO1l0DjnF\":{\n" +
" \"elements\":{\n" +
" \"-LlfWj5L6weXYZUPUoGW\":{\n" +
" \"extras_title\":\"3 Viandes\",\n" +
" \"max\":1,\n" +
" \"max_extras\":3,\n" +
" \"min_extras\":3,\n" +
" \"name\":\"L : Choisir 3 Viandes\",\n" +
" \"price\":9.5,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"name\":\"Taille\",\n" +
" \"row\":-1\n" +
" },\n" +
" \"-LlfX5HY1rzcQpz1p6mG\":{\n" +
" \"elements\":{\n" +
" \"-LlfXbVB-QA-utApD3HO\":{\n" +
" \"max\":3,\n" +
" \"name\":\"Barbecue\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":2,\n" +
" \"row\":0\n" +
" },\n" +
" \"-LlfXxF-7RRTZhFwXhyX\":{\n" +
" \"max\":3,\n" +
" \"name\":\"Marocaine\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":2,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"max_quantity\":4,\n" +
" \"min_quantity\":1,\n" +
" \"name\":\"Sauces\",\n" +
" \"row\":3\n" +
" },\n" +
" \"-LlfWPIAjjgTiqtqEzep\":{\n" +
" \"elements\":{\n" +
" \"-LlfWPI9_w1gH1A3HTsB\":{\n" +
" \"name\":\"Tacos\",\n" +
" \"price\":0.0,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"name\":\"Type\",\n" +
" \"row\":2\n" +
" }\n" +
" },\n" +
" \"price\":0.0,\n" +
" \"product_id\":\"-LlfTFlgrNBdLZRn5xgn\",\n" +
" \"quantity\":2,\n" +
" \"sub_category_id\":\"-LlbKEnvPMIV3DnSiYlJ\"\n" +
" },\n" +
" \"-MGNqOGcRfYb-myLgc1d\":{\n" +
" \"category_id\":\"-LlkUx5iBSXhKdMYGxTA\",\n" +
" \"discount_price\":3.5,\n" +
" \"extras\":{\n" +
" \"-M2JOJaB_Gsc28GT8wEg\":{\n" +
" \"max\":2,\n" +
" \"name\":\"Harissa\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":1,\n" +
" \"row\":2\n" +
" }\n" +
" },\n" +
" \"extras_title\":\"Sauces\",\n" +
" \"itemPrice\":0.0,\n" +
" \"main_image\":{\n" +
" \"ref\":\"/ZKRBeLgCauXKZ15rfRcuQTY2S1k1/-LlXe_ZbTQytlKujrhLF/products/1582809519364.jpg\",\n" +
" \"url\":\"https://firebasestorage.googleapis.com/v0/b/urban-food-a9a70.appspot.com/o/ZKRBeLgCauXKZ15rfRcuQTY2S1k1%2F-LlXe_ZbTQytlKujrhLF%2Fproducts%2F1582809519364.jpg?alt\\u003dmedia\\u0026token\\u003dabc457cb-2462-44be-886a-af83db3cb501\"\n" +
" },\n" +
" \"max_extras\":2,\n" +
" \"name\":\"Oignons frites\",\n" +
" \"options\":{\n" +
" \"-M15mpsXwAzsDRlLDHJI\":{\n" +
" \"elements\":{\n" +
" \"-M15mpsXwAzsDRlLDHJG\":{\n" +
" \"name\":\"Cheddar\",\n" +
" \"price\":0.0,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"name\":\"Au choix :\",\n" +
" \"row\":-1\n" +
" }\n" +
" },\n" +
" \"price\":3.5,\n" +
" \"product_id\":\"-M15mV_4Ui2B90GlzsaR\",\n" +
" \"quantity\":1,\n" +
" \"sub_category_id\":\"-LlkUx5h8rXECP8L_hjQ\"\n" +
" },\n" +
" \"-MGNqOxoHFGoigUXao96\":{\n" +
" \"category_id\":\"-LlkUx5iBSXhKdMYGxTA\",\n" +
" \"discount_price\":3.5,\n" +
" \"extras\":{\n" +
" \"-M2JOmBf1oN1BmUUHeiY\":{\n" +
" \"name\":\"Biggy burger\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":1,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"itemPrice\":0.0,\n" +
" \"main_image\":{\n" +
" \"ref\":\"/ZKRBeLgCauXKZ15rfRcuQTY2S1k1/-LlXe_ZbTQytlKujrhLF/products/1582809369789.jpg\",\n" +
" \"url\":\"https://firebasestorage.googleapis.com/v0/b/urban-food-a9a70.appspot.com/o/ZKRBeLgCauXKZ15rfRcuQTY2S1k1%2F-LlXe_ZbTQytlKujrhLF%2Fproducts%2F1582809369789.jpg?alt\\u003dmedia\\u0026token\\u003d705593e0-e403-4931-b040-5b2261cb96e5\"\n" +
" },\n" +
" \"name\":\"Bacon frites\",\n" +
" \"options\":{\n" +
" \"-M15lyQyHs1GujtZxMtS\":{\n" +
" \"elements\":{\n" +
" \"-M15lyQxrRFaLAWGaa3i\":{\n" +
" \"name\":\"Sauce fromagère\",\n" +
" \"price\":0.0,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"name\":\"Au choix :\",\n" +
" \"row\":-1\n" +
" }\n" +
" },\n" +
" \"price\":3.5,\n" +
" \"product_id\":\"-M15lqmhF16ZOLqebPzs\",\n" +
" \"quantity\":1,\n" +
" \"sub_category_id\":\"-LlkUx5h8rXECP8L_hjQ\"\n" +
" }\n" +
" },\n" +
" \"itemsCount\":0,\n" +
" \"level_one_zone_id\":\"Île-de-France\",\n" +
" \"level_two_zone_id\":\"Paris\",\n" +
" \"order_id\":\"ZYaJKmQF9n1RknziD1tj\",\n" +
" \"order_number\":31,\n" +
" \"order_type\":\"delivery\",\n" +
" \"paid\":false,\n" +
" \"paid_with_loyalty\":0.0,\n" +
" \"picked_at\":\"Sep 4, 2020 15:12:46\",\n" +
" \"platform\":\"android\",\n" +
" \"processedAt\":{\n" +
" \"nanoseconds\":994000000,\n" +
" \"seconds\":1599228406\n" +
" },\n" +
" \"restaurant_photo\":\"https://firebasestorage.googleapis.com/v0/b/menutium-319d0.appspot.com/o/LHx3fTdtoaRlrAHSjznJSaPz9rP2%2F-MEYUb7iepk3pLwUyWX3%2Fprofile%2F1597250393877.jpg?alt\\u003dmedia\\u0026token\\u003dcbccd3fe-91fd-4397-ab34-79f5f241def2\",\n" +
" \"status\":\"picked\",\n" +
" \"store_id\":\"-MEYUb7iepk3pLwUyWX3\",\n" +
" \"store_name\":\"La Fourchette\",\n" +
" \"total_price\":50.2,\n" +
" \"updated_at\":\"Sep 7, 2020 18:54:02\",\n" +
" \"user_address\":\"166 Quai de Stalingrad, 92130 Issy-les-Moulineaux, France\\nIssy-les-Moulineaux\",\n" +
" \"user_coordinates\":\"48.8256954,2.2579879\",\n" +
" \"user_name\":\"Mo Salah\",\n" +
" \"user_phone\":\"+21650001002\",\n" +
" \"user_photo\":\"https://firebasestorage.googleapis.com/v0/b/menutium-319d0.appspot.com/o/2Bz8euUmPgMqc4Z7QZWJjLfsgV72%2Fphoto_profile?alt\\u003dmedia\\u0026token\\u003df5dcee5b-fdda-45bd-9ec3-982cfe7832bd\",\n" +
" \"user_uid\":\"2Bz8euUmPgMqc4Z7QZWJjLfsgV72\",\n" +
" \"validated_at\":\"Sep 4, 2020 15:12:42\",\n" +
" \"validatedBy\":{\n" +
" \"name\":\"Urban-Admin\",\n" +
" \"id\":\"admin\"\n" +
" }\n" +
"}";
Start a realtime query on this document :
FirebaseFirestore.getInstance()
.collection("orders")
.document("ZYaJKmQF9n1RknziD1tj")
.addSnapshotListener(new EventListener<DocumentSnapshot>() {
#Override
public void onEvent(#Nullable DocumentSnapshot value,
#Nullable FirebaseFirestoreException error) {
Log.d("testing", "onEvent triggered");
if (error != null) {
Log.i("testing", "test error : "+ error.getMessage());
}
}
});
We created two Android projects (Java code), put them into public Github repos so that anyone could reproduce the issue we are facing.
Everything is detailed into the Readme repos.
First Project repository
Second Project repository with minimal code
Before i create this question, i created an issue within the official firebase-android-sdk repository.
After five days, someone from the Firebase team answered me, they did found a bug in the Firestore sdk, fixed it, but still didn't released it, so he recommended to downgrade to older version than 21.5.0 to avoid the bug as a temporary workaround.
Github issue link here
I want to change the firstPattern with the secondPattern. When I am using Pattern Matcher / String.replaceAll()
I am using the following logic to replace
System.out.println(fileContent.replaceAll(firstPattern, secondPattern));
I am getting following error =
at java.util.regex.Pattern.error(Pattern.java:1955)
at java.util.regex.Pattern.closure(Pattern.java:3157)
at java.util.regex.Pattern.sequence(Pattern.java:2134)
at java.util.regex.Pattern.expr(Pattern.java:1996)
at java.util.regex.Pattern.compile(Pattern.java:1696)
at java.util.regex.Pattern.<init>(Pattern.java:1351)
at java.util.regex.Pattern.compile(Pattern.java:1028)
at java.lang.String.replaceAll(String.java:2223)
It is happening because in the first pattern I have used "{" and "}" brace. So it is throwing an error. Don't know how to replace these.
String firstPattern = "text.append(\" where \");\r\n" +
" text.append(\"ObjId\" + \" = \");\r\n" +
" text.append(getObjId().toString());\r\n" +
"\r\n" +
" text.append(\" and \");\r\n" +
" text.append(\" LastCngDTime = \");\r\n" +
"\r\n" +
" try {\r\n" +
" tempString = dbaExecObj.Get_DataConverter()\r\n" +
" .SmsTimeStampToDBMSTimestampString(LastCngDTime,\r\n" +
" \"-WQ\");\r\n" +
" } catch (Exception e) {\r\n" +
" throw new SmsTntResult(new SmsSystemResult(logger,\r\n" +
" SmsCsvWhoAmI.getMyFullyQualifiedMethodName(),\r\n" +
" SmsTntCodes.DATA_TYPE_CONVERSION_ERROR,\r\n" +
" SmsSystemResult.ERROR));\r\n" +
" }\r\n" +
"\r\n" +
" text.append(tempString);";
String secondPattern = "text.append(\" where \");\r\n" +
" text.append(\"ObjId\" + \" = \");\r\n" +
" text.append(getObjId().toString());\r\n" +
"\r\n" +
" text.append(\" and \");\r\n" +
" text.append(\" LastCngDTime = \");\r\n" +
"\r\n" +
" try {\r\n" +
" tempString = dbaExecObj.Get_DataConverter()\r\n" +
" .SmsTimeStampToDBMSTimestampString(LastCngDTime,\r\n" +
" \"-WQ\");\r\n" +
" } catch (Exception e) {\r\n" +
" throw new SmsTntResult(new SmsSystemResult(logger,\r\n" +
" SmsCsvWhoAmI.getMyFullyQualifiedMethodName(),\r\n" +
" SmsTntCodes.DATA_TYPE_CONVERSION_ERROR,\r\n" +
" SmsSystemResult.ERROR));\r\n" +
" }\r\n" +
"\r\n" +
" text.append(\"CAST(\");" +
" text.append(tempString);" +
" text.append(\" AS datetime)\");";
String fileContent = new Scanner(new File(filePath)).useDelimiter("\\A").next();
System.out.println(fileContent.replaceAll(firstPattern, secondPattern));
I was trying to write a SQL statement that updates my database with the new information given. When I run the program it gives me an error saying that it has encountered "RECURRING" at line 1, column 401. What does this mean? I've added to the database using this word before, so I don't understand what the issue is. Here's the code...
stmt.executeUpdate("UPDATE \"CUSTOMERS\" SET FIRSTNAME = " + "'" + customer.getFirstName() + "'" + ", LASTNAME = " + "'" + customer.getLastName() + "'" + ", EMAIL = " + "'" + customer.getEmail() + "'" + ", PHONE = " + "'" + customer.getPhone() + "'" + ", ADDRESS = " + "'" + customer.getAddress() + "'" + ", GROUPONNUMBER = " + "'" + customer.getGrouponNumber() + "'" + ", NOTES = " + "'" + customer.getNotes() + "'" + ", ONETIME = " + customer.getOneTime() + ", RECURRING = " + customer.getRecurring()+ ", NONRESPONSIVE = " + customer.getNonResponsive() + " WHERE FIRSTNAME = " + "'" + active.getFirstName() + "'" + " AND LASTNAME = " + "'" + active.getLastName() + "'" + " AND EMAIL = " + "'" + active.getEmail() + "'" + "AND PHONE = " + "'" + active.getPhone() + "'" + "AND ADDRESS = " + "'" + active.getAddress() + "'" + "AND GROUPONNUMBER = " + "'" + active.getGrouponNumber() + "'" + "AND NOTES = " + "'" + active.getNotes() + "'" + " AND ONETIME = " + active.getOneTime() + "AND RECURRING = " + active.getRecurring() + "AND GROUPON = " + active.getGroupon() + "AND NONRESPONSIVE = " + active.getNonResponsive());
I've haven't used SQL too much, so I don't really know what I'm doing to be honest.
I am trying to update my new database but for some reason after executing my Prepared Statement the data remains the same. It returns no errors or any exceptions. Please have a look at my code and see if you can help me. Thanks in advance.
try {
connect();
PreparedStatement update = con.prepareStatement("UPDATE generalInfo SET "
+ "site" + " = '"
+ siteTt + "' , "
+ "area" + " = '"
+ areaTt + "' , "
+ "unit" + " = '"
+ unitTt + "' , "
+ "unitName" + " = '"
+ unitNameTt + "' , "
+ "drawing" + " = '"
+ drawingTt + "' , "
+ "system" + " = '"
+ systemTt + "' , "
+ "stream" + " = '"
+ streamTt + "' , "
+ "product" + " = '"
+ productTt + "' , "
+ "equipmentLoc" + " = '"
+ equipLocTt + "' , "
+ "specificLoc" + " = '"
+ specificLocTt + "' , "
+ "camOperator" + " = '"
+ camTechTt + "' , "
+ "camSerial" + " = '"
+ camSerialTt + "' , "
+ "gasSurveyOperator" + " = '"
+ surveyTechTt + "' , "
+ "gasSurveySerial" + " = '"
+ surveySerialTt + "' , "
+ "equipmentDesc" + " = '"
+ equipDescTt + "' , "
+ "equipmentType" + " = '"
+ equipTypeTt + "' , "
+ "equipmentSize" + " = '"
+ equipSizeTt + "' , "
+ "equipmentID" + " = '"
+ equipIDTt + "' , "
+ "[Maintenance type]" + " = '"
+ repairTt + "' , "
+ "measurementPosition" + " = '"
+ sourceTt + "'"
+ " WHERE leakerID = " + Integer.parseInt(leakerIDCombo.getSelectedItem().toString())+";");
update.closeOnCompletion();
update.executeUpdate();
con.close();
System.out.println("saved");
} catch (SQLException ex) {
Logger.getLogger(RefineryData.class.getName()).log(Level.SEVERE, null, ex);
}
never forgett to commit your changes:
con.setAutoCommit(true);
update.closeOnCompletion();
update.executeUpdate();
con.close();
or
update.closeOnCompletion();
update.executeUpdate();
con.commit();
con.close();
I am learning java, and from what I can tell, what I am looking to do is a rare situation.
I am trying to use an API (kindof) to randomly generate musical notes. I want it to generate 20 times so i have it in a for loop. I realize that i could have used a list for this I just dont know how I could have implemented it. The question I have is, when I try to compile this code, the first part runs. It lets me make the seed. However after that it gives me
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at co.kbcomp.music.Main.main(Main.java:64)
What could I do to prevent this? I know that what I am doing is wrong. That much I dont need to be told. What I want to know is where am I going wrong.
package co.kbcomp.music;
import java.util.*;
import org.jfugue.*;
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
System.out.println("Please enter a number for the seed of the song");
long seed = in.nextLong();
Calendar cal = Calendar.getInstance();
Random rand;
//rand = new Random(cal.getTime());
rand = new Random(seed);
int NoteNumber = 0;
int NoteLength = 0;
int OctiveNumber = 0;
int ChordNumber = 0;
int InversionNumber = 0;
//int Duration = rand.nextInt(100 - 5) + 5;
//This keeps track of the iteration of the for loop.
String[] NN = { " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
String[] NL = { " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
String[] IN = { " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
String[] CN = { " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
String[] ON = { " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
//This is what is being played
String[] note = { "A", "B", "C", "D", "E", "F", "G" };
String[] noteLength = {"", "w", "", "h", "", "q","", "i"};
String[] octive = { "","1","", "2", "", "3", "", "4", "", "5", "", "6", "", "7", "", "8", "", "9"};
String[] chord = { "", "maj", "", "min"};
String[] inversion = {"", "^", "", "^^", "", "^^^", "", "^^^^", "", "^^^^^"};
String[] key = {"",""};
String keys= " ";
String randstr = " ";
//this is the loop that defines the music legnth
for (int i = 0; i < 21; i++) {
NoteNumber = rand.nextInt(7);
NoteLength = rand.nextInt(8);
OctiveNumber = rand.nextInt(18);
ChordNumber = rand.nextInt(4);
InversionNumber = rand.nextInt(10);
NN[i] = note[NoteNumber]; // This randomly generates the note to be played.
NL[i] = noteLength[NoteLength]; // This randomly generates the length of the note.
ON[i] = octive[OctiveNumber]; // This defines the octive to be played in.
CN[i] = chord[ChordNumber]; // This is defines the major or the minor
IN[i] = inversion[InversionNumber]; // IN[i] = inversion[InversionNumber];
key[i] = NN[i] + NL[i] + ON[i] + CN[i] + IN[i];
//randstr = c[0] + " " + c[1] + " " + c[2] + " " + c[3] + " " + c[4] + " " + c[5] + " " + c[6] + " " + c[7] + " " + c[8] + " " + c[9] + " " + c[10] + " " + c[11] + " " + c[12] + " " + c[13] + " " + c[14] + " " + c[15] + " " + c[16];
keys = (key[0] + " " + key[1] + " " + key[2] + " " + key[3] + " " + key[4] + " " + key[5] + " " + key[6] + " " + key[7] + " " + key[8] + " " + key[9] + " " + key[10] + " " + key[11] + " " + key[12] + " " + key[13] + " " + key[14] + " " + key[15] + " " + key[16] + " " + key[17] + " " + key[18] + " " + key[19] + " " + key[20]);
}
System.out.println(key);
Player player = new Player();
Pattern pattern = new Pattern(key[0]);
player.play(pattern);
}
}
You declare your key array with a length of two:
String[] key = {"",""};
But then later in your for loop, you try to access elements beyond the length of your array:
keys = (key[0] + " " + key[1] + " " + key[2] + " " + key[3] + " " + key[4] +
" " + key[5] + " " + key[6] + " " + key[7] + " " + key[8] + " " + key[9] +
" " + key[10] + " " + key[11] + " " + key[12] + " " + key[13] + " " +
key[14] + " " + key[15] + " " + key[16] + " " + key[17] + " " + key[18] +
" " + key[19] + " " + key[20]);
Since your array has only a length of two, when you try to access the third element (at array index 2), you get an ArrayIndexOutOfBoundsException.
String[] key = {"",""};
...
for (int i = 0; i < 21; i++) {
...
key[i] = ....
Do you see the problem?
As you array in only 20 in length
then this
for (int i = 0; i < 21; i++) {
is going to cause an overflow
It should be < 20
Plus this code is meaningless as your key is only an array of 2
keys = (key[0] + " " + key[1] + " " + key[2] + " " + key[3] + " " + key[4] + " " + key[5] + " " + key[6] + " " + key[7] + " " + key[8] + " " + key[9] + " " + key[10] + " " + key[11] + " " + key[12] + " " + key[13] + " " + key[14] + " " + key[15] + " " + key[16] + " " + key[17] + " " + key[18] + " " + key[19] + " " + key[20]);