PDA

View Full Version : سوال: NullpointerException در CustomTag ها



Ehsan rashydy
شنبه 21 اسفند 1389, 17:31 عصر
سلام به همه ی دوستان!
یه مشکلی پیش اومده که نمیدونم از کجا آب میخوره!
یه کلاس ساده ی tag handler دارم
یه فایل tld و
یه صفحه ی jsp هم دارم که از تگ مورد نظر استفاده میکنه،
اما وقتی tomcat رو run میکنم صفحه رو درخواست میدم نمیدونم چرا هی NullpointerException میده!
تو اینتر نت هم گشتم ولی چیزه به درد بخوری پیدا نکردم!
اگه لطف کنید یه راهمایی کنید ممنون میشم!

این از کلاس tag handler


package taghandle;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.*;


public class Exampletag extends TagSupport{
/**
*
*/
@Override
public int doStartTag() throws JspException {
try {
JspWriter out = pageContext.getOut();
out.println("Hello world\n");
} catch (IOException ioe) {
System.out.println("Error in ExampleTag: "+ioe);
}
return SKIP_BODY;
}
}


این فایل tld


<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>mytag</shortname>

<tag>
<name>mytag1</name>
<tagclass>taghandle.Exampletag</tagclass>


</tag>

</taglib>


این هم از jsp استفاده کننده


<%@ page language="java" contentType="text/html; charset=windows-1256"
pageEncoding="windows-1256"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1256">
<title>Insert title here</title>
</head>
<%@ taglib uri="/WEB-INF/TLDs/Extag.tld" prefix="myprfx" %>


<body>
<h1>This is ME, a very professional java DEVELOPER</h1>
<h2> <myprfx:mytag1/> </h2>

</body>
</html>


این هم از StackTrace


type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

org.apache.jasper.JasperException: java.lang.NullPointerException org.apache.jasper.servlet.JspServletWrapper.handle JspException(JspServletWrapper.java:527) org.apache.jasper.servlet.JspServletWrapper.servic e(JspServletWrapper.java:359) org.apache.jasper.servlet.JspServlet.serviceJspFil e(JspServlet.java:313) org.apache.jasper.servlet.JspServlet.service(JspSe rvlet.java:260) javax.servlet.http.HttpServlet.service(HttpServlet .java:717)

root cause

java.lang.NullPointerException org.apache.jsp.Extag_jsp._jspInit(Extag_jsp.java:3 0) org.apache.jasper.runtime.HttpJspBase.init(HttpJsp Base.java:52) org.apache.jasper.servlet.JspServletWrapper.getSer vlet(JspServletWrapper.java:159) org.apache.jasper.servlet.JspServletWrapper.servic e(JspServletWrapper.java:329) org.apache.jasper.servlet.JspServlet.serviceJspFil e(JspServlet.java:313) org.apache.jasper.servlet.JspServlet.service(JspSe rvlet.java:260) javax.servlet.http.HttpServlet.service(HttpServlet .java:717)

note The full stack trace of the root cause is available in the Apache Tomcat/6.0.24 logs.

Apache Tomcat/6.0.24

Ehsan rashydy
یک شنبه 22 اسفند 1389, 04:13 صبح
بالاخره مشکل رو پیدا کردم!
پیش خودم گفتم برم ببینم یه html ساده بنویسم،tomcat بهم میدتش یا نه، امتحانش کردم دیدم آره، کار میکنه
گفتم حالا برم یه jsp دیگه بنویسم بدون هیچ custom tagای، اما ایندفعه مثل اون قبلیه NullpointerException بهم داد!
وقتی تو Error مربوط به tomcat دقیق شدم، دیدیم چیزیکه باعث این Exception میشه، بین servletهای مربوط به jspها مشترکه!
رفتم تو servletها و کد مربوطه رو کشوندم بیرون!
این اون کد است، که داخل متد _jspInit() قرار داره!(خط سوم)


public void _jspInit() {
_005fjspx_005ftagPool_005fmyprfx_005fmytag1_005fno body = org.apache.jasper.runtime.TagHandlerPool.getTagHan dlerPool(getServletConfig());
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletCo nfig().getServletContext()).getExpressionFactory() ;
_jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribut e(org.apache.AnnotationProcessor.class.getName());
}

بعد از یه سرچ ساده تو گوگل رسیدم به این اینجا
http://www.coderanch.com/t/366342/Servlets/java/null-pointer-jspInit
که وقتی خوندمش دستوپاشکسته یه چیزایی دستگیرم شد!
اینو فهمیدم که Containerهایی که جزو محصولات J2EE نیستند، نباید به برنامه اجازه بدن که کلاسهای پلتفرم J2se رو تغییر بدن! مثلا کلاسهایی که در پکیجهای java.* و javax.* قرار دارن اجازه ی تغییر ندارند!
اینکه من servlet-API و jsp-API رو مستقیما داخل WEB-INF/lib قرار دادم مثله این میمونه که میخوام از یه سری کلاس مربوط به پلتفرم J2SE که خودم override کردمشون استفاده کنم! و این یعنی اشتباه!
حالا 2 تا سوال برای من پیش اومده:
اول اینکه چرا containerهایی که جزوه محصولات J2EE نیستن، نباید همچین اجازه ای به برنامه بدن!
دوم اینکه چرا وقتی من APIهای مورد نظر رو جداگانه به برنامه اضافه میکنم NullpointerException اتفاق میفته؟
ممنوم میشم اگه دوستان لطف کنن به سوالام جواب بدن!

javaphantom
یک شنبه 22 اسفند 1389, 12:23 عصر
بالاخره مشکل رو پیدا کردم!
پیش خودم گفتم برم ببینم یه html ساده بنویسم،tomcat بهم میدتش یا نه، امتحانش کردم دیدم آره، کار میکنه
گفتم حالا برم یه jsp دیگه بنویسم بدون هیچ custom tagای، اما ایندفعه مثل اون قبلیه NullpointerException بهم داد!
وقتی تو Error مربوط به tomcat دقیق شدم، دیدیم چیزیکه باعث این Exception میشه، بین servletهای مربوط به jspها مشترکه!
رفتم تو servletها و کد مربوطه رو کشوندم بیرون!
این اون کد است، که داخل متد _jspInit() قرار داره!(خط سوم)


public void _jspInit() {
_005fjspx_005ftagPool_005fmyprfx_005fmytag1_005fno body = org.apache.jasper.runtime.TagHandlerPool.getTagHan dlerPool(getServletConfig());
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletCo nfig().getServletContext()).getExpressionFactory() ;
_jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribut e(org.apache.AnnotationProcessor.class.getName());
}

بعد از یه سرچ ساده تو گوگل رسیدم به این اینجا
http://www.coderanch.com/t/366342/Servlets/java/null-pointer-jspInit
که وقتی خوندمش دستوپاشکسته یه چیزایی دستگیرم شد!
اینو فهمیدم که Containerهایی که جزو محصولات J2EE نیستند، نباید به برنامه اجازه بدن که کلاسهای پلتفرم J2se رو تغییر بدن! مثلا کلاسهایی که در پکیجهای java.* و javax.* قرار دارن اجازه ی تغییر ندارند!
اینکه من servlet-API و jsp-API رو مستقیما داخل WEB-INF/lib قرار دادم مثله این میمونه که میخوام از یه سری کلاس مربوط به پلتفرم J2SE که خودم override کردمشون استفاده کنم! و این یعنی اشتباه!
حالا 2 تا سوال برای من پیش اومده:
اول اینکه چرا containerهایی که جزوه محصولات J2EE نیستن، نباید همچین اجازه ای به برنامه بدن!
دوم اینکه چرا وقتی من APIهای مورد نظر رو جداگانه به برنامه اضافه میکنم NullpointerException اتفاق میفته؟
ممنوم میشم اگه دوستان لطف کنن به سوالام جواب بدن!

در مورد پست قبلی که nullpointerexception می گرفتین باید بگم که اولا من مدت زیادی هست که با taglib ها کار نکردم ولی فکر کنم که این سایت بدرت بخوره که بیشتر بتونی اطلاعات بدست بیاری http://jakarta.apache.org/taglibs/site/tutorial.html


اما جواب سوالات شما


اول اینکه چرا containerهایی که جزوه محصولات J2EE نیستن، نباید همچین اجازه ای به برنامه بدن!

اول از همه سوالات یکم بی معنی هست. مثلا یعنی چی container هایی که جزو محصولات J2ee نیستن!!!؟؟؟

Jee یک platform هست. تعریف platform در این فروم بقدر کافی در موردش بحث شده است. Jee شامل یک سری library یا api یا dll فایل یا header فایل هرچی که دوست داری کلا شامل یک سری API هست که بشه یک سری تکنلوژیها رو با هاش پیاده سازی کرد مثل email مثل message و و و و. container داستانش فرق می کنه. همنطور که از اسمش پیداست یعنی یک ظرف. ظرف هم که معلومه چیه چیزی هست که تو خودش یک سری شی رو جا میده. حلا می تونه این اجسام هرچی نباشن و یک محصول یا شیی یا اشیاء خواصی باشن مثل اینکه بگیم ماشین container آب یعنی داره فقط آب با خودش می بره نه بنزین یا چیزه دیگه.


این containerی که شما داری استفاده می کنی بهش می گن servlet container. یعنی فقط servlet می شناسه. یعنی هر کلاسی که از HttpServlet ارث برده باشی می تونی بیایی به این container اضافه یا بقولی معرفی کنی. کجا توی web.xml الان که جاوا 1,6 اومده می تونی با metadata یا همون annotation معرفی کنی.

این container کاری که می کنکه یعنی یکی از کارهای مهمی که می کنه مدیریت life cycle همون servlet های شما هست. به اضافه یک سری کار های دیگه. چرا نگفتم JSP برای اینکه JSP همون servlet هست. یعنی در نهایت همون servlet می شه. این container ها بر اساس یک سری استانداردها ساخته می شن ولی ممکن که نوع پیاده سازیشون متفاوت باشن. tomcat محبوب شده چون open source هست و از طرفی خوب جواب داده الان هم JBoss و هم glassfish دارن از این container استفاده می کنند. پس هیچ ربطی به j2ee نداره. بلکه بستری هست برای مدیریت و راه اندازی api های javaEE. مثل ما ejb container درایم که یک container جدا از servlet container هست که فقط ejb ها رو می شه توش انداخت مثل tomcat که فقط توش servelt می اندازن. امیدوارم این مسئله برات روشن شده باشه.

سوال دوم

دوم اینکه چرا وقتی من APIهای مورد نظر رو جداگانه به برنامه اضافه میکنم NullpointerException اتفاق میفته؟

بزار از اینجا شروع کنم که مفهوم NullPointerException رو یک بار باهم مرور کنیم. وقتی که ما می گیم Object یعنی اینکه ما از یک class در حافظه سخت افزاری یک نمونه ایجاد کنیم و به آدرس اون نقطه از حافظه دسترسی داشته باشیم که به این عمل می گیم Instantiate یا همان new کردن خودمون. حالا وقتی به کامپایلر می گی من نمونه ای از یک class رو دارم با هر نامی و اون وقت آدرس حافظه رو بهش نگی درست کنه یعنی اینکه بصورت default داره به نقطه ای حافظه اشاره می کنه که به ا ونجا می کن null. یعنی اینکه کلاس معرفی شده ولی در حافظه ساخته نشده و آدرسی نیست و آدرس فعلی همان null هست.
خوب شما معلوم نیست که چجوری داری به برنامه API اضافه می کنی. چون api در jar فایل ها هستن که به برنامه اضافه می شن و ما از api ها استفاده می کنیم چه جوری مثلا extend می کنیم یا implement یا در نهایت new .
خوب معلوم هست که شما به مفاهیم Object oriented بصورت کامل آگاهی ندارید و تمام تلاش شما این هست که کدی بزنی و یک محصول بیرون بدی.
دوست عزیز جاوا یک ابزار هست مثل تمام ابزارها دیگه. قدرتی که در این زبان وجود داره بخاطر خود زبان نیست بخاطر مفاهیمی هست که این زبان داره پشتیبانی می کنه. مفاهیم خیلی ارزش بیشتری نسبت به هر زبانی داره

Ehsan rashydy
یک شنبه 22 اسفند 1389, 14:43 عصر
ممنون بابت توجهتون جناب javaphantom

اینطورکه من فهمیدم سوال اولم کلا اشتباه بود!
و اینکه سوال دومم هم بدون اشراف به مفاهیم Object oriented پرسیدم!
این یعنی اینکه کار من از پایه ایراد داره!

بهتون حق میدم! با اینکه تو زمینه ی OOP مطالعه داشتم باز هم احساس میکنم هیچی نمیدونم!

فقط لطف کنید یه منبع معرفی کنید که بتونم این مفاهیم رو پوشش بدم!

javaphantom
یک شنبه 22 اسفند 1389, 14:52 عصر
ممنون بابت توجهتون جناب javaphantom

اینطورکه من فهمیدم سوال اولم کلا اشتباه بود!
و اینکه سوال دومم هم بدون اشراف به مفاهیم Object oriented پرسیدم!
این یعنی اینکه کار من از پایه ایراد داره!

بهتون حق میدم! با اینکه تو زمینه ی OOP مطالعه داشتم باز هم احساس میکنم هیچی نمیدونم!

فقط لطف کنید یه منبع معرفی کنید که بتونم این مفاهیم رو پوشش بدم!

تو سایت amazon که بری بنویس Object-Oriented Analysis and Design کلی کتاب برات می یاد. ولی خوب بستگی به زبان انگلیسیتم داره. اگر کتابی می خوای که تفریح هم بکنی شکلم زیاد داشته باشه و از حالت خیلی رسمی که منظورم همش text هست خلاصی پیدا کنی. Head First Object-Oriented Analysis and Design بهت معرفی می کنم. و کلان مجموعه کتابهای head first حتی مستقیم برای جاوا هم پیدا کردی جالبه. عکس داره شوخی زیاد کرده آخرش تست می گیره. کلمه ها ی کلیدی رو با هزار مسخره بازی توی مغزت جا می اندازه.

درضمن من یک پیشنهاد دیگم داشتم که java standard edition از نون شب برات واجبتره تا بری سراغ JSP که دیگه من کمتر جایی دیدم دارن استفاده می کنند. اول standard بعد enterprise یا Micro