Question Paper Generator with Bloom's Taxonomy Blueprint (Java, JSP, MySQL)
It proves when a blueprint is impossible before it tries, and it measures the gap between the paper you print and the paper a student actually sits.
One-time purchase — source code, database, the written report and everything below, all in a single ZIP.
No account needed — pay & download instantly
Look inside the report
Showing the first 12 pages of 40. Tap any page to read it full size — this is the actual Word file you get, not a mock-up.
Screenshots
Tap any screenshot to open it full size. These are from the project actually running — not mockups.
About this project
A question paper generator built on the AKTU B.Tech theory paper: ten 2-mark questions in Section A, five 10-mark questions in Section B of which a student attempts three, and five questions in Section C each carrying two alternatives. A blueprint says what share of the marks should sit at each of Bloom's six levels and at each difficulty, and three strategies fill the paper against it - a random baseline, a greedy filler and simulated annealing written from scratch. There is no optimisation library anywhere in it.
What makes it more than a filler is that it answers the question every generator ducks. When a paper misses its blueprint there are two completely different reasons: the search was too weak, or the target was impossible on that question bank. Told apart by nothing, a project writes "60,000 iterations, 3% short" and nobody can say whether that 3% was ever reachable. Here a feasibility check runs first and computes an upper bound by counting, not by searching - Section A has two slots per unit, Section C has two per unit, Section B has five open slots that cannot reuse a question already placed. From those bounds comes a floor on the deviation that no algorithm of any kind can go below. Measured across twenty subjects: the average deviation is 44.8 and the floor is 42.5, so only 2.4 of it belongs to the algorithm at all, and on four subjects annealing lands exactly on the floor - which is a proof of optimality, not a comparison.
The floor is not an excuse, it is a diagnosis. AKTU publishes the Bloom level of every course outcome, and the question bank is built so that no question exceeds a subject's declared ceiling. Big Data declares K1, K2, K5 and K6 - it has no K3 or K4 at all - so a university-wide blueprint asking for 30% Apply and 20% Analyse is 50% unreachable on it, provably, forever. Nineteen of the twenty subjects cannot satisfy the standard blueprint; exactly one can. The system does not just report this - it says which questions to add, and adding them moves the ceiling by the amount it predicted.
The second measurement is the one examiners tend to sit up for. The paper prints 170 marks but a student attempts 100, choosing three of five in Section B and one of two in each Section C question - 320 different papers out of one printed sheet. So "the paper matches the blueprint" and "the student sat a paper matching the blueprint" are not the same claim. Measured: a student can vary the hard marks they face by 24 out of 100 on average, and on one subject the recall-only content ranges from 40 to 100 marks. The bounds are exact rather than estimated, because the three choices are independent - and the self-test verifies that by enumerating all 320 combinations and comparing.
A random strategy is included deliberately as a baseline. It produces a completely valid paper - every unit covered, no question twice - because that is what happens when a teacher picks questions by hand. Without it, "our paper follows the blueprint" is a claim with nothing behind it. It is on the dropdown so the difference can be seen: 121.2 against 44.8.
MySQL is used properly throughout: InnoDB with real foreign keys, a UNIQUE key on the question hash so the same question cannot enter a bank twice, another that makes one slot holding two questions impossible, and a third that stops a question appearing twice in one paper. Papers are written in a transaction so half a paper can never be stored. Every query is parameterised. The PDF export is written from scratch too - no PDF library - and the student's copy deliberately omits the Bloom level, difficulty and unit that the teacher's copy shows.
Features
- ✓AKTU's real paper structure - 170 marks printed, 100 attempted
- ✓Blueprint over Bloom's six levels and three difficulty bands, in marks and not question counts
- ✓Three strategies from scratch - random baseline, greedy, simulated annealing
- ✓Feasibility runs BEFORE generation and proves when a target is unreachable
- ✓The bound comes from counting slots, not from searching, so no algorithm can beat it
- ✓A floor on the deviation - landing on it is a proof of optimality
- ✓Measured: 44.8 average deviation of which 42.5 is the floor, 2.4 is the algorithm
- ✓Four of twenty subjects hit the floor exactly
- ✓Nineteen of twenty subjects provably cannot satisfy the standard blueprint
- ✓It says which questions to add, and the ceiling moves by the predicted amount
- ✓Measured: adding questions helps, then plateaus when the next missing level binds
- ✓One printed paper is 320 different papers a student can sit
- ✓Exact bounds on what a student can face, not estimates
- ✓Self-test verifies those bounds by enumerating all 320 combinations
- ✓Measured: a student can swing the hard marks by 24 of 100 on average
- ✓The random baseline is valid, not broken - it is what hand-picking looks like
- ✓Blueprint editor shows each target against the bank's ceiling as you type
- ✓Targets that do not sum to 100% are refused, because the deviation maths rests on it
- ✓PDF export written from scratch - no PDF library, no CDN, no Maven
- ✓The student's PDF hides Bloom level, difficulty and unit; the teacher's shows them
- ✓Role check for the teacher's copy is on the server, not just the link
- ✓Fixed seed, so the same bank gives the same paper every time
- ✓Embedded Tomcat - one command runs it, nothing to install or deploy
- ✓Question bank CRUD with a duplicate guard on a content hash
- ✓InnoDB with real foreign keys and ON DELETE CASCADE throughout
- ✓UNIQUE keys make a duplicate question, a double-filled slot and a repeated question impossible
- ✓Papers saved in a transaction - half a paper can never exist
- ✓PBKDF2 password hashing, session fixation handled at login
- ✓Every query parameterised
- ✓45 self-tests that run WITHOUT a database, so MySQL being down cannot stop them
- ✓Every number in the report comes from evaluation/results.json, none typed by hand
Modules
Tools
- • JDK 8 or newer (Adoptium is free)
- • Java Servlets and JSP
- • Apache Tomcat 9 (embedded - ships inside, nothing to install)
- • MySQL / MariaDB (XAMPP works out of the box)
- • JDBC with MySQL Connector/J (ships inside)
- • Real AKTU syllabus and Bloom levels (ship inside the project)
- • Any editor - VS Code, Eclipse, IntelliJ or Notepad
- • Any web browser
Requirements
A JDK (version 8 or newer) and MySQL. Get a free JDK from adoptium.net - the JRE alone is not enough, because the project compiles itself. XAMPP is the easiest way to get MySQL: install it, open the Control Panel and press Start next to MySQL. Nothing else has to be installed - Tomcat 9 and the MySQL driver ship inside the ZIP, and there is no Maven, no Gradle and no internet access needed at any point. The AKTU syllabus, units and the 1,891-question bank ship inside as CSV. The database and all its tables are created on first run - there is no .sql file to import. Works on Windows, Linux and Mac.
How to run
1. Extract the ZIP.
2. Start MySQL - open the XAMPP Control Panel and press Start next to MySQL.
3. Open CMD and go to the folder: cd path\to\question-paper-generator
4. Compile it: build.bat (Linux/Mac: ./build.sh)
5. Load the question bank: java -cp "webapp/WEB-INF/classes;webapp/WEB-INF/lib/*" qpg.db.Import data
6. Start the app: run.bat (Linux/Mac: ./run.sh)
7. Open http://localhost:8080 in your browser.
8. Login: admin / admin123
Then: open Blueprint to see each target against what the bank can actually reach, and Generate to build a paper. Try the 'random' strategy on the same subject to see what a paper looks like without a blueprint.
If MySQL uses a password on your machine, set it once before step 5:
set QPG_DB_PASSWORD=yourpassword
Before a viva run 'python selftest.py' - 45 checks, and they pass even with MySQL switched off. To regenerate the research numbers used in the report:
java -cp "webapp/WEB-INF/classes;webapp/WEB-INF/lib/*" qpg.eval.Results data evaluation
To see the whole thing on the command line without a browser:
java -cp "webapp/WEB-INF/classes;webapp/WEB-INF/lib/*" qpg.eval.Demo BCS501The same steps are in README.md inside the ZIP, along with a troubleshooting table.
What you get in the ZIP
- 📁 Full source code — commented throughout, so you can explain it in the viva
- 🗄️ Database — the schema builds itself on first run, with sample data
- 📖 README.md — step-by-step run instructions, database design and troubleshooting
- 📄 Full project report (Word) — Written out and formatted for AKTU — not an outline you have to fill in
- 📊 Presentation (PPT) — Ready for the final viva presentation
- 📝 Synopsis (Word) — The short write-up your guide asks for before approval
- ❓ Viva questions with answers — The questions examiners actually ask about this project
- 📐 11 ready-made diagrams — DFD, ER, use case, sequence and architecture, as images you can paste straight into the report