0

For my program the goal is to use a bunch of interfaces and create a program that makes a test and allows the user to take it. The specific issue I have is with the interface IQuestionFactory, which assists in making questions in the TestMaker class. I'm using a class loader given by my professor, which uses the name of the class I need to load as a parameter. I cannot figure out why I'm getting the error.

Error

java.lang.NoSuchMethodException: test.api.IQuestionFactory.<init>()
    at java.lang.Class.getConstructor0(Unknown Source)
    at java.lang.Class.getConstructor(Unknown Source)
    at test.util.MyClassLoader.createInstance(MyClassLoader.java:37)
    at test.maker.TestMaker.main(TestMaker.java:13)
Exception in thread "main" java.lang.NullPointerException
    at test.maker.TestMaker.main(TestMaker.java:14)

ClassLoader

package test.util;

import java.lang.reflect.Constructor;

public class MyClassLoader {

    //instead of using the constructor, we provide a single instance of MyClassLoader
    public static MyClassLoader instance = new MyClassLoader();

    //by making the constructor private, we ensure that it can't be called.
    private MyClassLoader() {

    }

    /**
     * Load class of the given className and create an object of that class.
     * @param className the name of the class including its package. e.g.  test.impl.QuestionFactory
     * @return return the object created.
     */
    public Object createInstance(String className) {
        try {
            ClassLoader classLoader = this.getClass().getClassLoader();
            Class loadedMyClass = classLoader.loadClass(className);
            Constructor constructor = loadedMyClass.getConstructor();
            Object myClassObject = constructor.newInstance();
            return myClassObject;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

TestMaker Class

package test.maker;

import test.api.IQuestion;
import test.api.IQuestionFactory;
import test.api.ITestSet;
import test.util.MyClassLoader;

public class TestMaker {
    public static void main (String[] args){

        MyClassLoader cl = MyClassLoader.instance;

        IQuestionFactory factory = (IQuestionFactory) cl.createInstance("test.api.IQuestionFactory");
        ITestSet testset = factory.makeEmptyTestSet();

        String question = "Which of the following people was not a US president?";
        String[] choices = {"George Washington", "Benjamin Franklin", "Andrew Jackson", "Mr. Rodgers"};
        int answer = 1;

        IQuestion q = factory.makeMultipleChoice(question, choices, answer);
        testset.add(q);

        factory.save(testset,"Questions");

    }
}

IQuestionFactory Interface

package test.api;

import java.io.IOException;


public interface IQuestionFactory {
    /**
     * @param question The question
     * @param choices The choices as an array
     * @param answer The index to the answer in the choices array
     * @return An instance of a multiple choice question.
     */
    public IQuestion makeMultipleChoice(String question, String[] choices, int answer);


    /**
     * @param question The question.
     * @param answer The answer
     * @return an instance of a true-false question
     */
    public IQuestion makeTrueFalse(String question, boolean answer);

    /** 
     * @param question The question, including the blanks
     * @param answers Array of answers to the blanks
     * @return an instance of a fill-in-the-blank question
     */
    public IQuestion makeFillInBlank(String question, String [] answers);

    /**
     * @param question The question.
     * @param keywords The answers as a list of key words.  
     * @return an instance of a short answer question.
     */
    public IQuestion makeShortAnswer(String question, String[] keywords);

    /**
     * @param filename The file containing the test set.
     * @return A Test set
     * @throws IOException if can't load the file.
     */
    public ITestSet load(String filename);


    /**
     * @param testSet The test set to be stored.
     * @param filename  The filename to be used.
     * @return true if save is successful
     * @throws IOException if unable to save the test set.
     */
    public boolean save(ITestSet testSet, String filename);


    /**
     * Create an empty test set.
     * 
     * @return an empty test set.
     */
    public ITestSet makeEmptyTestSet();


}
6
  • Pls format your code. What is the output of your stacktrace? Where is the error? Commented Dec 14, 2015 at 1:49
  • 1
    Are you trying to create an instance of an interface? Commented Dec 14, 2015 at 1:52
  • When asking for help resolving an exception, you're more likely to get useful help if you post the full exception message and stack trace, not just the name of the exception type. Commented Dec 14, 2015 at 2:02
  • Your MyClassLoader class creates a ClassLoader and Class object. If these classes exist, it may help to include that code as well. As the exception error implies, you are trying to invoke a method that does not exist, so one of the objects is calling a method that isn't there. Commented Dec 14, 2015 at 2:07
  • My bad, sorry. I edited the post. Commented Dec 14, 2015 at 2:07

1 Answer 1

3

You are trying to create an instance of an interface, which doesn't make any sense. You can only create an instance of a class. You need to implement the interface with another class and use that class as the parameter for cl.createInstance.

Edit: Although I honestly have no idea why you're using reflection here at all. You should probably be doing something like this:

IQuestionFactory factory = new MyQuestionFactory()

Where MyQuestionFactory implements IQuestionFactory. It's more efficient like that and then the compiler would catch your mistakes. What you are doing right now is:

IQuestionFactory factory = new IQuestionFactory()

And the compiler would catch that.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.