Bridging the Theory-Practice Gap in a Maintenance Programming Course: An Experience Report

This paper presents our experience in teaching a maintenance programming course with the aim of bridging the gap between theory and practice, a recurring issue in previous course offerings. To achieve this goal, we implemented active learning strategies within an active learning classroom setting and redesigned the project work. Our approach involves peer learning and teamwork activities to cover various aspects of legacy code maintenance. For the project work, we adopted an open-ended approach that allowed students to choose their legacy code projects, which could be open-source software or a previous software project they had worked on. Analysis of students' feedback and project reports highlighted the effectiveness of our approach in bridging the gap between theory and practice. We believe that our approach had the potential to enhance students' engagement and critical thinking abilities, as well as improve practical maintenance skills relevant to their future careers.


INTRODUCTION
Software is frequently employed over an extended period, during which it undergoes development and modifications to adapt to evolving needs.According to ISO/IEC/IEEE 14764 standard [25], software maintenance could be defined as "totality of activities required to provide support to a software system." It is imperative for developers to possess the expertise required to design and implement programs that are easy to maintain.They should also be skilled in making modifications to existing, often large, programs.
It is therefore important to prepare university students for software maintenance.Software maintenance often serves as the inaugural assignment for early-career software engineers and freshly graduated students, allowing them to acquire the skills necessary for their professional evolution.Regrettably, maintenance programming has often been perceived as an unattractive activity, primarily due to its association with legacy code.
Legacy code is a term often used in the industry to describe code that presents significant challenges for modification due to its lack of comprehensibility.Various definitions of legacy code exist, with one of the most widely recognized coming from Michael Feathers, who defined it as "code without tests" [17].Several challenges can be encountered when maintaining legacy code [22], including: • The absence of proper documentation, which hinders the understanding of the software's intended functionality.• Reliance on outdated technologies, leading to compatibility issues with newer development technology.• The code's dependence on third-party libraries that are no longer maintained or supported, further complicating the maintenance process.
To teach maintenance programming, it is important that students work on existing legacy code to grasp the challenges, methods, and tools associated with maintenance programming [27].In this paper, we present our experience in teaching a maintenance programming course with a focus on legacy code.We redesigned the group activities and project assignments to address a recurring concern expressed in previous course evaluations: the perceived disconnect between theoretical instructions and practical application.We describe the active learning activities conducted in the lecture sessions and the structure of the project work.We analyzed the efficacy of our approach by examining project reports and students' feedback.

BACKGROUND 2.1 The course: Maintenance Programming
The 1DL601 -Maintenance Programming course is a 5-credit Master's course that focuses on teaching techniques and tools for maintaining and optimizing legacy code.At the end of this course, students are expected to achieve the following Intended Learning Outcomes (ILOs): ILO1 -Develop correct, stable, maintainable, and efficient software that extends or improves existing code.ILO2 -Debug and optimize programs.ILO3 -Use suitable software development tools and discuss their range and capabilities.ILO4 -Work collaboratively in programming projects.
ILO5 -Plan projects so that they can be implemented within a given framework.
The content and structure of the course is described below: • Lectures, which provide maintenance-related domain knowledge.The lectures cover the compulsory course book "Working Effectively with Legacy Code" by Michael C. Feathers [17], in addition to related literature.Lectures take place in person.• A mandatory project, which covers most of the course's topics.• Lab sessions, in which selected aspects from the lectures are practically applied.• A seminar, in which an expert from the industry shares with the students their experience in maintenance programming.• A take-home exam at the end of the course to assess the theoretical learning outcomes of the course.
In industry, software maintenance often involves working with a team.Therefore, a major part of this course is about group project work instead of individual assignments to prepare students for real-life situations.
In previous offerings of the course, students were assigned the same codebase for maintenance.However, upon taking over the course in Fall 2023, we noticed a consistent theme in the course evaluation reports: while students were generally satisfied with the course, they expressed a strong desire for better integration between lectures/theory and practical project work.In response to this feedback, we redesigned the student projects and group activities to enhance the application of theoretical concepts in their practical assignments.
This paper presents our experience in redesigning project work and group activities within an active learning classroom (ALC).In this paper, we provide an overview of the various group activities conducted during course sessions and present the details of the project work.

Literature review
Before redesigning the activities of this course, a literature review was conducted in August 2023 in the digital library Scopus.The inclusion criteria were defined as follows: • Papers reporting the teaching experiences of the authors.
• Papers addressing students' projects in a software maintenance course.
Based on these criteria, the terms for the search string were defined.A total of 1606 documents were identified when applying this search string to the title, abstract, and keywords of the papers: (teach* OR educat* OR experience) AND (software OR programming) AND maintenance AND (project OR course).
To refine the results we applied the following search string: Search within article title: ((teach* OR educat* OR experience) AND (software OR programming) AND maintenance) AND Search within title, abstract, keywords: (project AND course).
Seven papers [1,2,21,23,30,35,39] were identified, all published in English between 1996 and 2019.Two papers [30,39] were excluded because their focus was not on students' projects in a software maintenance course.Additionally, two papers [1,2] had similar contributions authored by the same authors and were published in the same year.For this reason, the journal version [2] was included in the final selection.
The small number of studies found could be attributed to the fact that, while software maintenance is an essential component of the software life cycle, it has not received the same level of attention as other software engineering activities [16].This problem is also encountered in software engineering education [28], as a few instructors have reported their experience in teaching software maintenance through project work.
Andrews and Hanan [2] reported their experience teaching a senior-year software maintenance course.The students organized themselves into groups to work on real-world software projects, which included both commercial-client and open-source software (OSS) projects.The students were tasked with two types of maintenance: adaptive and perfective.Students were required to deliver the following: an initial project plan, three progress reports, and a final report.Each group presented their work in a 25-minute presentation.The instructors conducted small group meetings to monitor individual student progress.During the course, some difficulties were encountered, particularly with the commercial-client projects, such as a client cancelled a project after six weeks of work done by the students.In contrast, the OSS projects were more predictable.
Gokhale et al. [23] reported their experience teaching an introductory, junior-level software engineering course with an emphasis on maintenance using OSS.Students were given the opportunity to choose one project from a list of 17 OSS projects selected by the authors.The authors observed that OSS projects provided students with engagement in various maintenance aspects, including understanding the code and enhancing features.
Szabo [35] reported their experience in teaching practical software maintenance using a student-produced codebase with real maintenance challenges.The project, which was originally developed by a previous student, contained approximately 11,000 lines of code and was written in a language that the majority of the students were not experts in.Students were expected to perform four types of maintenance: corrective, adaptive, perfective, and preventive.The author argued that student projects are not throwaways and that they could be valuable to teach software maintenance.
Gallagher et al. [21] reported their experience teaching software maintenance to second-year university students.The students were randomly assigned to groups and were asked to sit together in lectures.Different groups could select the same OSS project, and they were encouraged to collaborate with each other.The authors observed that the real-world aspects of the projects increased students' motivation and enabled them to meet the course objectives.
The literature review results influenced certain choices made to redesign the course.For instance, we decided to request regular progress reports from students, a practice that has been reported to be beneficial in [2,21].We decided also that students should include a reflection section in their final reports, discussing the impact of their maintenance work on their legacy code, such as in [35].Another decision was to have students working on the same project sit together in the classroom [21].We decided also to give students the choice to select the projects they want to work on [23].Moreover, we considered previous students' software projects as a valuable source for learning about legacy code [35].Take-home exam Theory.

APPROACH
In this course, we explored the following pedagogic ideas to enhance students' learning experience, primarily active and collaborative learning [36], learning-by-doing [31], documented problem solutions [3,18], reflection [9], and peer learning [8].The schedule of the course is presented in Table 1.
In the lab sessions, students worked on two popular coding Katas: (1) the Gilded Rose Refactoring Kata [4], which serves as a good starting exercise for practicing the refactoring of legacy code and designing test cases; and (2) the Tennis Refactoring Kata [5], where students had the opportunity to practice refactoring legacy code under time constraints.A Kata is a karate exercise where you repeat a form several times, making small improvements each time.Code Katas aim to apply this concept to software development, emphasizing the importance of practice over finding the perfect solution.

Active Learning Experience
We redesigned group activities within an ALC.To the best of our knowledge, this was the first time the course was offered in such a setting.The ALC was equipped with 8-person tables, two large screens, and whiteboards, see Fig. 1.
Students assigned themselves to ALC groups to engage with the rest of the group in various active learning activities within the classroom.These activities were designed to enhance students' understanding and application of the course lectures/theory and encourage them to consider how they could apply it in their projects.To ensure effective teamwork and collaboration, each ALC group consisted of a maximum of 5-6 students.Nine ALC groups were created in total.
The following subsections describe the active learning activities used in each lecture session.
3.1.1Lecture in week 1.During this session, students were asked to engage in discussions within their ALC groups to determine their agreement with the following two statements, which were presented separately during the lecture: (i) The quote by Dave Thomas: "All programming is maintenance programming because  [37], and (ii) The approach to handling risky changes in a conservative manner: "If it's not broke, don't fix it."The first activity aimed to allow students to reflect on different meanings of maintenance programming, while the second aimed to enable students to reflect on the mindset needed to approach changing code.
3.1.2Lecture in week 2.During this session, we introduced the maintenance types covered by the ISO/IEC/IEEE 14764 standard [25]: Corrective maintenance "modification of a software product performed after delivery to correct discovered problems." Preventive maintenance "modification of a software product after delivery to correct latent faults in the software product before they occur in the live system." Adaptive maintenance "modification of a software product, performed after delivery, to keep a software product usable in a changed or changing environment." Additive maintenance "modification of a software product performed after delivery to add functionality or features to enhance the usage of the product." Perfective maintenance "modification of a software product to provide enhancements for users, improvements of information for users, and recording to improve software performance, maintainability or other software attributes." Emergency maintenance "unscheduled modification performed to temporally keep a system operational, pending corrective maintenance." Each ALC group was assigned a maintenance type for discussion within their group.Subsequently, group members were tasked with presenting their assigned maintenance type to other groups.This involved team members visiting other group tables to explain their assigned maintenance type, while one member from their group remained at their own table to welcome students from other groups.This peer learning activity enabled students to better grasp the concepts and convey them in a simplified manner to their peers.
During the same lecture, students were instructed to choose a method to comprehend code from the book by Feathers on legacy code [17].These methods included storytelling, sketching, scratch refactoring, tinkering, deleting unused code, listing markup, and class-responsibility-collaborator (CRC).Students were then required to present and discuss their chosen method within their ALC group.
3.1.3Lecture in week 3.During this session, ALC groups engaged in a refactoring exercise.Refactoring has been reported to be an essential activity for maintaining and modernizing legacy code [19,33].Students were provided with one page of code and instructed to individually read the code to identify the section that required refactoring.Following this, they were required to discuss their findings with their fellow teammates within the group.The example used for this exercise was adapted from chapter 1 of the book by Fowler on refactoring [19].
3.1.4Lecture in week 4.During this session, students participated in both individual and group exercises.They were tasked with creating an effect sketch of a one-page code provided to them, which was sourced from pages 157-163 in [17].
Additionally, during the same lecture, students were introduced to the envelope exercise, which aimed to highlight challenges in dealing with legacy code.Each group was given an envelope and sheets of paper, and they were instructed to follow these steps: Step 1. Formulate a challenge that you encountered when maintaining your legacy code for other groups to solve (10 min) Rotate envelopes between groups Step 2. Suggest a solution to the problem (10 min) Rotate envelopes between groups Step 3. Analyse problem and solution and give feedback (10 min) Return envelopes to their owners Below is an example of challenge solutions formulated by students as part of the envelope exercise: 3.1.5Lecture in week 5.During this session, students engaged in a debate concerning the pros and cons of Test-Driven Development (TDD) in the context of legacy code.The class was divided into two groups: one in favor of TDD and the other against it.Each group was tasked with discussing and presenting five arguments to support their respective positions.Furthermore, they were instructed to anticipate arguments from the opposing teams and prepare responses accordingly.To facilitate the debate, each group selected a representative to engage in a debate with the opposing viewpoint on TDD.
3.1.6Lecture in week 6.During this session, students within their ALC groups were prompted to deliberate on the value of identifying performance hotspots and optimizing legacy code instead of opting for a complete code rewrite.They were also encouraged to share their reflections with the rest of the class.The dilemma of when there is a need to rewrite the code instead of maintaining it has been present in the software engineering community for decades [7] and remains relevant to this day [29].Through this activity, students realized that, in some cases, it is cost-effective to rewrite (part of) the legacy code instead of optimizing it.

Project
During the lecture in week 2, ALC students were requested to selfassign themselves to project groups.Within these project groups, which comprised a subset of the ALC group, students collaborated on assignments, providing them with an opportunity to apply what they had learned in practice.To promote effective teamwork and collaboration, each project group consisted of 2-3 students, resulting in a total of 16 project groups.
In contrast to conventional textbook-style project problems, we encouraged students to opt for real-world legacy code systems as the focus of their maintenance efforts.They were granted the flexibility to select code written in any programming language they were comfortable with or wished to explore.Additionally, they had the option to work on OSS or revisit their own code from prior projects, often encountering challenging maintenance issues.This open-ended approach aimed to motivate students to apply the techniques learned in lectures to the maintenance of legacy code, particularly in areas they were personally interested in exploring.
The students were asked to follow the pedagogic idea of Documented Problem Solutions [3].This meant not only addressing issues in the legacy code but also documenting their solutions and the thought processes behind them.They were required to submit four reports and do group presentations.The project timeline is as follows: • Initial Report due at the beginning of course week 3: This report should outline the chosen legacy code, the programming language it is written in, and a preliminary plan for its maintenance.
• Progress Report due at the beginning of course week 5: This report should detail the work done so far, any challenges faced, and group strategy for addressing them.• Progress Report due at the end of course week 6: This report should describe group continued progress, adjustments made to their plan, and any breakthroughs or setbacks encountered.
• Project Presentations in course week 7: group project work is presented to the class during 15-min presentations, to encourage students to reflect on their project and allow them to showcase their work.For the students unable to attend in person, team members needed to arrange for their participation via Zoom.• Final Report due at the end of course week 9: This report should comprehensively cover group maintenance activities, the types of maintenance performed, how they applied the course theory, and the overall impact of their work on the legacy code.A project room was available to all students throughout the entire duration of the course.The students were instructed to utilize various tools to maintain their legacy code, including the generative artificial intelligence (AI) tool, ChatGPT.Students were made aware of the limitations of such tools, such as the hallucination problem [20], and were advised to verify the outcomes.The use of generative AI tools in programming has become a reality, and students should be prepared for real-world working challenges [40].
To pass, groups needed to cover one maintenance type; to pass with credit, they needed to cover two maintenance types; and to pass with distinction, they needed to cover three maintenance types.Table 2 presents the choices of students for their maintenance projects.It is worth noting that the majority of students who chose to work on previous course projects decided to work on one of their teammates' projects and were not familiar with the chosen project beforehand.However, there were two groups where three members worked on the same projects in a previous course.Additionally, there was a group whose members were working on a digital health startup and obtained permission to use the code for this course.Five groups opted to work on OSS projects, two of which were large and complex, posing some difficulties and requiring more effort than the other groups.Nevertheless, it was a good learning experience on how working with legacy code can be tedious and at times frustrating.
In total, 16 different projects were conducted in this course.The students were exposed to this variety of projects during the group presentations in week 7, scheduled over two days in 2-hour sessions.During these sessions, students learned about the different challenges and breakthroughs of other groups.We believe this was a better learning experience compared to having a single project assignment for all, as it highlights how dealing with legacy systems can vary in complexity from one project to another.

ANALYSIS 4.1 Project reports
Except one group who chose to conduct only two types of maintenance, the rest conducted three types.All of them did preventive maintenance by refactoring the code and implementing unit tests, which cover a major part of the theory presented in the lectures.
By following the documented problem solutions approach when reporting their contribution, students explained the steps they took to address issues and how they managed to resolve them or not.The following are excerpts from randomly selected students' progress reports describing challenges they faced.The text was redacted for brevity and spell-checked.
• A group describing their difficulty understanding the code: The size of the project made it quite a challenge to be able to understand every part of the code.The legacy code also lacks documentation in many cases.This created the challenge of identifying where we can make our changes.Fortunately, the project is also very modular.Therefore, we can focus on understanding certain modules of the legacy code and keep our maintenance tasks related to them.We removed the dependency, and tried to run the application again, and it gave another dependency error.After a while, we realized that we have too many dependencies intertwined with each other, so we decided to completely remove and reinstall all dependencies from the ground up.We did this by moving the source code, and only the source code with no dependencies, to a new folder, and initialized a new project inside the folder with the latest React framework.We then tried to start the program, and when it complained that a dependency was missing, we ran npm-install to install that dependency.This continued until all dependencies were installed from the ground up, which finally resulted in the application launching without errors.• A group describing their approach to fix a bug in the source code: One of the issues had to do with the way the cloud functions would handle email sendouts.The code running this functionality was not tested, so to fix this bug, we had to address the issue itself and add tests for it.When the cloud functions would send out an email, the images would come in broken.[...] We found out that the problem was the recent server switch from US-based servers to European servers.This change led to the endpoints pointing to the wrong images, which were now located in Europe.This issue was resolved once we corrected the endpoints to the Europe-based ones.• A group describing changes to their initial plan: Initially, we planned to port the game to a different platform, like mobile.We have scrapped that plan since it would probably require too much time and work.Instead, we focused on bug fixes and improving our new additions and implementations to the game.• A group reported on how they used ChatGPT to solve a problem in changing a feature: To solve the problem [...], we gave in and asked ChatGPT how to implement this small change, and it immediately gave us an answer which was both short, simple, and worked.However, there was an unwanted white background in the sprite files, but that was not ChatGPT's fault.We understood the answer we were given and implemented it into our own code.
In their final reports, students were requested to reflect on the overall impact of their work on the legacy code.Overall, students expressed satisfaction with their maintenance work, as highlighted in the following excerpts from their final reports: "we feel proud of the changes that we have made"; "we believe that the code is improved in several ways compared to how it was before maintaining it"; "before this project, we did not believe that maintaining code would take much time or effort"; "it's clear that our efforts in understanding, updating, and enhancing the legacy code have had a positive impact"; "all of these different types of maintenance have improved the quality and lifespan of the code"; "we leave the legacy code with slight improvements, both to the quality of the codebase and the gameplay itself "; "we have at the very least created a foundation for others to build on by creating additional tests or for others to even add new functionality"; "overall our changes improved the project significantly"; and "we believe that the maintenance we have carried out for this legacy code has been impactful and very educational for us."

Students Feedback
At the end of the lecture in week 6, students were presented with the problem that had been reported in the previous offering of the course, which pertained to the discontinuity between lectures and practice.They were also presented with the changes that had been made to redesign the course's group activities and project work.Students were then invited to voluntarily and anonymously respond to a brief online questionnaire, created using Google Forms, buy scanning a QR code shown in the last slide of the final lecture.
The questionnaire contained three sections: • Section 1: ALC Group Activities.This section contained one 5-Likert scale question: The ALC group activities helped me assimilate the theoretical knowledge presented in the lectures (ranging from 1, strongly disagree, to 5, strongly agree), and two open-ended questions: Please list the aspects you liked about the ALC group activities and Please provide constructive suggestions to improve the ALC group activities.• Section 2: Project.This section contained one 5-Likert scale question: The project and the theoretical knowledge acquired in the lectures were connected (ranging from 1, strongly disagree, to 5, strongly agree), and two open-ended questions: Please list the aspects you liked about the project and Please provide constructive suggestions to improve the project.• Section 3: Overall Experience.This section contained two 5-Likert scale questions: I enjoyed the active learning experience in this course and I enjoyed working on the project.
Only six students provided feedback, which may be attributed to the fact that the questionnaire was presented at the very end of an afternoon session.Table 3 presents the results of the 5-Likert scale questions, while Table 4 presents responses to the open questions.

LESSONS LEARNED
The small number of students who provided feedback at the end of the last lecture session could be considered a limitation.However, this section was completed with our observation and analysis of The ALC group activities helped me assimilate the theoretical knowledge presented in the lectures 1 strongly agree, 4 agree, 1 neutral.4 The project and the theoretical knowledge acquired in the lectures were connected 3 strongly agree, 3 agree 4.5 I enjoyed the active learning experience in this course 2 strongly agree, 3 agree, 1 neutral.4.2 I enjoyed working in the project 3 strongly agree, 1 agree, 1 agree, 1 disagree 4 Working on open source project, choosing which kind of maintenance to perform.
Lab room or some TA who could provide some help.
students reports.The results were also supplemented with the course evaluation.Overall, students appreciated the interactive nature of the course, where they actively engaged with lecture materials compared to traditional one-way lectures.
Small Collaborative Group Activities: Students appreciated the small collaborative group activities, such as code refactoring and the envelope exercise.The informal and relaxed discussions about theoretical concepts were enjoyable.While opportunities to interact with other students were appreciated, a student mentioned the need for validation of their findings.Some of the activities, such as reflection on statements and debating TDD, do not have correct answers.The software engineering community perceives certain aspects differently, such as the way the value of TDD [26,34].We need to communicate this more clearly to the students in future offerings of the course.
Group Mixing: Some students expressed interest in more frequent ALC group mixing, similar to the exercise on maintenance types.
They found that discussing course content with students from different working groups helped enhance their understanding of the lectures.Peer learning is being implemented in many courses in different disciplines.According to David Boud "students learn a great deal by explaining their ideas to others and by participating in activities in which they can learn from their peers" [13].We plan to provide more opportunities for group mixing in future course offerings.
Fine-grained Instructions: Discussing relevant topics was valued, but there were occasional issues with unclear instructions.Assuming that students at the master's level do not need detailed instructions could be misleading in how information is presented.It has been demonstrated that clear and detailed instructions can significantly enhance university students' engagement and performance [32,38].Providing handouts before lectures to prepare for group activities was suggested as a helpful practice.There was also a need for more guidance on what constitutes a good progress report.This aspect could be improved in future offerings by sharing an example of a high-quality report from this course.
Freedom in Project Choice: Students greatly appreciated the flexibility to choose their own projects and programming languages.They enjoyed the option to work on real code they had previously developed or OSS.They also enjoyed having the autonomy to choose the types of maintenance to perform.This freedom allowed students to align their projects with their interests and strengths.The open-ended nature of projects has been shown to not only enhances students' knowledge and programming skills [24] but also benefits those in engineering disciplines [6].They are considered an effective way of forcing students to think about the problem rather than spending time looking for the correct answer in a textbookstyle project for all [11].The freedom of choice fosters a culture of trust between the instructors and the students, which leads to positive learning environment [14,15].
Use of Generative AI tools: Most of the groups explored the use of ChatGPT for their maintenance activities.The overall feedback is that it could be a useful tool to help students understand the code, identify code sections to be refactored, debug, write tests, and break dependencies.However, it's important to note that such tool can provide inaccurate results, and students were made aware of this at the beginning of the course.Generative AI tools have the potential to revolutionize software engineering education [12].Therefore, it is critical for instructors to incorporate these tools into their courses and highlight both the benefits and challenges associated with them [10].

CONCLUSION
In this paper, we presented our approach to bridging the gap between lecture/theory and practice in a maintenance programming course.Students conducted activities within a collaborative ALC environment, encouraging peer learning and teamwork.Students worked on activities such as code refactoring, effect sketching, and engaged in discussions on topics like TDD in legacy code and performance optimization versus code rewriting.Students had also the freedom to select their own legacy code projects, promoting autonomy and enabling them to explore codebases of personal interest.Overall, our approach integrated active learning and collaborative teamwork to prepare students for real-world software maintenance challenges.We believe that our approach enhances student engagement, fosters critical thinking, and facilitates practical skill development.

Figure 1 :
Figure 1: Active learning classroom used for the course

Table 1 :
The weekly course schedule 1 Lecture Introduction to the course and maintenance programming.2 Lecture Introduction to different types of maintenance and the software maintenance process.Introduction to Feathers' methodology on how to work effectively with legacy code [17], with a focus on understanding the code.3 Lecture Code smells, refactoring techniques and software maintainability measures.4 Lecture Finding test points.5 Lecture and Lab Lecture: breaking dependencies and writing tests.Lab: practicing refactoring legacy code and designing test cases with Gilded Rose Refactoring Kata.6 Lecture Code optimization and Profiling.7 Group Presentations and Lab Lab: practicing refactoring legacy code with a time constraint with the Tennis Step 2, proposed solutions by another group: "-If the author of the code is available contact them and ask.-Insert the code into ChatGPT and ask "what does this code do?" -Check makefile/libraries used.-Try to identify the "red thread" of the program and follow it".•Step 3, feedback given by another group: "OK".
• Step 1, actual challenge formulated by a group: "How to deal with missing documentation?Examples: -No running instructions.-No documentation of used Hacks." •

Table 2 :
Student project types • A group reporting their struggle in fixing issues with the source code: Both of these error messages seem to stem from the same origin [...].To combat this, we attempted several workarounds, such as manually installing packages [...].We also attempted to change the openJDK version, amidst others, [...] and more.

Table 3 :
Results of the 5-Likert scale questions

Table 4 :
Students feedback