How can this be...
Another odd thing is that the error appears on the page but no trace in console
This is my code

package actions;

import com.opensymphony.xwork2.ActionSupport;

import logic.*;
import logic.organizations.Project;
public class CreateProjectAction extends ActionSupport{
	private Project project =null;
	private String message = "NULL";
	public void setProject(Project pr){
		this.project = pr;
	}
	
	public String execute(){
		
//		if (project !=null && project.getName().length()==0){
//			message = "Execute: "+project.toString();
//		}
		message = "Execute";
		return SUCCESS;
	}
	public String dummy(){
		return null;
	}
	public void validate(){
		if(project !=null && project.getName().length()==0){
			addFieldError( "project.name", "Name is required." );
		}
		message = "Validate";
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public String getMessage() {
		return message;
	}
}

error code

Struts Problem Report

Struts has detected an unhandled exception:
Messages:
File: actions/CreateProjectAction.java
Line number: 26
Stacktraces
java.lang.NullPointerException

actions.CreateProjectAction.validate(CreateProjectAction.java:26)
com.opensymphony.xwork2.validator.ValidationInterceptor.doBeforeInvocation(ValidationInterceptor.java:249)
com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:261)
org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:133)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:267)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:142)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:166)
com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:485)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:244)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:541)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:383)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:288)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
java.lang.Thread.run(Thread.java:636)

Dani AI

Generated

A NullPointerException here is almost always coming from project.getName() returning null, not from Java's boolean operators (as @peterbudo helpfully demonstrated). @Alex already found the name string itself was null even though a form field existed — the most likely cause in Struts2 is that the form tag is using the i18n/key attribute instead of binding the HTTP parameter. The Struts tag must expose the parameter name so the ParametersInterceptor can populate project.name.

Use the tag's name attribute (and optionally label) so the generated HTML input has the correct name that matches the action property. Example:

<s:textfield name="project.name" label="%{getText('project.name')}" />

Also verify the Java-side bean structure that OGNL will populate: Project needs a public no-arg constructor plus public getName()/setName(String) methods, and the action should expose a getProject() that returns a non-null Project (lazy-initialize it if convenient) so nested binding won't fail:

public Project getProject() {
    if (project == null) project = new Project();
    return project;
}

Finally, harden the validate() check so a missing parameter or an empty string cannot cause an NPE. A null-safe check (or StringUtils.isBlank) is safer than calling length() directly:

if (project == null || project.getName() == null || project.getName().trim().isEmpty()) {
    addFieldError("project.name", "Name is required.");
}

Practical diagnostics: view the page source or use the browser inspector to confirm the input's HTML name attribute, and inspect the request parameter map (or enable Struts devMode/logging) to see whether project.name is being sent to the action.

Recommended Answers

All 7 Replies

Are you sure you wanted to use if(project !=null && project.getName().length()==0) and not if(project ==null || project.getName().length()==0) (sort of crude check actually)

Yes, i'm sure. I want to check if it's null, if it isn't then proceed getting the object's name and compare it's length with 0.
The problem is that it passes the null verification (meaning that the reference has a concrete object), but when i want to call a method, it says "Hey, null.getName() is never possible!"... as far as i understand
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/NullPointerException.html

How I read that statement is: If project is not null and length of project name is equal to zero add error message.

Real time test: What happens if project is null? Well I'm project and I'm null therefore "not null" statement is not me, lets check if name length is equal to zero. Bang NullPointException

Hehe. :) Wrong. The && operator doesn't verify it's right value if it's left is false. It's no sense: the scope is to have two logic "trues", so why bother checking the second if the first is already known to be false.
My code now is:

if (project != null) {
			String str = project.getName();
			if (str.length() == 0)
				addFieldError("project.name", "Name is required.");
		}

and it gives me the error on line if (str.length() == 0). So, it's the String that is null here.
This changes my question: Why didn't struts initialized the name field? I do have a (Project) Organization.setName(String name) method and i have inserted a name in my form. Any ideas?
This is my form

<s:form action="createproject">
	<s:textfield key="project.name"/>
	<s:textfield key="project.president.name"/>
	<s:submit label="Submiter"/>
</s:form>

My CreateProjectAction.properties

project.name=Projects name
project.users=Multiple Users
project.president.name=Presidents name
project.id=DB ID

Btw, the key has been initialized. Odd.
PS: i have changed my Organization a bit: Organization.name="No name yet". This was done so that i can get pass the NullExceptionError.

Well lets have small show&see

public class NullObjectTest{

	public static void main(String[] args){
		Project test = new Project("T-E-S-T");
		Project empty = new Project("");

		System.out.println("Validate initialize project by Peter");
		validateByPeter(test);
		validateByPeter(empty);
		validateByPeter(null);

		System.out.println("\n\nValidate initialize project");
		validate(test);
		validate(empty);
		validate(null);
	}

	public static void validate(Project project){
		if(project !=null && project.getName().length()==0){
			System.out.println( "Name is required." );
		}else{
			System.out.println("Name is "+ project.getName());
		}
	}

	public static void validateByPeter(Project project){
		if(project ==null || project.getName().length()==0){
			System.out.println( "Name is required." );
		}else{
			System.out.println("Name is "+ project.getName());
		}
	}

	static class Project{
		private String name;

		public Project(String name){
			this.name = name;
		}

		public String getName(){
			return name;
		}
	}
}

Can you tell me what are the results?

Oh...
Validate initialize project by Peter
Name is T-E-S-T
Name is required.
Name is required.

Validate initialize project
Name is T-E-S-T
Name is required.
Exception in thread "main" java.lang.NullPointerException
at NullObjectTest.validate(NullObjectTest.java:22)
at NullObjectTest.main(NullObjectTest.java:15)
Shame on me. So it's the || operator that doesn't verify its second parameter ?

Ok, but the problem still persists because it's the string returned that is null. So why didn't struts initialised it? It initialised the second parameter, why not the first?

>>So it's the || operator that doesn't verify its second parameter ?
Not exactly. It is combination of what you want to check for and what would be next step after you pass this test.

>>Ok, but the problem still persists because it's the string returned that is null. So why didn't struts initialised it? It initialised the second parameter, why not the first?
There isn't much I can help as I do not have knowledge of Struts, only logical thing I can advice is to have closer look on your Project object and see why it wasn't populated. Check how you are populating it, check that you are are storing data into database. Testing frameworks are your best friend...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.