NullPointerException bei aufruf einer Methode über ein Interface

Valentin-

Erfahrenes Mitglied
Hi,
ich habe ein gewaltiges Problem, an dem ich schon ziemlich lange jetzt sitzte.
Ich habe eine StrutsAction, die mir einen Wert an an eine Methode über ein
Interface weiterreichen soll.
Das Interface implementiert alle Methoden seiner Klasse und läuft prima.
Die StrutsAction extends einer AbstractBaseForm, die sich um die initialisierung
des interfaces kümmert. Source folgt:
Baseform
Code:
/*
 * Created on May 26, 2004
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
package petclinic.struts.form;

/**
 * @author johannes.hiemer
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */

import org.apache.log4j.Category;
import org.apache.struts.action.Action;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContextException;
import petclinic.service.IClinic;


abstract public class AbstractBaseForm extends Action implements InitializingBean {

	private IClinic clinic;
	Category cat = Category.getInstance(AbstractBaseForm.class.getName());
	
	public void setClinic(IClinic clinic) {
		this.clinic = clinic;
	}

	public IClinic getClinic() {
		return this.clinic;
	}
	
	public void afterPropertiesSet() throws Exception {
		if (clinic == null)
			throw new ApplicationContextException("Must set clinic bean property on " + getClass());
	}
}

Action
Code:
/*
 * Created on May 26, 2004
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
package petclinic.struts.action;

/**
 * @author johannes.hiemer
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Category;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import petclinic.struts.form.AbstractBaseForm;
import petclinic.struts.form.OwnerForm;

public class OwnerAction extends AbstractBaseForm {
	
	Category cat = Category.getInstance(AbstractBaseForm.class.getName());
	
    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
        ActionErrors errors = new ActionErrors();
    	List list;
    	OwnerForm oForm = (OwnerForm) form;
    	
		/** Logging the entered values, after that NullPointerException **/
    	cat.info("Retrieving owner form value...");
    	cat.info("Value:"+oForm.getlastName());
    	
    	cat.info("Class: "+ getClinic().getClass().getMethods().toString());
    	
    	list = getClinic.findOwner(oForm.getlastName());
    	
    	           
        if(list.size() < 1) {
        	errors.add(Globals.ERROR_KEY, new ActionError("error.owner.not.found"));
        	saveErrors(request, errors);
        	return mapping.getInputForward();
        }
        if(list.size() > 1) {
        	return mapping.findForward("showOwner");
        }
        return mapping.findForward("showOwner");
    }


}

Immer wenn ich die ActionForward execute aufrufe bekomme ich die
NullPointerException genau in der Zeile list = getClinic.findOwner(oForm.getlastName());

oForm.getlastName ist definitiv nicht leer, weil ich den value mit FormValidation überprüfe, aber auch mir wie ihr seht mit dem logging mir
den Inhalt ausgeben lasse.

Ich hoffe mir kann jemand helfen, ich bin echt am verzweifeln.

Vielen dank im voraus.

Ciao
 
Hey!

Vielleicht liegt es an den fehlenden Klammern von getClinic() . Ohne die Klammern wird getClinic als Feld interpretiert und ist natürlich nicht vorhanden.

getClinic.findOwner(oForm.getlastName());

Grüsse TrueSUn
 
Der getClinic() Fehler wird wohl nur hier im Forum passiert sein, das wäre aufgefallen da der Compiler da meckert.

Aber mir werden ein paar Dinge nicht ganz klar, wieso du das so implementiert hast.
---snipp---
abstract public class AbstractBaseForm extends Action implements InitializingBean
---snapp--

Wieso leitet sich deine ActionForm Implementierung von einer Action ab? Deine FormImplementierung sollte sich von ActionForm nicht von Action ableiten.

Und im nachhinein leitest du deine Action von einer ActionForm ab?

Das kann nicht funktionieren.


Dadurch das du keine wirkliche ActionForm hast, sondern eine von Action abgeleitete komische Implementierung
wirft dieser Ausdruck:
getClinic().findOwner(oForm.getlastName());
natürlich eine NullPointerException weil oForm == null ist.

Meine Behauptung solltest du im Debugger nachvollziehen können.
 
Original geschrieben von Christian Fein
Der getClinic() Fehler wird wohl nur hier im Forum passiert sein, das wäre aufgefallen da der Compiler da meckert.

Aber mir werden ein paar Dinge nicht ganz klar, wieso du das so implementiert hast.
---snipp---
abstract public class AbstractBaseForm extends Action implements InitializingBean
---snapp--

Wieso leitet sich deine ActionForm Implementierung von einer Action ab? Deine FormImplementierung sollte sich von ActionForm nicht von Action ableiten.

Und im nachhinein leitest du deine Action von einer ActionForm ab?

Das kann nicht funktionieren.


Dadurch das du keine wirkliche ActionForm hast, sondern eine von Action abgeleitete komische Implementierung
wirft dieser Ausdruck:
getClinic().findOwner(oForm.getlastName());
natürlich eine NullPointerException weil oForm == null ist.

Meine Behauptung solltest du im Debugger nachvollziehen können.

Wenn ich AbstractBaseForm von ActionForm ableite, bekomme ich beim Aufruf
im Form immer eine HTTP Status 500 - No action instance for path /getOwner could be created.
Bei Action jedoch funtkioniert es.
Und oForm ist definitiv nicht null, wenn ich es übergebe, denn ich habe in OwnerAction
mir mit dem logging den jeweiligen Value ausgeben lassen, der so aussieht:
2004-06-03 07:51:30,812 [http-8080-Processor24] INFO - Retrieving owner form value...
2004-06-03 07:51:30,812 [http-8080-Processor24] INFO - Value:bbxbcxcb

Bekomme aber genau dann immer eine:
2004-06-03 07:51:30,828 [http-8080-Processor24] WARN - Unhandled Exception thrown: class java.lang.NullPointerException

ohne eine weitere Fehlermeldung-

Vielen dank für eure Hilfe.
 
Valentin- hat gesagt.:
Wenn ich AbstractBaseForm von ActionForm ableite, bekomme ich beim Aufruf
im Form immer eine HTTP Status 500 - No action instance for path /getOwner could be created.
Bei Action jedoch funtkioniert es.
Funktionieren != Richtig ;)

Es ist dennoch falsch. Sorry
aber poste mal deine struts-config.xml
 
bitte:
Code:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
                               "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
 <data-sources/>
 <form-beans>
  <form-bean name="OwnerForm" type="petclinic.struts.form.OwnerForm"/>
 </form-beans>
 <global-exceptions/>
 <global-forwards/>
 <action-mappings>
  <action input="/Owner.jsp" name="OwnerForm" path="/getOwner"
   scope="request" type="petclinic.struts.action.OwnerAction">
   <forward name="showOwner" path="ShowOwner.jsp" redirect="true"/>
  </action>
 </action-mappings>
 <controller/>
 <message-resources parameter="ApplicationResources"/>
 <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
  <set-property property="pathnames" value="/WEB-INF/validator-rules.xml, /WEB-INF/validation.xml"/>
 </plug-in>
</struts-config>

danke :D
 
Das Problem bei deinem Design ist das du deine Action von einer Klasse die sich als eine Form zu
erkennen gibt. Das würde ich auf jedenfall ändern, denn das ist extrem verwirrend.

Wenn deine Action erben soll, dann solltest du auch deine Action von einer BaseAction ableiten.

Die ActionForm hat mit der Action nicht wirklich viel gemeinsam. Ausser das die ActionForm als Parameter der execute() Methode der Action übergeben wird, und das sie in der Deklaration der Action angegeben wird. Ansonsten ist die ActionForm absolut selbständig.

Die Action sollte auch nicht sich wie eine Bean verhalten, denn sie ist keine. Sprich es macht wenig Sinn in der Action Attribute zu definieren. Die Action ist ein Controller der nichts anderes macht als die Logic anzusteuern wie und was mit den Daten (die FormBean) geschieht.

Bevor ich irgendwelche Fehler ausmerzen würde, würd ich hier extrem refactoring betreiben.
 
Original geschrieben von Christian Fein
Das Problem bei deinem Design ist das du deine Action von einer Klasse die sich als eine Form zu
erkennen gibt. Das würde ich auf jedenfall ändern, denn das ist extrem verwirrend.

Wenn deine Action erben soll, dann solltest du auch deine Action von einer BaseAction ableiten.

Die ActionForm hat mit der Action nicht wirklich viel gemeinsam. Ausser das die ActionForm als Parameter der execute() Methode der Action übergeben wird, und das sie in der Deklaration der Action angegeben wird. Ansonsten ist die ActionForm absolut selbständig.

Die Action sollte auch nicht sich wie eine Bean verhalten, denn sie ist keine. Sprich es macht wenig Sinn in der Action Attribute zu definieren. Die Action ist ein Controller der nichts anderes macht als die Logic anzusteuern wie und was mit den Daten (die FormBean) geschieht.

Bevor ich irgendwelche Fehler ausmerzen würde, würd ich hier extrem refactoring betreiben.

Okay den ersten Teil deiner Antwort verstehe und akzeptiere ich voll und ganz. Das mit BaseForm
ist verwirrend und wird geändert.

Beim zweiten Teil habe ich vielleicht ein Verständnisproblem, aber dennoch versuche ich es
mal zu erläutern wie ich es auffasse.
Du meinst also, dass ich in der Action an sich nur die weitergabe der Daten an das Formbean
duchführen lassen sollte und den Rest durch das Formbean an sich regeln lassen sollte. Okay -
Einverstanden.

Im großen und ganzen muss ich keine refactoring betreiben, da ich bis dato nur dieses eine
Form und die eine Action habe.

Gut, ich hoffe das ist so richtig, grundsätzlich würde ich dann gerne mal eine Action sehen,
die alle Daten einfach nur weitergibt und die logic an sich von Spring managen lässt, hättest
du dazu ein Beispiel?

Vielen Dank.

Ciao
 

Neue Beiträge

Zurück