Está en la página 1de 100

JAVA memo

1 Ref. & doc........................................................................................................................................................................ 3


1.1 The ref....................................................................................................................................................................... 3
1.2 Other......................................................................................................................................................................... 4
2 Basics............................................................................................................................................................................... 4
2.1 Types & structures.................................................................................................................................................... 4
2.1.1 Primitive types i!sta!ciatio! defau"t va"ues #................................................................................................4
2.1.2 Auto$o%i!&........................................................................................................................................................ 4
2.1.3 Boo"ea!s............................................................................................................................................................. '
2.1.4 (haracters.......................................................................................................................................................... '
2.1.' )tri!&.................................................................................................................................................................. '
2.1.* Arrays................................................................................................................................................................. +
2.1., Associative arrays - .ap /ashmap0.................................................................................................................. 1
2.1.+ 2ists.................................................................................................................................................................. 12
2.1.1 3!ums creati!& a custom type.........................................................................................................................13
2.2 Operators & co!structs............................................................................................................................................ 24
2.2.1 (ompariso! chec5i!& for e6ua"ity !u""ity......................................................................................................24
2.2.2 2oops............................................................................................................................................................... 24
2.2.3 7oreach "oop..................................................................................................................................................... 24
2.2.4 Ter!ary operator............................................................................................................................................... 21
2.3 Adva!ced types & o$8ects....................................................................................................................................... 21
2.3.1 9ate (a"e!dar.................................................................................................................................................. 21
2.4 Adva!ced co!structs............................................................................................................................................... 21
2.4.1 :e!eric types.................................................................................................................................................... 21
2.4.2 2ist of parameters of u!5!o;! si<e =#>..........................................................................................................21
2.' Basic arithmetics..................................................................................................................................................... 22
3 ("asses & o$8ects........................................................................................................................................................... 22
3.1 .odifiers =access fi!a" #>..................................................................................................................................... 22
3.1.1 7i!a" ................................................................................................................................................................ 22
3.2 7ie"ds -attri$utes0.................................................................................................................................................... 22
3.2.1 ?!tia"i<i!& fie"ds............................................................................................................................................... 22
3.2.2 )tatic fie"ds....................................................................................................................................................... 22
3.3 .ethods.................................................................................................................................................................. 23
3.3.1 Over"oadi!& a method...................................................................................................................................... 23
3.3.2 Over"oadi!& a method ;ith su$type parameters...............................................................................................23
3.4 :et !ame of c"ass.................................................................................................................................................... 23
3.4.1 (hec5 if 2 o$8ects are of the same c"ass...........................................................................................................24
3.' ("ass co!structors................................................................................................................................................... 24
3.'.1 (a""i!& co!structor from a!other co!structor...................................................................................................24
3.* Other $ui"di!& patter!s............................................................................................................................................ 24
3., ("ass i!herita!ce..................................................................................................................................................... 2'
3.,.1 ("ass i!herita!ce ;ith co!structors..................................................................................................................2'
3.,.2 ?!teractio! $et;ee! chi"d a!d pare!t c"ass.......................................................................................................2,
3.,.3 A$stract............................................................................................................................................................ 2,
3.+ !u"".......................................................................................................................................................................... 2,
3.1 Po"ymorphism......................................................................................................................................................... 2,
3.1.1 3mu"ate @attri$uteA po"ymorphism =B "a P/P>.................................................................................................2+
3.14 Po"ymorphismCRedefi!itio! =overridi!&>.............................................................................................................. 21
3.14.1 Overridi!&...................................................................................................................................................... 21
3.14.2 Overridi!& a static method............................................................................................................................. 21
3.11 Overridi!& O$8ect.e6ua"s...................................................................................................................................... 34
3.12 ("o!i!&................................................................................................................................................................. 31
3.13 Ref"ectio! =a!d ;ider>........................................................................................................................................... 32
3.13.1 9oc................................................................................................................................................................. 32
3.13.2 :et !ame of curre!t fu!ctio!..........................................................................................................................32
3.13.3 (a"" method dy!amica""y................................................................................................................................ 32
3.13.4 (a"" fie"d dy!amica""y.................................................................................................................................... 33
3.13.' (a"" co!structor dy!amica""y.......................................................................................................................... 34
3.14 (asti!&.................................................................................................................................................................. 34
1
3.14.1 9efi!itio!....................................................................................................................................................... 34
3.14.2 (asti!& !u""D .................................................................................................................................................. 3'
3.14.3 E(asti!&F to a! o$8ect it ;as !ot =GHco!verti!& Ico!vert to su$Gtype co!u!drumI -7/?0>...............................3'
3.1' TypeCc"ass of a! o$8ect -i!sta!ceof0...................................................................................................................... 3*
3.1'.1 i!sta!ceof operatorD........................................................................................................................................ 3*
3.1'.2 9y!amic......................................................................................................................................................... 3*
3.1* (ovaria!t retur! type =retur!i!& a su$type i! a imp"eme!tedCe%te!ded method>..................................................3,
4 3%ceptio!s...................................................................................................................................................................... 3,
4.1 :et pri!t)tac5Trace i! stri!&.................................................................................................................................. 3,
4.2 ?!teresti!& sites =o! the su$8ect>.............................................................................................................................. 3,
4.3 (hai!ed e%ceptio!s................................................................................................................................................. 3,
4.4 .u"ti catch =catchi!& mu"tip"e e%ceptio! i! o!e catch $"oc5> -mu"ticatch0.............................................................3,
4.' 7i!a""y J.................................................................................................................................................................. 3+
' JV. c"ass"oaders security............................................................................................................................................ 31
'.1 ("asspath................................................................................................................................................................. 31
'.2 ("ass"oaders............................................................................................................................................................ 31
'.2.1 3%te!di!&Cusi!& )ecure("ass2oader................................................................................................................44
'.3 )ystem..................................................................................................................................................................... 41
'.3.1 :et curre!tCe%ecutio! directory........................................................................................................................41
'.3.2 7u!ctio! ca"" stac5 -"o&&i!& de$u&&i!& thro;a$"e0........................................................................................41
'.4 )ecurity................................................................................................................................................................... 42
'.4.1 /o; permissio! is ca"cu"atedD..........................................................................................................................43
* AP?s a!d co!cer!s.......................................................................................................................................................... 43
*.1 7i"es -path KR2 KR?#0..............................................................................................................................43
*.1.1 7i"es a!d Paths................................................................................................................................................. 43
*.1.2 Ksi!& the c"ass2oader to "oad a resource -c"ass "oader "ocate fi"e0..................................................................4*
*.1.3 Properties......................................................................................................................................................... 4+
*.1.4 ResourceBu!d"e............................................................................................................................................... '1
*.2 ?!putstreams BufferedReaders & co......................................................................................................................'2
*.3 9O. L.2............................................................................................................................................................ '2
*.3.1 9oc & Ref........................................................................................................................................................ '2
*.3.2 Mode types a!d va"ues ..................................................................................................................................... '2
*.3.3 2oad L.2 docume!t 6uery a LPath...............................................................................................................'3
*.3.4 2oop throu&h Mode2ist a!d MamedMode.ap.................................................................................................'4
*.3.' Mode va"ues...................................................................................................................................................... '4
*.3.* :et Mode va"ue =as i! P/P>.............................................................................................................................'4
*.3., L.2 parsi!&.................................................................................................................................................... ''
*.3.+ L)2T............................................................................................................................................................... ''
*.4 Met.......................................................................................................................................................................... ''
*.' Other AP?s.............................................................................................................................................................. ''
*.'.1 (o"or................................................................................................................................................................ ''
*.* (ipheri!& crypto&raphy security...........................................................................................................................''
*.*.1 :e!erati!& a 5ey.............................................................................................................................................. ''
*.*.2 3!crypti!&........................................................................................................................................................ ''
*.*.3 )i&!i!& a messa&e =&uara!teei!& i!te&rity>......................................................................................................'*
*.*.4 Neystores a!d permissio!.................................................................................................................................',
*.*.' JAA)................................................................................................................................................................ '+
*., ?!ter!atio!a"isatio! -i1+!0....................................................................................................................................... '1
*.+ 2o&&i!&................................................................................................................................................................... '1
*.+.1 2o&&i!& ;ith "o&48........................................................................................................................................... '1
*.+.2 2o&&i!& ;ith commo! "o&&i!&s....................................................................................................................... *,
*.+.3 Orappi!& "o&48 ="o&&i!& ;ith a custom i!terface as used i! our struts pro8ects>............................................*+
*.1 R.?......................................................................................................................................................................... ,4
, Arou!d........................................................................................................................................................................... ,1
,.1 Javadoc................................................................................................................................................................... ,1
,.1.1 9isp"ayi!& code................................................................................................................................................ ,1
,.1.2 3"eme!ts........................................................................................................................................................... ,3
,.2 9ep"oy pac5a&e a "i$rary ma5e e%ecuta$"e...........................................................................................................,3
,.2.1 Jars................................................................................................................................................................... ,4
,.2.2 Pac5a&e fi"es mea!t to act as a "i$rary i! a 8ar..................................................................................................,4
,.2.3 Pac5a&e fi"esC8ars mea!t to act as a "i$rary 3c"ipse "i$rary...............................................................................,*
2
,.2.4 Pac5a&eCdep"oy app as a ru!!a$"e sta!da"o!e e%ecuta$"e 8ar fi"e ...................................................................,,
+ 9esi&! practises............................................................................................................................................................ ,+
+.1 9oc.......................................................................................................................................................................... ,+
+.2 :ood practises......................................................................................................................................................... ,+
+.2.1 )ecure de$u& fu!ctio!s.................................................................................................................................... ,+
+.3 )hou"d "i$rary c"asses $e made static or !otP..........................................................................................................,+
+.4 (o!tro""i!& access to attri$utes =read ;rite r;>.....................................................................................................,+
+.' Oor5i!& ;ith e%ceptio!s........................................................................................................................................ ,1
+.'.1 9oc................................................................................................................................................................... ,1
+.'.2 :e!era"............................................................................................................................................................. ,1
+.'.3 :ood practises =;ide"y pu$"ici<ed>..................................................................................................................+4
+.'.4 :ood practises =!ot so ;ide"y pu$"ici<ed>........................................................................................................+4
+.'.' (hec5ed e%ceptio! OR u!chec5ed e%ceptio! P usi!& o!e or the other............................................................+'
+.'.* (hec5ed V) u!chec5ed =a5a the de$ate ra&es o!>...........................................................................................13
+.'., 2o&&i!& errors =or does the e%ceptio! suffice P>..............................................................................................14
+.'.+ 7urther.............................................................................................................................................................. 1*
+.* AP?C7rame;or5 9esi&!.......................................................................................................................................... 1*
+.*.1 3%tract from Joschua B"ochFs @/o; To 9esi&! A :ood AP? a!d Ohy it .atters ..........................................1*
+.*.2 (o!ve!ie!ce methods...................................................................................................................................... 1,
+.*.3 A""o;i!&Cdesi&!i!& e%te!si$i"ity -p"u&i! e%te!sio! poi!t0..............................................................................1+
+., Boo55eepi!& code................................................................................................................................................... 1+
+.+ ("ass temp"ate......................................................................................................................................................... 1+
1 Quips.............................................................................................................................................................................. 1+
14 AddCResearch............................................................................................................................................................... 11
14.1 Research................................................................................................................................................................ 11
14.1.1 Ohe! ;rappi!& a c"assCo$8ect........................................................................................................................11
14.1.2 (a! ? override a method a!d addCcha!&e e%ceptio!s that are thro;!P ........................................................144
14.1.3 /e"per c"asses & compositio! patter!D access to composite features............................................................144
14.2 Orite a$out.......................................................................................................................................................... 144
11 Bi$"io&raphy.............................................................................................................................................................. 144
Written and/or compiled from diverse sources by Franois Hill
First version: 2010.12
This memo is by no means an ehaustive documentation on the sub!ect matter. "t is meant as a dynamic support
document primarily for the use of the author and as such addresses his needs and concerns first and foremost. This is
not a tutorial# $fundamental points may %ell be omitted&
The author cannot be held responsible for any use %hich may be made of the information contained therein. 'se at o%n
discretion.
1 Ref. & doc.
1.1 The ref
The 8ava tutoria"sD a"thou&h 5i!d of messy i! its or&a!isatio! itFs a"" thereR
httpDCCdo;!"oad.orac"e.comC8avaseCtutoria"Ci!de%.htm"
)pecifica""y the S Trails Covering the basics T sectio! ;hich comprisesD
GLearning the Java LanguageD
G Language BasicsD vars( arrays( operators( control flo%
G Classes & Objects:
- Numbers & Strings: "nte)er( *trin)( +har
- Generics
GEssential ClassesD ,ceptions( -e)ular ,pressions .
#
3
1.2 Other
httpDCCdo;!"oad.orac"e.comC8avaeeC*Ctutoria"CdocC
2 Basics
2.1 Types & structures
2.1.1 Primitive types, instanciation, default values
2.1.1.1 Default values
:e!era""y spea5i!& this defau"t ;i"" $e <ero or null depe!di!& o! the data type
-httpDCCdo;!"oad.orac"e.comC8avaseCtutoria"C8avaC!utsa!d$o"tsCdatatypes.htm"0
2.1.1.2 Type conversions
2.1.1.2.1 trin! to int
int my_int = Integer.parseInt(str);
// or
Integer my_int = Integer.valueOf(str); // throws NumberFormatException - if the string cannot be parsed as an integer.
2.1.1.2.2 int to trin!
String my_str = String.valueOf(int);
// or
String my_str = Integer.toString(int);
2.1.1.2." trin! to Boolean
Boolean boolean1 = Boolean.valueOf("true"); // anything else other than "true" will return false.
Boolean boolean2 = Boolean.parseBoolean("true"); //
2.1.1.2.# $oolean to trin!
public static boolean stringToBool(String s) {
if (s.equals("1"))
return true;
if (s.equals("0"))
return false;
throw new IllegalArgumentException(s+" is not a bool. Only 1 and 0 are.");
}
2.1.1.2.% int to he&
java.lang.Integer.toHexString( col_rgb );
2.1.2 'uto$o&in!
Bo%i!& U co!verti!& =for e%amp"e> a! int to a! Integer.
K!$o%i!& U other ;ay rou!d.
Be a;are of auto$o%i!&R
3%amp"eD
?f ;idth is a! Integer the fo""o;i!& testD
shelf_bo.getWidth() <= 0
is e6uiva"e!t throu&h the mecha!ism of auto$o%i!& =a!d autoGu!$o%i!&> toD
shelf_bo.getWidth().intValue() <= 0
The Integer retur!ed $y getWidth() is automatica""y KMBOL39 to the !o!Go$8ect type int.
)o this ca! e%p"ai! NullPointerException arisi!& o! that "i!e =a!d ;e sure itIs !ot shelf_bo thatIs null)D itIs getWidth()
that retur!s null.
4
2.1." Booleans
2.1.3.1 (ot )*+
R =the I!otI operator> seems to ;or5 o!"y for the primitive type boolean
7or Boolean =the ;rappi!& O$8ect> useD
if ((Boolean.FALSE.equals(this.serviceBo.isCalendarAlwasOpen()) )
2.1.3.2 ,omparin!
2.1.3.3 -sin! a Boolean in a if, .hen this Boolean is null
=)ee sectio! o! casti!& !u"" to a Boo"ea!>
Boolean doit=null;
if (doit)
{ // throws NPE
if (doit != null && doit)
{ // OK
?! &e!era" =a!d this may ;e"" $e o!e of the reaso!s for that> -B"och0 recomme!ds usi!& the u!$o%ed type =i.e. $oo"ea!>
rather tha! the $o%ed type =Boo"ea!>.
2.1.# ,haracters
2.1.4.1 ,omparin!
U U does the tric5
S char is a primitive data type a Mumeric 9ata Type a"o!& ;ith Byte )hort ?!t. The UU operator ;i"" ;or5 as it ;i""
compare the ascii codes of the opera!ds a!d "et you 5!o; if they are e6ua" e%act"y as it does ;ith i!ts. T
2.1.% trin!
2.1.5.1 ,omparin!
String equals!String otherString#
As for a!y other O$8ect the UU operator ;i"" !ot achieve the desired effect R
2.1.5.2 ,hec/ if strin! is empty
if (s == null || s.length() == 0)
Ksi!& orga!achecommonslangString"tils:
isBlan#$String str%: This method is used to chec5 ;hether a stri!& is empty =VV> !u"" or ;hitespace.
isNotBlan#$String str%: This method is used to chec5 ;hether a stri!& is !ot empty =VV> !ot !u"" or !ot a ;hitespace .
isNotEm!t&$String str%: Kse this method for chec5i!& a stri!& ;hether it is !ot empty=VV> or !ot !u"".
isEm!t&$String str%: Kse this method to chec5 a stri!& for its empty =V > or !u"" va"ue.
2.1.5.1 ,onversion )$yte array+
String myString = new String(byteArray, "ISO-8859-1"));
byte[] byteArray = cipher.doFinal(myString.getBtes());
2.1.5.2 ,oncatenatin!
A$$reviated sy!ta%D
msg_action += "extra info"
Appare!t"y this is a cost"y shortcut =httpDCC;;;.rosei!dia.!etC8avatutoria"sCappe!di!&Wstri!&s.shtm">
Automatic type conversion:
(o!cate!ati!& schemesD
Class O!erator S!ee'(cost Threa' sa)e
'
)tri!& X Appare!t"y cost"y
)tri!&Buffer appe!d=> faster yes
)tri!&Bui"der appe!d=> =eve!P> faster !o =P>
2.1.5.3 trin! functions
2.1.%.".1 0ormattin!
httpDCCdo;!"oad.orac"e.comC8avaseC1.'.4CdocsCapiC8avaCuti"C7ormatter.htm"
String.for$at("(day, hour, seuil) = (%d, %d, %s)", day, hour, seuil)
2.1.%.".2 Paddin!
String stri = String.for$at("%02d", i); //Pads an integer with zeros on left to a width of 2 (01, . 09, 10.)
Other methodD
DecimalFormat df = new DecimalFormat("00");
System.out.println(df.format(x));
2.1.%."." u$strin!
String substring!int %eginIndex#
String substring!int %eginIndex& int endIndex#
2.1.%.".# Replacin!
httpDCC;;;.8avapractices.comCtopicCTopicActio!.doP?dU+4
myString.replace(oldPattern, newPattern);
3%amp"eD
String str = "babibu";
String old_str= "ba";
String new_str= "bu";
/* */ logger.debug(String.for$at("str, old_str, new_str = %s, %s, %s", str, old_str, new_str));
/* */ logger.debug("str after replace =" + str.replace(old_str, new_str));
new_str = new_str.replace("u", "i");
/* */ logger.debug(String.for$at("str, old_str, new_str = %s, %s, %s", str, old_str, new_str));
/* */ logger.debug("str after replace =" + str.replace(old_str, new_str));
OutputsD
2011-06-15 15:01:28,995 [LOGGER_FJL] DEBUG Main:subMain2(),62 - str, old_str, new_str = babibu, ba, bu
2011-06-15 15:01:28,995 [LOGGER_FJL] DEBUG Main:subMain2(),63 - str after replace =bubibu
2011-06-15 15:01:28,995 [LOGGER_FJL] DEBUG Main:subMain2(),67 - str, old_str, new_str = babibu, ba, bi
2011-06-15 15:01:28,995 [LOGGER_FJL] DEBUG Main:subMain2(),68 - str after replace =bibibu
2.1.%.".% plit
// Classes name are usually: package.subpackage.class ; get only that last bit:
String[] arr_call_class = call_class_name.split("\\.");
call_class_name= arr_call_class[arr_call_class.length - 1];
2.1.%.".1 2oin
Kse
org.apache.commons.lang.StringUtils.join(Object[] array, String separator)
or a!y other provided si&!ature.
Or if you "i5e to rei!ve!t the ;hee"D
ArrayList<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
StringBuilder sb = new StringBuilder();
for (String s : list)
{
s%.append(s);
s%.append("\t");
}
System.out.println(sb.toString());
httpDCCstac5overf"o;.comC6uestio!sC'111*1C$estG;ayGtoGco!vertGa!Garray"istGtoGaGstri!&
2.1.%.".3 Other strin! functions e&amples
*
// trim an array
for (int i = 0; i < selectors.length; i++)
{ selectors[i] = selectors[i].trim();
}
2.1.5.4 trin!$uffer
TO9O
2.1.5.5 -sin! re!e& 4re!ular e&pressions5
httpDCCdo;!"oad.orac"e.comC8avaseCtutoria"Cesse!tia"Cre&e%C
A co!ve!ie!t shortcut is $ui"t i!to the )tri!& c"assD
String regexp = "xmlns:(.*)";
if (myString.matches(regexp))
{ myString = myString.replaceAll(regexp, "$1");
3%amp"eD
private boolean isNumber(String s)
{ if (s == null || "".equals(s))
return false;
return s.$atches("[0-9]+");
}
Re&e%p ;i"dcards & patter!sD
(o!struct 9escriptio!
. A!y character $ma& or ma& not match line terminators%
Yd A di&itD -4G10
Y9 A !o!Gdi&itD -Z4G10
Ys A ;hitespace characterD - YtY!Y%4BYfYr0
Y) A !o!G;hitespace characterD -ZYs0
Y; A ;ord characterD -aG<AG[W4G10
YO A !o!G;ord characterD -ZY;0
String stringToSearch = "fe fi fo I smell";
// the pattern we want to search for
Pattern p = Pattern.compile("fi");
Matcher m = p.matcher(stringToSearch);

if (m.find())
System.out.println("match");
else
System.out.println("no match");
2.1.%.%.1 0ollo.ed $y, preceeded $y
=PRe%pr> !ot fo""o;ed $y
=PUe%pr> fo""o;ed $y
2.1.%.%.2 ,ommon re!e&es
*or +ege, Teste'- Source
Mum$ers =i!ts a!d f"oat>
=positive>
Pattern p = Pattern.co$pile("[0-9]*\\.?[0-9]+");
\es .e
Mum$ers =i!ts a!d f"oat> =P]RYZ>=G^YX>P-Yd.0XX=PR%> Mo
1
1
httpDCCstac5overf"o;.comC6uestio!sC111'*324Ce%tractGaGdou$"eGorGi!te&erGfromGaGstri!&Gusi!&Gre&u"arGe%pressio!Gi!G8ava
,
Kser!ame Z-aG<4G1WG0J31'_` Mo
Pass;ord ==PU.aYd>=PU.a-aG<0>=PU.a-AG[0>=PU.a-bc`d0>.J*24_> Mo
/e%adecima" (o"or Zc=-AG7aGf4G10J*_^-AG7aGf4G10J3_>` Mo
3mai" Z-WAG[aG<4G1G0X=YY.-WAG[aG<4G1G0X>ab-AG[aG<4G10X=YY.-AG[aG
<4G10X>a=YY.-AG[aG<0J2_>`
Mo
?ma&e 7i"e 3%te!sio! =-ZYs0X=Y.=Pi>=8p&^p!&^&if^$mp>>`> Mo
?P Address Z=-410PYYdYYdP^2-4G40YYd^2'-4G'0>YY.=-410PYYdYYdP^2-4G40YYd^2'-4G
'0>YY.
=-410PYYdYYdP^2-4G40YYd^2'-4G'0>YY.=-410PYYdYYdP^2-4G40YYd^2'-4G'0>`
Mo
Time i! 12G/our 7ormat 1-4120^-1G10>D-4G'0-4G10=YYs>P=Pi>=am^pm> Mo
Time i! 24G/our 7ormat =-410P-4G10^2-4G30>D-4G'0-4G10 Mo
9ate 7ormat =ddCmmCyyyy> 4P-1G10^-120-4G10^3-410>C=4P-1G10^1-4120>C==11^24>YYdYYd> Mo
/T.2 ta& ]=V-ZV0aV^I-ZI0aI^-ZIVH0>aH Mo
/T.2 "i!5s Mo
/T.2 a ta& =Pi>]a=-ZH0X>H=.XP>]CaH Mo
3%tract /T.2 "i!5 Ysa=Pi>hrefYsaUYsa=YV=-ZV0aYV>^I-ZI0aI^=-ZIVHYs0X>>e Mo
2.1.5.6 ,oo/$oo/
2.1.%.1.1 Pattern and matcher
/**
* Example: for sizeFactor=2
* Input: 15.2px 20.4px 22px 30px
* Output: 30.4px 40.8px 44.0px 60.0px (Tested)
*
* @param originalSetting string to be modified
* @param sizeFactor
* @return
*/
public String applySizeFactorDouble(String originalSetting, double sizeFactor)
{
Pattern p = Pattern.co$pile("[0-9]*\\.?[0-9]+"); //Look for ints or doubles
Matcher m = p.matcher(originalSetting);
StringBuffer orig = new StringBuffer();
while(m.find())
{ Double new_val = Math.round( Double.valueOf(m.group()) * sizeFactor *10 ) / 10.0d ; //
Rounding to 1 decimal
System.out.println("new_val=" + new_val);
m.appendReplacement(orig, "" + new_val);
}
m.appendTail(orig);
return orig.toString(); }
2.1.%.1.2 Remove end line from a file6te&t
String text = readFileAsString("textfile.txt");
text = text.replace("\n", "").replace("\r", "");
A"soD &etti!& the !e;"i!e )tri!& for a!y e!viro!me!t D
System.getProperty("line.separator").
2.1.1 'rrays
2.1.6.1 Declaration
Arrays have to $e i!sta!ciated =space reserved>.
int[] anArray = new int[10];
// OR:
int[] anArray;
anArray = new int[10];
// If second allocation was missing, compilation would fail:
// ArrayDemo.java:4: Variable anArray may not have been initialized.
// Non initialised array seems to be filled with default values (seems to be) 0:
System.out.println(anArray[1]); // prints: 0
// and null for an array of Strings
+
// One liner
String[] arr = new String[]{"blah", "hey", "yo"} ;
2.1.6.2 Print arrays
Arrays.toString(arr)
or
Arrays.deepToString(two_dimension_arr)
2.1.6.3 -sin! anonymous array7
3%amp"eD
createNewBlob( "-" ,
';' ,
new String[][]{ { "days-hours", "0"} },
new String[][]{ { "1","2"} }
);
2.1.6.4 8&tract a su$9array
KseD
public static void arraycopy(Object src,
int srcPos,
Object dest,
int destPos,
int length)
3%amp"eD
// Initialise copy first with correct length, arraycopy will not resize !
int [] copy = new int[aArray.length];
System.arraycopy( aArray, 0, copy, 0, aArray.length );
MoteD ;hy )ystem !ot ArraysPP #
2.1.6.5 ,ontains element:
T/0/
2.1.6.6 ,ost of callin! len!th6si;e)+ on an array6collection :
A5aD shou"d i store arr."e!&th i! a varia$"e or ca! ? ca"" arr."e!&th everytime P
-#0 a ca"" to array.length is O(1) or co!sta!t time operatio!.
)i!ce the .length is =acts "i5e> a public final mem$er of array it is !o s"o;er to access tha! a "oca" varia$"e. =?t is
very differe!t from a ca"" to a method "i5e size()>
A moder! compi"er is "i5e"y to optimi<e the ca"" to .length ri&ht out a!y;ay.
-httpDCCstac5overf"o;.comC6uestio!sC124+324C;hatGisGtheGcostGofGca""i!&GarrayG"e!&th0
?t seems for co""ectio!s the case is differe!t.
2.1.3 'ssociative arrays 4 <ap, =ashmap5
Java does !ot support associative as such $ut offers the @.apA i!terface ;hich /astha$"e imp"eme!ts.
2.1.7.1 HashMap, TreeMap, LinkedHashMap etc.
=httpDCCstac5overf"o;.comC6uestio!sC2++1,,,Cdiffere!ceG$et;ee!GhashmapG"i!5edhashmapGa!dGsortedmapGi!G8ava >
A"" three c"asses imp"eme!t the .ap i!terface a!d offer most"y the same fu!ctio!a"ity. The most importa!t differe!ce is
the order i! ;hich iteratio! throu&h the e!tries ;i"" happe!D
HashMap ma5es a$so"ute"y !o &uara!tees a$out the iteratio! order. ?t ca! =a!d ;i""> eve! cha!&e comp"ete"y
;he! !e; e"eme!ts are added.
TreeMap ;i"" iterate accordi!& to the V!atura" orderi!&V of the 5eys accordi!& to their compareTo() method
=or a! e%ter!a""y supp"ied Comparator>. Additio!a""y it imp"eme!ts the SortedMap i!terface ;hich co!tai!s
methods that depe!d o! this sort order.
LinkedHashMap ;i"" iterate i! the order i! ;hich the e!tries ;ere put i!to the map
1
V/ashta$"eV is the &e!eric !ame for hashG$ased maps. ?! the co!te%t of the Java AP? Hashtable is a! o$so"ete c"ass
from the days of Java 1.1 $efore the co""ectio!s frame;or5 e%isted. ?t shou"d !ot $e used a!ymore
2.1.7.2 Declaration
// Map is an interface
Map<Integer,String> hTable = new Hashtable<Integer,String>(); // DEPRECATED
Map<String, Object> map = new HashMap<String, Object>();
// Using Hashtable // DEPRECATED
Hashtable<Integer,String> hTable = new Hashtable<Integer,String>();
// TreeMap is a sorted map
// Inline declaration using an 'unnamed block'
TreeMap<Integer, String> inputMaxCapacityValues = new TreeMap<Integer, String>()
{ //Unnamed Block.
{ put(1, "1 port");
put(2, "2 ports");
put(3, "3 ports");
}
};
// Here we want to build an ArrayList of Hashmaps (that contain only one pair of key=>value
final HashMap<String, String> hm_1= new HashMap<String, String>()
{ {put("1", "Salle attente 1");
}
}
ArrayList<HashMap<String, String>> listSalleAttente = new ArrayList<HashMap<String, String>>()
{ {add(hm_1); // To be able to add the
add(hm_2); // hashmaps in that way,
add(hm_3); // they have to be `final'
}
};
TO9OD compare /ashmap hashta$"e treemap
2.1.7.3 'ddin! or settin! items
hTable.put(new Integer(2), "Two");
hTable.put(new Integer(1), "One");
hTable.put(new Integer(4), "Four");
hTable.put(new Integer(3), "Three");
hTable.put(new Integer(5), "Five");
2.1.7.4 ,hec/in! if contains !iven /ey or !iven value
hashmap.containsKey(
hashmap.containsValue(
2.1.7.5 >ettin! the set of /eys7 /eyset)+
Oi"" the 5eys $e retur!ed i! the order they appear i! the map P =e.&. if the map is a 2i!5ed/ash.ap ;ere e"eme!ts
appear i! the order they ;ere i!serted ;i"" map.5ey)et=> retur! the 5eys i! that same order P i.e. order of i!sertio!>
Appare!t"y yesD
httpDCCstac5overf"o;.comC6uestio!sC34,+4*1CdoesG8avasG"i!5edhashmapGmai!tai!GtheGorderGofG5eys
2.1.7.6 ?oopin! throu!h
// METHOD 1: Get Hashtable Enumeration to get key and value
Enumeration em=hTable.keys(); // does not work with Map
while(em.hasMoreElements())
{
//nextElement is used to get key of Hashtable
int key = (Integer)em.nextElement();
//get is used to get value of key in Hashtable
String value=(String)hTable.get(key);
System.out.println("Key:"+key+" value:"+value);
}
// METHOD 2: using an iterator:
Set s = hTable.entrySet(); // works with Map
Iterator i=s.iterator();
14
while(i.hasNext())
{
Map.Entry m=(Map.Entry)i.next();
int key = (Integer)m.getKey();
String value=(String)m.getValue();
System.out.println("Key:"+key+" value:"+value);
}
// METHOD 3: Map -> Set -> Iterator -> Map.Entry -> troublesome
Iterator iterator=map.entrySet().iterator();
while(iterator.hasNext())
{
Map.Entry mapEntry=(Map.Entry)iterator.next();
System.out.println("Key: "+ mapEntry.getKey() + ", value:"+ mapEntry.getValue());
}
l
// METHOD 4: more elegant way
for (Map.Entry<String, String> entry: map.entrySet())
{
System.out.println("Key: " + entry.getKey() + " Value: " + entry.getValue());
}
// METHOD 5: weird way, but works anyway
for (Object key: map.keySet())
{
System.out.println("Key: " + key.toString() + " Value: " + map.get(key));
}
.ore e%amp"esD
for (Map.Entry<?, ?> e : map.entrSet())
{ o = e.get'alue();
System.out.println("object for key:" + e.get(e() +
" is of class: " + o.getClass().getCanonical)a$e() +
" and value: " + o.toString()
}
2.1.7.7 ,onvert seriali;ed list to map list
httpDCCi""e&a"ar&ume!te%ceptio!.$"o&spot.comC2441C4'C8avaGusi!&G%pathG;ithG!amespacesGa!d.htm" =courtesy of>
private static Map<String, String> toMap(String... mappingPairs)
{
Map<String, String> prefixMappings = new HashMap<String, String>(mappingPairs.length / 2);
for (int i = 0; i < mappingPairs.length; i++)
{ prefixMappings.put(mappingPairs[i], mappingPairs[++i]);
}
return prefixMappings;
}
2.1.7.8 Reverse loo/up7
httpDCCstac5overf"o;.comC6uestio!sC13+3,1,C8avaGhashmapGho;GtoG&etG5eyGfromGva"ue
G 3ither use a! apache commo!s "i$rary
G OrD
public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {
Set<T> keys = new HashSet<T>();
for (Entry<T, E> entry : map.entrySet()) {
if (entry.getValue().equals(value)) {
keys.add(entry.getKey());
}
}
return keys;
}
2.1.7.9 ,opy arrays
httpDCC;;;.8avapractices.comCtopicCTopicActio!.doP?dU3
int [] copy = new int[aArray.length];
System.arraycopy( aArray, 0, copy, 0, aArray.length );
11
// ...or:
int[] copy = Arrays.copyOf(aArray, aArray.length);
// ...or:
int[] copy = (int[])aArray.clone();
OARM?M: R c"o!e=> method does !ot seem to ;or5 o! mu"ti dime!sio!a" arrays
@A clone of a mu"tidime!sio!a" array is sha""o; ;hich is to say that it creates o!"y a si!&"e !e; array. )u$arrays are
shared. T
2.1.@ ?ists
List<TypeAnnee> list_ret =new ArrayList<TypeAnnee>();
list_ret.add(a);
TypeAnnee[] arr_ret = (TypeAnnee[]) list_ret.toArray(new TypeAnnee[0]);
private List<TypeMois> populateMoisFutur = Arrays.asList(TypeMois.values());
2.1.8.1 Anitialisin!, accessin!
// Create new list of (here,) strings:
ArrayList<String> list = new ArrayList<String>();
// or create a fixed-size list initialized to contain several elements:
List stooges = Arrays.asList("Larry", "Moe", "Curly");
// or create one from an array:
String[] arr = {"Larry", "Moe", "Curly"};
List list2 = Arrays.asList(arr);
// Here list2 is backed by the specified array. (Changes to the returned list "write through" to the array.)
@The Arrays c"ass has a static factory method ca""ed asList ;hich a""o;s a! array to $e vie;ed as a List. This
method does !ot copy the array. (ha!&es i! the List ;rite throu&h to the array a!d vice versa. The resu"ti!& 2ist is !ot
a &e!era"Gpurpose List imp"eme!tatio! $ecause it does!It imp"eme!t the =optio!a"> add a!d remove operatio!sD
Arrays are !ot resi<a$"e.A
// Benefit from the list functions such as add() (adds at end):
list.add(my_str);
// Convert (back) to array. The param of toArray is used only to indicate the type of the array:
String[] str_arr = list.toArray(new String[0]);
// or if list was created through Arrays.asList, use input array directly
2.1.8.2 ,ontains)+
(arefu"R Re"ies o! O$8ect.e6ua"s=> a!d this "atter @i$ple$ents the $ost discri$inating possi%le equivalence
relation on o%*ects+ that is& for an non,null reference values x and & this $ethod returns true
if and onl if x and refer to the sa$e o%*ectA
i.e. "ist.co!tai!s=o$8> ;i"" retur! true o!"y if "ist co!tai!s actua" o$8 a!d !ot a @va"ueG@simi"ar.
)ee a"soD
httpDCC;;;.e%amp"edepot.comCe&sC8ava.uti"Cco""W:etArray7romVector.htm"
2.1.8.3 ,ost of callin! si;e)+
Vs ca""i!& o!ce a!d stori!& i! a "oca" varia$"e.
)ee simi"ar sectio! i! sectio! o! arrays.
2.1.8.4 ,onvertin! ?ists6,ollections to arrays
// Fixed-size list
List list = Arrays.asList(array);
// Growable list
list = new LinkedList(Arrays.asList(array));
// Duplicate elements are discarded
Set set = new HashSet(Arrays.asList(array));
12
2.1.8.5 Operations on lists 40ilterin!, remove, sort, matcher, searcher 5
--.e$ove all null values in a list/
excp0asList.re$oveAll(Collections.singletonList(null));
)orti!& co""ectio! of o$8ectsD )ee 7J2 -matcher searcher0
2.1.8.6 Prepend
T/0/
3%amp"e of ho; that ;as achieved o! a c"ass e%te!di!& struts2Fs Actio!)upportD usi!& Collections.rotate
private void prependActionError(String err)
{
this.addActionError(err);
List<String> action_errors = (List<String>) this.getActionErrors();
// It seems that ActionSupport's collection of errors is ordered
// (otherwise we wouldn't be needing this present function !): they appear ordered on the page when
// flushed
// So it seems legitimate to assume it's a List
Collections.rotate(action_errors, 1); // Last element will become first
this.setActionErrors(action_errors);
}
2.1.8.7 Other utilities
httpDCCdocs.orac"e.comC8avaseC1.'.4CdocsCapiC8avaCuti"C(o""ectio!s.htm"
2.1.8.8 Bor/in! .ith lists7 e&amples )to sort out+
private Set excludeActions = Collections.E12345SE3;
this.excludeActions = TextParseUtil.commaDelimitedStringToSet(values);
// Remove a sublist from a list:
// Sublist to be removed:
List<?> listToBeRemoved = new ArraList<?>();
// Go through list and "mark" (i.e. put in sublist to be removed) all elements that satisfy some criteria:
for (? elm: list)
{ if ( criteria .)
{ listToBeRemoved.add(elm);
}
}
list.re$oveAll(listToBeRemoved);
2.1.C 8nums, creatin! a custom type.
2.1.9.1 8num
2.1.C.1.1 8&ample7
public enum TypeMois
{
// NB: it seems the enum `main' value can't be an int.
// For years we would have to write:
// A56777 ("A_2000", "2000", "2000"),
// A56778 ("A_2001", "2001", "2001"),
// A56776 ("A_2002", "2002", "2002"), .
9A)'IE. ("JANVIER" , "01", "Janvier" , "01" , 1),
FE'.IE. ("FEVRIER" , "02", "Fvrier" , "02" , 2),
1A.S ("MARS" , "03", "Mars" , "03" , 3),
A'.IL ("AVRIL" , "04", "Avril" , "04" , 4),
1AI ("MAI" , "05", "Mai" , "05" , 5),
9:I) ("JUIN" , "06", "Juin" , "06" , 6),
9:ILLE3 ("JUILLET" , "07", "Juillet" , "07" , 7),
AO:3 ("AOUT" , "08", "Aot" , "08" , 8),
SE23E1B.E ("SEPTEMBRE", "09", "Septembre", "09" , 9),
OC3OB.E ("OCTOBRE" , "10", "Octobre" , "10" , 10),
)O'E1B.E ("NOVEMBRE" , "11", "Novembre" , "11" , 11),
0ECE1B.E ("DECEMBRE" , "12", "Dcembre" , "12" , 12);
private final String id;
private final String valueNumeral;
private final String valueName;
private final String valueDb;
13
private final int valueInt;
// This constructor is used by Java to build the type
TypeMois(String id, String valueNumeral, String valueName, String valueDb, int valueInt)
{
this.id = id;
this.valueNumeral = valueNumeral;
this.valueName = valueName;
this.valueDb = valueDb;
this.valueInt = valueInt;
}
public String getId()
{ return id;
}
public String getValue() {
return this.getValueName();
}
public String getValueNumeral()
{ return valueNumeral;
}
// etc.
}
// Values as array:
TypeMois[] arrTypeMois = TypeMois.values() ;
// Values as list:
List<TypeMois> inputMoisValues = Arrays.asList(TypeMois.values());
// Checking if is of type:
if ( ! (this.inputAnnee instanceof TypeAnnee)) {// Throw exception
// Setting a variable ot type TypeMois:
private TypeMois inputMois ;
public void setInputMois(String inputMois)
{ this.inputMois = TypeMois.valueOf(inputMois);
}
3%amp"e 2D
private enum TypeRendering { 33S, WA' };
private TypeRendering type;
public boolean isTypeRendering(TypeRendering t)
{ return t.equals(this.type);
}
public boolean isWav()
{ return isTypeRendering(TypeRendering.WA');
}
3%amp"e 3D
public enum TypeApplicationValues
{
// id , value possibly taken by field "typeApplication"
ACC:EIL ("ACCUEIL" , "ACCUEIL" ),
A335CO12 ("ATT_COMP" , "ATT_COMP" ),
A335E0F ("ATT_EDF" , "ATT_EDF" ),
A335LCA ("ATT_LCA" , "ATT_LCA" ),
A335SCO. ("ATT_SCOR" , "ATT_SCOR" ),
A:.53LF ("AUR_TLF" , "AUR_TLF" ),
0ISS:ASIO)5FE.158 ("DISSUASION_FERM_1" , "DISSUASION_FERM_1" ),
0ISS:ASIO)5)O5A;E)3 ("DISSUASION_NO_AGENT", "DISSUASION_NO_AGENT"),
0ISS:ASIO)5CO)F ("DISSUASION_CONF" , "DISSUASION_CONF" ),
0ISS:ASIO)52AS5E0F ("DISSUASION_PAS_EDF" , "DISSUASION_PAS_EDF" ),
E'E)35FL:< ("EVENT_FLUX" , "EVENT_FLUX" ),
E'E)51ESS5;E) ("EVEN_MESS_GEN" , "EVENT_NAT" ),
EW3 ("EWT" , "EWT" ),
I)CO. ("INCOR" , "INCOR" ),
1E):51ES ("MENU_MES" , "MENU_MES" ),
1E):5.ECLA ("MENU_RECLA" , "MENU_RECLA" ),
1E):5S3ICA' ("MENU_STICAV" , "MENU_STICAV" ),
1E):5S3IH)O ("MENU_STIHNO" , "MENU_STIHNO" ),
2A:SE ("PAUSE" , "PAUSE" ),
.ECO.0 ("RECORD" , "RECORD" ),
SAISI5C2 ("SAISI_CP" , "SAISI_CP" );
private final String id;
private final String valueDb;
public String getId()
14
{ return id;
}
public String getValueDb()
{ return this.valueDb;
}
/**
* Internal (This constructor is used by Java to build the type)
*/
TypeApplicationValues(String id, String valueDb)
{ this.id = id;
this.valueDb = valueDb;
}
/**
* The values as a list for easy manipulation
*/
private static List<TypeApplicationValues> list'alues=Arrays.asList(TypeApplicationValues.values());
/**
* Get the TypeApplicationValues corresponding to the passed valueDb
* If several matches, return the first.
* @param valueDB
* @return
* @throws DataAccessWrongFormatException
*/
public static TypeApplicationValues forValueDb(String valueDb)
{ for (TypeApplicationValues val : list'alues)
{ if (val.getValueDb().equals(valueDb))
{ return val;
}
}
String err_msg = "Passed value (" + valueDb +") is not an authorised value for field
typeApplication' (in ApplicationDTO)";
throw new DataAccessWrongFormatException(err_msg); // Runtime exception
}
}
Example
public static enum DayOfWeek
{ 1O) (Calendar.1O)0A4 ),
3:E (Calendar.3:ES0A4 ),
WE0 (Calendar.WE0)ES0A4),
3H: (Calendar.3H:.S0A4 ),
F.I (Calendar.F.I0A4 ),
SA3 (Calendar.SA3:.0A4 ),
S:) (Calendar.S:)0A4 );
private final int intValue;
private DayOfWeek(int int_val)
{ this.intValue = int_val;
}
public int getValueInt()
{ return intValue;
}
}
2.1.C.1.1.1 <ap enum6value
public enum ETypeTheme
{
2:.E ( "pure" ),
ELAS3IC ( "elastic" ),
C.4S3AL ( "crystal" );
/**
* Value for that type, in database
*/
private final String value;
public String getValue() { return value; }
// This constructor is used by Java to build the type
ETypeTheme(String value)
{ this.value = value;
}
/**
* Return the map of {ETypeTheme, associated value}
* @return
*/
1'
public static Map<ETypeTheme, String> getMapEnumValue()
{ Map<ETypeTheme, String> ret = new Hash1ap<ETypeTheme, String>();
for (ETypeTheme e : ETypeTheme.values())
{ ret.put(e, e.get'alue());
}
return ret;
}
T/0/ 1uestions
(a! you pass !u"" i! "ieu of a e!um type P
2.1.C.1.2 The specs
A"" e!ums imp"icit"y e%te!d 8ava."a!&.3!um. )i!ce Java does !ot support mu"tip"e i!herita!ce a! e!um ca!!ot e%te!d
a!ythi!& e"se
A! e!um type has !o i!sta!ces other tha! those defi!ed $y its e!um co!sta!ts.
?t is a compi"eGtime error to attempt to e%p"icit"y i!sta!tiate a! e!um type. The final clone method i! Enum e!sures
that enum co!sta!ts ca! !ever $e c"o!ed a!d the specia" treatme!t $y the seria"i<atio! mecha!ism e!sures that dup"icate
i!sta!ces are !ever created as a resu"t of deseria"i<atio!. Ref"ective i!sta!tiatio! of e!um types is prohi$ited. To&ether these
four thi!&s e!sure that !o i!sta!ces of a! enum type e%ist $eyo!d those defi!ed $y the enum co!sta!ts.
Because there is o!"y o!e i!sta!ce of each enum co!sta!t it is permissi$"e to use the ==operator i! p"ace of
the equals method ;he! compari!& t;o o$8ect refere!ces if it is 5!o;! that at "east o!e of them refers to
a! enum co!sta!t. =The equals method i! Enumis a final method that mere"y i!vo5es super.equals o! its ar&ume!t
a!d retur!s the resu"t thus performi!& a! ide!tity compariso!.>
-httpDCC8ava.su!.comCdocsC$oo5sC8"sCthirdWeditio!Chtm"Cc"asses.htm"c+.10
/e!ceD
2.1.C.1." 8&tendin! an enum
3!ums are not e,ten'able =!or overrida$"e>. They are fi!a". ?! cases ;here that ;ou"d $e re6uired =a"thou&h use ;ith
careD @e!ums are supposed to $e a set of set va"ues 5!o;! to every$ody $"a $"a $"aA> see the @typeGsafe e!umeratio!A
patter!.
2.1.C.1.# ,omparin! enums i.e. eDuality
9erivi!& from the specificatio!sI e%tracts "isted i! a! a$ove sectio!D using .. is o#
)ee a"soD httpDCCstac5overf"o;.comC6uestio!sC1,'443'Ccompari!&G8avaGe!umGmem$ersGorGe6ua"s
2.1.C.1.% Reverse loo/up
A"ready sho;! i! o!e of the e%amp"es a$ove. /ere is a!other ;ayD
public enum Status
{
WAI3I);(0),
.EA04(1),
S(I22E0(-1),
CO12LE3E0(5);
private int code;
public int getCode() { return code; }
// This constructor is used by Java to build the type
private Status(int code) { this.code = code; }
// ===============================================================
// REVERSE LOOKUP
// ===============================================================
private static final Map<Integer,Status> loo=up = new HashMap<Integer,Status>();
static { for(Status s : EnumSet.allOf(Status.class))
{ loo=up.put(s.getCode(), s);
}
1*
}
/**
* Reverse lookup: get a Status from its code
*/
public static Status get(int code) { return loo=up.get(code); }
}
The static $"oc5 to popu"ate the Map uses a specia"i<ed imp"eme!tatio! of Set java.util.EnumSet that
Vpro$a$"yV =accordi!& to the 8avadocs> has $etter performa!ce tha! java.util.HashSet. Java '.4 a"so provides
java.util.EnumMap a specia"i<ed imp"eme!tatio! of Map for e!umeratio!s that is more compact tha!
java.util.HashMap..
)ee a"soD httpDCCstac5overf"o;.comC6uestio!sC'212,14Cco!vertGi!te&erGva"ueGtoGmatchi!&G8avaGe!um
A!other ;ay is to use
3!um.va"ueof=)tri!& ]!ame of the e!um va"ueH
)eeD httpDCCdocs.orac"e.comC8avaseC*CdocsCapiC8avaC"a!&C3!um.htm"
3%amp"eD
2.1.C.1.1 Reverse loo/up outside of the enum )enum utility6helper class+
/**
* Return the enum value for which the passed field equals the passed value.
* If several matches are possible will return one of the matches (no garantee as to which).
* The enum class should make the searched field public or provide a getter method, of type
* {@code getField, i.e. "get" + capitalize(field)}.
* Note: the lookup mechanism uses reflection.
* Note: the equality check between the passed value and the values of the passed field of all the
* possible enum values is is done through equal(). If using "exotic" types, make sure equal() is
* overridden.
*
* Example:
* Given the following enum:
* <pre>{@code
* public enum BookGenre
* {
* FICTION (1),
* NON_FICTION (2),
* TRAVEL (3),
* CHILDREN (4),
* REFERENCE (5),
* COMIC (6);
*
* private int valueDb ; // value in DataBase
*
* // Internal constructor (used by Java to build these types)
* BookGenre(int valueDb)
* {
* this.valueDb = valueDb;
* }
*
* public int getValueDb()
* { return valueDb;
* }
*
* }</pre>
*
* the following calls:
<br />
*
* <pre>{@code
* BookGenre genre = lookup(BookGenre.class, "valueDb", 1);
* System.out.println("genre is: " + genre);
*
* genre = lookup(BookGenre.class, "valueDb", 2);
* System.out.println("genre is: " + genre);
*
* genre = lookup(BookGenre.class, "valueDb", 5);
* System.out.println("genre is: " + genre);
*
* genre = lookup(BookGenre.class, "valueDb", "yo");
* System.out.println("genre is: " + genre);
* }</pre>
*
* will yield:
*
1,
* <pre>{@code
* genre is: FICTION
* genre is: NON_FICTION
* genre is: REFERENCE
* Exception in thread "main" java.lang.IllegalArgumentException: Could not find the requested enum of type
{common.Runnable_Test$BookGenre} with the field {valueDb} equal to the value {yo}. Reason: looped through all
enum values and could not find a match.
* at common.Runnable_Test.lookup(Runnable_Test.java:252)
* at common.Runnable_Test.test_5(Runnable_Test.java:86)
* at common.Runnable_Test.main(Runnable_Test.java:26)
* }</pre>
*
* If the field is not accessible (e.g. private) and no accessor is accessible either, the following exception
will occur: <br />
*
* <pre>{@code
* Exception in thread "main" java.lang.IllegalArgumentException: Could not find the requested enum of type
{common.Runnable_Test$BookGenre} with the field {valueDb} equal to the value {1}. Reason: failed to access
field directly, so tried to access it through getter method {getValueDb}, but this getter seems not to be
defined, please add it to the enum class.
* at common.Runnable_Test.lookup(Runnable_Test.java:247)
* at common.Runnable_Test.test_5(Runnable_Test.java:77)
* at common.Runnable_Test.main(Runnable_Test.java:26)
* Caused by: java.lang.NoSuchMethodException: common.Runnable_Test$BookGenre.getValueDb()
* at java.lang.Class.getDeclaredMethod(Class.java:1909)
* at common.Runnable_Test.lookup(Runnable_Test.java:234)
* ... 2 more
* }</pre>
*
*
* @param <E>
* @param e
* @param field
* @param value
* @return the enum value
* @throws IllegalArgumentException field is either not defined, accessible (directly or through getter
method), or no enum value
* with this field equal to the passed value exists.
* @author francois hill
* @since 2012.08.24
*
*/
public static <E extends Enum<E>> E lookup(Class<E> e, String field, Object value)
{
String err_msg = "Could not find the requested enum of type {" + e.get)a$e() + "} with the field {" +
field + "} equal to the value {" + value.toString() + "}. ";
Object val = null;
Method m = null;
for(E s : EnumSet.allOf(e))
{ Field f;
/* */ try
/* */ {
f = e.get0eclaredField(field);
val = f.get(s);
/* */ }
/* */ catch (Exception e4)
/* */ {
/* */ String getter_name = "get" + StringUtils.capitali>e(field);
/* */ String err_msg_2 = "Reason: failed to access field directly, so tried to
access it through getter method {" + getter_name + "}";
/* */ try
/* */ {
// The field is not public. Try with a getter method instead:
m = e.get0eclared1ethod(getter_name);
val = m.invo=e(s);
/* */ }
/* */ // This time, there's nothing much else we can do other than fail
/* */ catch (SecurityException e5)
/* */ {
/* */ err_msg = err_msg + err_msg_2 + ", but access was denied too.
Please make either field or getter public.";
/* */ throw new IllegalArgu$entException(err_msg, e5);
/* */ }
/* */ catch (NoSuchMethodException e6)
/* */ {
/* */ err_msg = err_msg + err_msg_2 + ", but this getter seems not to
be defined, please add it to the enum class.";
/* */ throw new IllegalArgu$entException(err_msg, e6);
/* */ }
1+
/* */ catch (IllegalAccessException e7)
/* */ {
/* */ err_msg = err_msg + err_msg_2 + ", but access was denied too.
Please make either field or getter public.";
/* */ throw new IllegalArgu$entException(err_msg, e7);
/* */ }
/* */ catch (Exception e8)
/* */ {
/* */ err_msg += ", but an exception was encountered.";
/* */ throw new IllegalArgu$entException(err_msg, e8);
/* */ }
/* */ }
if (val.equals(value))
{ return s;
}
}
err_msg += "Reason: looped through all enum values and could not find a match. Is the passed value of
the right type ?";
throw new IllegalArgu$entException(err_msg);
}
2.1.C.1.3 >ettin! a i1@n la$el from a resource $undle
/**
* Return a localized text value associated to the passed enum value of the passed enum type.
*
* The associated text values are classically looked up in resource bundles associated to the enum
* type.
* Example: if the enum type is com.my.BookGenre.java, then the bundle is com.my.BookGenre and the
* following * properties files are looked up:
* com/my/BookGenre_en.properties,
* com/my/BookGenre_fr.properties,
* com/my/BookGenre_de.properties,
* etc.
*
* Given the following enum:
* <pre>{@code
* public enum BookGenre
* {
* FICTION (1),
* NON_FICTION (2),
* TRAVEL (3),
* CHILDREN (4),
* REFERENCE (5),
* COMIC (6);
*
* private int valueDb ; // value in DataBase
*
* // Internal constructor (used by Java to build these types)
* BookGenre(int valueDb)
* {
* this.valueDb = valueDb;
* }
*
* public int getValueDb()
* { return valueDb;
* }
*
* }</pre>
*
* the resource bundle for the French language could be:
* <pre>{@code
* FICTION = Fiction
* NON_FICTION = Documentaire
* TRAVEL = Voyages
* CHILDREN = Enfants
* REFERENCE = Rfrence
* COMIC = Bande Dessine
*
* }</pre>
*
* If no resource bundle can be located then the string value of the enum value will be returned.
*
* @param etype class of enum type
* @param value
* @return
*/
public static <E extends Enum<E>> String getTet(Class<E> etype, E value, Locale locale)
{
String enum_pckg_name = etype.getClass().getCanonical)a$e();
String enum_value_str = value.toString();
String result = enum_value_str;
11
/* */ try
/* */ {
ResourceBundle res_bundle = java.util.ResourceBundle.getBundle(enum_pckg_name, locale);
result = res_bundle.getString(enum_value_str);
/* */ }
/* */ catch (MissingResourceException e)
/* */ { // !"!: log warning
/* */
/* */ }
return result;
}
2.1.9.2 The type9safe enumeration pattern
This ;as the patter! used to emu"ate e!ums i! prior versio!s of Java devoid of e!umD
public final class Suit
{
private Suit() {}
public static final Suit S2A0ES = new Suit();
public static final Suit HEA.3S = new Suit();
public static final Suit 0IA1O)0S = new Suit();
public static final Suit CL:BS = new Suit();
}
)i!ce these e!umeratio! i!sta!ces are a"" effective"y si!&"eto!s they ca! $e compared for e6ua"ity usi!& ide!tity =VU
UV>.
2.2 Operators & constructs
2.2.1 ,omparison, chec/in! for eDuality, nullity
The U U operator chec5s to see if t;o o$8ects are e,actl& the same Object.
Kse .equals to chec5 if t;o O$8ects are logicall& e6ua"
(hec5i!& !u""ityD
if (object == null) {
)tri!&sD
if (s == t) // Legal, but usually WRONG.
if (s.equals(t)) // RIGHT
if (s > t) // ILLEGAL
if (s.compareTo(t) > 0) // CORRECT>
)ee sectio! TypeC)tri!&s for more i!fo
2.2.1.1 0urther7 EE vs eDuals
== !ever thro;s Mu""Poi!ter3%ceptio!
== is su$8ect to type compati$i"ity chec5 at compi"e timeD
enum Color { BLACK, WHITE };
enum Ciral { LE!T, "I#HT };
if $Color.BLACK.equals$Ciral.LE!T%%; && compiles fine
if $Color.BLACK == Ciral.LE!T%; && '(E)*+T C(,-ILE... Incompa/i0le /1pes.
/o;ever == is su$8ect to the typi!& $"u!derD if =a U $>
?f a! immuta$"e c"ass that has proper co!tro" over its i!sta!ces ca! &uara!tee to its c"ie!ts that ==is usa$"e the!
-B"och0 itFs $etter to use == =@i!creased performa!cesA>
2.2.2 ?oops
Brea5i!& "oopD $rea5 httpDCCdo;!"oad.orac"e.comC8avaseCtutoria"C8avaC!utsa!d$o"tsC$ra!ch.htm"
2.2." 0oreach loop
for (String[] line : my_two_dim_str_array)
{ print(line) .
}
24
2.2.# Ternary operator
2.2.4.1 (ested ternary
httpDCC;;;.codera!ch.comCtC44+'24C8avaC8avaCTer!aryGoperatorGifGe"seifGe"se
MoticeD appare!t"y the !ested ter!ary operator is eva"uated @starti!& from the e!dA.
2." 'dvanced types & o$Fects
2.".1 Date, ,alendar
!e; 9ate=> is deprecated
3%amp"esD
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
-- ;et current date ti$e with 0ate!# 0E2.ECA3E0
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
System.out.println(dateFormat.format(date));

-- ;et current date ti$e with Calendar!#
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Calendar cal = Calendar.getInstance();
System.out.println(dateFormat.format(cal.getTime()));

-- 0efine a date& using a ;regorian calendar
GregorianCalendar gregCalendar = new GregorianCalendar();
gregCalendar.set(2020, 12, 25);
? @ gregCalendar.getTime();
-- 0ifference %etween 6 dates/ define a date& using a ;regorian calendar
Date today = new Date(); // DEPRECATED
// Get msec from each, and subtract. -> difference is in milliseconds:
long diff = today.getTime() - other_date.getTime();
2.# 'dvanced constructs
TO9O
2.#.1 >eneric types
2.#.2 ?ist of parameters of un/no.n si;e )+
3%amp"eD this
public NamespaceContextMap(Map<String, String> prefixMappings)
{ prefixMap = createPrefixMap(prefixMappings);
nsMap = createNamespaceMap(prefixMap);
}
ca! a"so $e ;ritte!D
/**
* Convenience constructor.
*
* @param mappingPairs pairs of prefix-namespaceURI values
*/
public NamespaceContextMap(String... mappingPairs)
{ this(toMap(mappingPairs));
}
21
2.% Basic arithmetics
=httpDCCmi!dprod.comC8&"ossCdivisio!.htm">
// sample divisions
int i = 7;
int * = 2;
int = = i / *; // gives 3
double d = (double) i / (double) *; // gives 3.5
double oops = (double) ( i / * ); // gives 3.0
double shortcut = ((double) i ) / *; // gives 3.5, j is promoted to double automatically.
double surprise = 1.0d / 10.0d; // gives approximately 0.1.
// 0.1 is a binary repeater fraction.
" ,lasses & o$Fects
".1 <odifiers )access, final +
/ccess Levels
0o'i)ier Class 1ac#age Subclass 2orl'
public
\ \ \ \
protected
\ \ \ M
no modifier \ \ M M
private
\ M M M
".1.1 0inal
/ttribute
ca!!ot $e cha!&ed =if itFs a refere!ce the refere!ced o$8ect ca! of course $ut !ot the refere!ce>
)eems it ca! $e overridde! =Vhidde!V i! the terms of the 8ava docume!tatio!> thou&h.
0etho'
ca!!ot $e redefi!ed =overridde!>
Class
ca!!ot $e e%te!ded
".2 0ields 4attri$utes5
".2.1 Antiali;in! fields
)ee 8avadoc
".2.2 tatic fields
)tatic ca""s are reso"ved at com!ile time
)tatic fie"dsCmethods ca!!ot $e overri''en =technicall& &es compi"er 3on4t com!lain $ut the po"ymorphism
e%pected ;i"" !ot happe! =see that sectio!>>.
)tatic fie"dsCmethods ca!!ot $e abstract
3%amp"e of a p"ace ;here static ;as!It 8ust e!ou&hD
//#/**
//# * To be redefined in extending classes
//# *
//# * Here we choose to make this field static.
//# *
//# * DESIGN NOTE:
//# * It is debatable whether to make this field static or not.
//# * Static fields are computed at compile time and not runtime, and since we will be relying on
//# * polymorphism subtyping (i.e. manipulating the parent class at compile time and getting the
//# * exact subclass at runtime), in several places notably in the list of plugins in class BaseACT,
//# * (this list is typed with the parent plugin class, and is fed with plugins which are
//# * dynamically injected by spring with appropriate subtype).
//# *
//# * If this field were made static, we would have to redefine both this filed and its getter in
extending classes.
//# * If we make it non-static, we only need redefine this field.
//# * However, this means we wouldn't be able to do such stuff as:
//# * PluginSubclass.PLUGIN_NAME
22
//# * Instead we would have to do something like:
//# * new PluginSubclass().getPluginName()
//# *
//# * @deprecated
//# */
//#public static String PLUGIN_NAME = "TO_BE_REDEFINED_IN_EXTENDING_PLUGINS";
private String plugin)a$e;
/**
* Return canonical name of plugin
* Note: on making this function static, see comment above.
*/
public String get!luginName()
{ if (plugin)a$e == null)
{ plugin)a$e = PluginSupport.get2lugin)a$e(this);
}
return plugin)a$e;
}
"." <ethods
".".1 Overloadin! a method
http://docs.oracle.com/!avase/tutorial/!ava/!ava///methods.html
B"och item 41D @Kse over"oadi!& 8udicious"yA
o The choice o) 3hich overloa'ing to invo#e is ma'e at com!ile time =;hereas the choice $et;ee!
overri''en methods is made dy!amica""y>
o / sa)e5 conservative !olic& is never to o))er t3o overloa'ings 3ith the same number o)
!arameters
o Offeri!& t;o over"oadi!&s is pro$a$"y o5 if they are u!"i5e"y to co!fuse the user. 3%D o!e si&!ature ;ith
int a!other ;ith Collection.
o (arefu" ;ith &e!erics auto$o%i!&
".".2 Overloadin! a method .ith su$type parameters
The choice of the actua" fu!ctio! used is made at compi"e time.
?f severa" si&!atures match the ca""ed fu!ctio! the most VspecificV si&!ature &ets chose!.
?f the compi"er ca!It decide a! error ;i""=mi&htP> $e firedD Vca"" to # is am$i&uous#V
The Java specificatio!s o! thisD httpDCCdocs.orac"e.comC8avaseCspecsC8"sCse'.4Chtm"Ce%pressio!s.htm"c1'.12.2
(hoosi!& ;hat over"oaded method shou"d $e used ;he! usi!& !u"".
1. A&ai! the most specific fu!ctio! &ets chose!
2. ?t is possi$"e a!y;ay to cast !u"" to the type of the desired fu!ctio!.
".# >et name of class
// Method 1: static. (Equivalent to PHP's __CLASS__)
// Drawback: actual name of class is written in the code
NameOfClass.class
// Method 2: Compile time ("static") class: (Equivalent to PHP's __CLASS__) (DOUBLE CHECK THAT !!)
String class_compiletime = Thread.currentThread().getStackTrace()[1].getClassName(); // Runtime
// Method 3: "dynamic" class: (Equivalent to PHP's get_class($this)):
String class_runtime = this.getClass().getName();
// Equivalent to PHP's __FUNCTION__
String method = Thread.currentThread().getStackTrace()[1].getMethodName();
23
".#.1 ,hec/ if 2 o$Fects are of the same class
Beyo!d the 6uestio! ;hether itIs a &ood thi!& or !ot to $ase o!eIs code o! such a test
2
classAInstance.getClass().equals(classBInstance.getClass());
".% ,lass constructors
?f a c"ass has !o co!structor Java i!serts the imp"icit fo""o;i!& co!structorD
public MyClass() { super(); }
?f a c"ass defi!es a co!structor =;ith or ;ithout ar&ume!ts> this imp"icit empty co!tructor is !ot i!serted. ?f !eeded it
;i"" therefore have to $e e%p"icit"y dec"ared.
".%.1 ,allin! constructor from another constructor
public DOMDocument() throws DOMDocumentBuildException
{ this.DOMDocumentSub(false, true);
}
public DOMDocument(boolean set_validating, boolean namespace_aware) throws DOMDocumentBuildException
{ this.DOMDocumentSub(set_validating, namespace_aware);
}
public DOMDocument(String xml_file) throws DOMDocumentBuildException
{ this();
}
This is o!"y possi$"e from ;ithi! a co!structor. (a""i!& a co!structor ;ith this=> i!side a fu!ctio! ;i"" fai".
".1 Other $uildin! patterns
The $ui"der patter!
)ee B"och ?tem 2
3%amp"e of useD $ui"der ;ith o!"y optio!a" paramsD
public class PainterBackground extends Painter
{
private Boolean fill = null;
private ETypeColorSet colorSet = null;
private ETypeColorShade shade = null;
...
/**
* Builder pattern, adapted. Offers an alternate way of building a PainterBackground. <br />
* Ex: <br />
* <pre>
* new
PainterBackground.Builder().fill().shade(ETypeColorShade.BASE).gradient(1).gradientReverse().backgroundImage(bc
kg_image_url).build()
* </pre>
* instead of
* <pre>
* new PainterBackground (true, null, null, ETypeColorShade.BASE, true, new GradientIntensity(1),
true, bckg_image_url)
* </pre>
* The main advantages are the general advantages of the builder pattern.
* The builder proves more verbose than the constructor when many parameters are to be set,
* however, when only few parameters are to be set, it is less verbose.
* In all cases it proves vastly more readable, scalable and versatile.
*/
public static class Builder
{ PainterBackground p%;
/**
* Build a new PainterBackground 'from scratch'.
* @see Builder
*/
public "uilder()
{ p% = new 2ainterBac=ground();
2
httpDCCstac5overf"o;.comC6uestio!sC1*,22',Cho;GtoGchec5G;hetherGt;oGo$8ectsGareGofGtheGsameGc"ass
24
}
/**
* Build a new PainterBackground on the basis of the passed PainterBackground.
* @see Builder
*/
public "uilder(PainterBackground p)
{ p% = (PainterBackground) p.clone();
}
/**
* Same as fill(true)
*/
public Builder #ill() {p%.fill = true ; return this; }
public Builder #ill (Boolean fill) {p%.fill = fill ; return this; }
public Builder color(String color) {p%.color = color; return this; }
public Builder colorSet(ETypeColorSet colorSet)
{p%.colorSet = colorSet; return this; }
#
/**
* Finalize building and return the built PainterBackground.
*/
public PainterBackground build()
{ return p%;
}
}
/**
* @used#by {@link PainterBackground.Builder}
*/
protected !ainter"ackground() {}
/**
* The `equivalent' constructor
*/
public !ainter"ackground(Boolean fill ,
String color ,
ETypeColorSet colorSet ,
ETypeColorShade shade ,
Boolean gradient ,
GradientIntensity gradientIntensity,
Boolean gradientReverse ,
String backgroundImage
)
{
this.fill = (fill != null) ? fill : null;
this.color = (color != null) ? color : null;
this.colorSet = (colorSet != null) ? colorSet : null;
this.shade = (shade != null) ? shade : null;
this.gradient = (gradient != null) ? gradient : null;
this.gradientIntensit = (gradientIntensity != null) ? gradientIntensity : null;
this.gradient.everse = (gradientReverse != null) ? gradientReverse : null;
this.%ac=groundI$age = (backgroundImage != null) ? backgroundImage : null;
}
#
".3 ,lass inheritance
".3.1 ,lass inheritance .ith constructors
3.7.1.1 ,onstructor calls
Because Java @&uara!teesA that a co!structor method of a c"ass is ca""ed ;he!ever a! i!sta!ce of that c"ass is created G
eve! if tech!ica""y it is a su$c"ass that is $ei!& created G
if the first stateme!t i! a co!structor does !ot e%p"icit"y i!vo5e a!other co!structor ;ith this() or super()
Java imp"icit"y i!serts the ca"" super()e that is it ca""s the superc"ass co!structor ;ith !o ar&ume!ts
(o!comita!t"y if a superc"ass co!structor is e%p"icit"y ca""ed it has to $e do!e first thi!& i! the $ody of the
su$c"ass co!structor. -=ca! $e a $it of a dra& RR>0. @Ohe! a co!structor is i!vo5ed it ca! cou!t o! the fie"ds of its
superc"ass to $e i!itia"i<edA.
o The do;!side of this is that o!e ca!!ot ca"" super=> ;ith "oca""y defi!ed attri$utes
2'
Example$
public class GenericException extends Exception
{
public String exceptionDescription = "";
public GenericException(String msg, Exception e)
{ //# // Java does not structurally allow the following:
//# super(this.exceptionDescription + msg, e);
//# // ("Cannot refer to 'this' nor 'super' while explicitly invoking a constructor")
super(msg, e);
this.initalise();
}
?! the a$ove case ;e cou"d have tried to &et a;ay ;ithD
public GenericException(String msg, Exception e)
{ super(e);
super.setMessage(this.exceptionDescription + msg);
.
}
$ut sad"y i! this precise case the pare!t c"ass does !ot provide a! a"ter!ate ;ay =i.e. aside from co!structor> to set the
desired attri$ute =messa&e>.
Ohat ca! $e do!e o! the other ha!d is to override the &et.essa&e=> fu!ctio!.
A su$c"ass ca!!ot imp"icit"y re"y o! a superc"ass co!structor. ?t has to redefi!e it =same si&!ature> a!d ca"" it throu&h
super=params>. -ma8or pai! i! the aa0
=this is !ot the case i! P/P. -dou$"eGchec5 that0>
Heritage
3.7.1.2 Anvo/in! overrida$le methods from constructors
There are a fe; more restrictio!s that a c"ass must o$ey to a""o; i!herita!ce. (o!structors must !ot i!vo5e overrida$"e
methods direct"y or i!direct"y. ?f you vio"ate this ru"e pro&ram fai"ure ;i"" resu"t.
-B"och0
)ee a"soD httpDCCstac5overf"o;.comC6uestio!sC3444341C;hatsG;ro!&G;ithGoverrida$"eGmethodGca""sGi!Gco!structors
2*
To circumve!t thisD use the 7actory patter!.
".3.2 Anteraction $et.een child and parent class
3.7.2.1 Redefine function
".3.2.1.1 ,all parent function
super.<name of function> (<parent function params>)
".3." '$stract
?t is possi$"e for a! a$stract c"ass to defi!e a co!structor. /o;ever si!ce a! a$stract c"ass ca!!ot $e i!sta!tiated
direct"y this co!structor ;i"" have to $e ca""ed from a co!structor of a! imp"eme!ti!& c"ass =usi!& super=#>>.
httpDCCstac5overf"o;.comC6uestio!sC2*4***Cca!Ga!Ga$stractGc"assGhaveGaGco!structor
3.7.3.1 ,all su$class constructor from a$stract class in 2ava
httpDCCstac5overf"o;.comC6uestio!sC+11+24Cca""Gsu$c"assGco!structorGfromGa$stractGc"assGi!G8ava
public AbstractBook getNe$%nstance(AbstractBook model) throws InstantiationException, IllegalAccessException
{
AbstractBook ret = this.getClass().newInstance();
return ret;
}
Pro$"emD this so"utio! !eeds the imp"eme!ti!& c"ass to defi!e a !u""ary co!structor =co!structor ;ith !o ar&ume!ts>
other;ise chec5ed e%ceptio!s ;i"" $e thro;!.
A"ter!ative ;ayD use c"o!e=>. /o;ever this so"utio! i! tur! !eeds the copied o$8ect to imp"eme!t the c"o!e i!terface.
".@ null
null is a refere!ce. null is !ot a! o$8ect. GH ?s null a! i!sta!ce of a!y c"ass P NO
null is a "itera" that mea!s that a varia$"e does !ot refere!ce a!y o$8ect
instanceo) used o! null =!u"" i!sta!ceof #> a";ays retur!s )alse.
Casting null:
httpDCCstac5overf"o;.comC6uestio!sC31'+4*C;hyG!u""Gcast
)ee AP? desi&! sectio!.
".C Polymorphism
K!"i5e P/P Java does !ot support po"ymorphism o! attri$utes. =i.e. @referri!& statica""y to a! attri$ute i! a pare!t c"ass
;i"" at ru!time use the attri$ute redefi!ed i! the chi"d c"ass if ru!time c"ass is a chi"d c"assA>. ?! fact Java discoura&es
the redefi!i!& =@hidi!&A is the term used i! the 8ava docume!tatio!> of attri$utes i! chi"d c"asses.
Both do ho;ever support po"ymorphism for fu!ctio!s =the @$asicA po"ymorphism>
public class %y&lass
{
protected static final String displa1essage = "";
public String getDisplayMessage()
{ /* */ try {
// Emulate polymorphism on attributes:
return (String) this.getClass().getDeclaredField("displayMessage").get(this);
/* */ // Any exception here is due to a "static" mistake.
/* */ // If this code is well written it should never happen.
/* */ // We will still report it so as to allow the programmer to correct it if it
does.
/* */ } catch (Exception e) {
/* */ throw new RuntimeException(e); }
}
2,
".C.1 8mulate Gattri$uteH polymorphism )I la P=P+
The idea is to use &etters a!d setters rather tha! acess the attri$utes direct"y.
public class ParentClass
{
public static String classAtt = "ParentClass_classAtt";
protected String instanceAtt = "ParentClass_instanceAtt";
/**
* This function is NOT redefined in child class.
*
* It emulates PHP's "attribute" polymorphism.
* It relies on getting the attributes through getters that are themselves
* redefined in the ChildClass.
*/
public String toString()
{ // Compile time ("static") class: (Equivalent to PHP's __CLASS__)
String class_compiletime = Thread.currentThread().getStackTrace()[1].getClassName();
// Runtime ("dynamic") class: (Equivalent to PHP's get_class($this)):
String class_runtime = this.getClass().getName();
// Equivalent to PHP's __FUNCTION__
String method = Thread.currentThread().getStackTrace()[1].getMethodName();
String ret = "";
ret = ret + "Class at compile time = " + class_compiletime + "\n";
ret = ret + "Class at run time = " + class_runtime + "\n";
ret = ret + "Method = " + method + "\n";
//ret = ret + $this->printClass(__CLASS__);
ret = ret + "My attributes are:" + "\n" ;
ret = ret + " classAtt =" + getClassAtt() + "\n" ;
ret = ret + " instanceAtt=" + this.getInstanceAtt() + "\n" ;
return ret;
}
public static String getClassAtt()
{ return this.classAtt;
}
public String getInstanceAtt()
{ return this.instanceAtt;
}
}
public class ChildClass extends ParentClass
{
public static String classAtt = "ChildClass_classAtt";
protected String instanceAtt = "ChildClass_instanceAtt";
// We will have to re-write the following getters in the present class
// to achieve our goal (even though they already are defined in parent class)
// There lies the difference with PHP: in PHP this would not have been necessary.
//
// At runtime, `this' always refers to the most precise class (here ChildClass).
public String getClassAtt()
{ return this.classAtt;
}
public String getInstanceAtt()
{ return this.classAtt;
}
}
OT/3R .3T/O9
?!stead of overridi!& =a5a S hidi!& T ie redefi!i!& the same attri$ute i! su$c"ass> o!e ca! reaffect !e; va"ues to the
attri$utes i! the co!structorD
public class ParentClass
{
public static String classAtt = "ParentClass_classAtt";
protected String instanceAtt = "ParentClass_instanceAtt";
public String toString()
{ String ret = "";
ret = ret + "My attributes are:" + "\n" ;
ret = ret + " classAtt =" + classAtt + "\n" ;
2+
ret = ret + " instanceAtt=" + this.instanceAtt + "\n" ;
return ret;
}
}
public class ChildClass extends ParentClass
{
// Instead of redefining the attributes
//public static String classAtt = "ChildClass_classAtt";
//protected String instanceAtt = "ChildClass_instanceAtt";
// we set the parent's with using an initializer block
// (overwrite, rather than set, if they were already set in parent)
{ this.instanceAtt = "ChildClass_instanceAtt";
}
static {
classAtt = "ChildClass_classAtt";
}
// And this does the trick
}
(a""sD
ChildClass child = new ChildClass();
ParentClass parent= new ParentClass();
System.out.println("**parent.toString()");
System.out.println(parent.toString());
System.out.println("");
System.out.println("**child.toString()");
System.out.println(child.toString());
System.out.println("");
;i"" outputD
============== TEST ==============
**parent.toString()
My attributes are:
classAtt =ChildClass_classAtt NOTE THAT THE STATIC VAR HAS BEEN REWRITTEN BY CHILD even
though Parent build was called after. (static, not instance)
instanceAtt=ParentClass_instanceAtt
**child.toString()
My attributes are:
classAtt =ChildClass_classAtt
instanceAtt=ChildClass_instanceAtt
".1JPolymorphism6Redefinition )overridin!+
".1J.1 Overridin!
App"ies o!"y to methods.
7or attri$utes this is ca""ed Vhidi!&V =a!d is discoura&ed as per the Java doc>
3.10.1.1 override .ith e&tendin! return type :
?t seems it is !ot possi$"e.
/o;ever overridi!& ;ith a su$type as retur! ;ou"d $e ON.
Java '.4 i!troduces a !e; faci"ity ca""ed covariant retur! type. \ou ca! override a method ;ith the same si&!ature $ut retur!s
a su$c"ass of the o$8ect retur!ed
-httpDCC;;;.%y<;s.comCJavafa6Cca!Ga!Goverridi!&GmethodGhaveGaGdiffere!tGretur!GtypeGtha!GtheGoverridde!GmethodC31 0
".1J.2 Overridin! a static method
Overridi!& a static method ;o!Ft ;or5 the ;ay overridi!& a !o! static method does =the "atter &ivi!& us the opportu!ity
to use po"ymorphism>D the mai! reaso! $ei!& that static calls are resolve' at com!ile time a!d !ot ru!time.
)uper.method=> does!Ft ;or5 either.
21
?! some p"aces a!d circumsta!ces it mi&ht $e i!teresti!& to co!sider MOT ma5i!& a! attri$ute static =specia""y ;he!
;or5i!& ;ith ?o( mecha!isms ;hich re"y heavi"y o! dy!amic typi!&>
3.10.2.1 8&ample
(ompareD
;ith static !ame for the p"u&i!
public abstract class Plugin
{
/**
* Return canonical name of plugin
*/
public abstract String getPluginName();
public class PluginLogin extends Plugin implements ConfFileSupport
{
public static final String PLUGIN_NAME = "login";
@Override
public String getPluginName()
{ return PLUGIN_NAME;
}
...
public void logIn(ILoggable ubo)
{ /* */ if (debugOn) this.logger.debug("<<");
PluginSession plugin_session = (PluginSession)
this.pluggee.getPlugin('luginSession(')*+IN#N,%E);
plugin_session.add(SESSION_LOGGED_USER, ubo);
...
a!d ;ith !o!Gstatic !ame for the p"u&i!D
public abstract class Plugin
{
/**
* To be redefined in extending classes
*
* DESIGN NOTE: this field was chosen not to be made static. The reason for this is that static fields
* are computed at compile time and not runtime, and we will be relying on
* polymorphism subtyping (i.e. manipulating the parent class at compile time and waiting for runtime
* to know the exact subtype), in several places, notably in the list of plugins in class BaseACT,
* (this list is typed with the parent plugin class, and is fed dynamically with subtype plugins by
* spring).
* It this field were made static, then we would have to redefine both it and its getter in extending
* classes.
* By not making it static, we only need redefine the variable.
* However, this means we won't be able to do such stuff as:
* PluginSubclass.PLUGIN_NAME
* Instead we will have to do something like:
* new PluginSubclass().getPluginName()
*/
public String 2L:;I)5)A1E = "";
/**
* Return canonical name of plugin
*/
public String get!luginName()
{ return 2L:;I)5)A1E;
}
public class PluginLogin extends Plugin implements ConfFileSupport
{
{ PLUGIN_NAME = "plugin_login";
}
...
public void logIn(ILoggable ubo)
{ /* */ if (debugOn) this.logger.debug("<<");
PluginSession plugin_session = (PluginSession) this.pluggee.getPlugin(
new PluginSession().getPluginName());
plugin_session.add(SESSION_LOGGED_USER, ubo);
...
".11Overridin! O$Fect.eDuals
httpDCCdo;!"oad.orac"e.comC8avaseCtutoria"C8avaC?a!d?Co$8ectc"ass.htm"
34
@The equals() method provided i! the Object c"ass uses the ide!tity operator ===>A
The fo""o;i!& is the correct ;ay of overridi!& e6ua"s. The bOverride a!!otatio! ca! $e importa!t as it ;i"" preve!t
;riti!& somethi!& "i5e public boolean equals(MyClass m) ;hich ;i"" !ot override O$8ect.e6ua"s=O$8ect>. -3ffective
Java 3*0
@Override
public boolean equals(Object o)
{ if (!(o instanceof JourBO))
return false;
JourBO jbo = (JourBO) o;
return
(
( (this.typeOfDay == null) ? (jbo.typeOfDay == null) : (this.typeOfDay ==
(jbo.typeOfDay ) ) )
&& ( (this.date == null) ? (jbo.date == null) : (this.date .equals(jbo.date
) ) )
&& ( (this.timeOpening == null) ? (jbo.timeOpening == null) : (this.timeOpening
.equals(jbo.timeOpening) ) )
&& ( (this.timeClosing == null) ? (jbo.timeClosing == null) : (this.timeClosing
.equals(jbo.timeClosing) ) )
);
}
/**
* Since we override equals we have to override hashCode too.
* [Bloch Item 9]
*/
@Override
public int hashCode()
{ int result = 17;
result = 31 * result + this.typeOfDay .hashCode();
result = 31 * result + this.date .hashCode();
result = 31 * result + this.timeOpening.hashCode();
result = 31 * result + this.timeClosing.hashCode();
}
".12,lonin!
O$8ects that ca!C!eed to $e c"o!ed must imp"eme!t the i!terface Cloneable. Other;ise a CloneNotSupportedException
;i"" $e thro;!.
Cloneable dos !ot e%pose a pu$"ic fu!ctio! clone() GH have to override it
)ee Joschua B"och ?tem
Ksi!& c"o!i!&P
Avoid imp"eme!ti!& clone.
- clone is very tric5y to imp"eme!t correct"y i! a"" circumsta!ces !ear"y to the poi!t of $ei!& patho"o&ica"
- the importa!ce of copyi!& o$8ects ;i"" a";ays remai! si!ce o$8ect fie"ds ofte! !eed to $e defe!sive"y copied -7/ i.e.
c"o!e=> o!"y copies $it for $it so i! order to actua""y dup"icate a!y refere!ced su$Go$8ect =Ufie"d> that o$8ect ;i"" have to
imp"eme!t c"o!e=> a"so0
- copy co!structors a!d static factory methods provide a! a"ter!ative to clone a!d are much easier to imp"eme!t
httpDCC;;;.8avapractices.comCtopicCTopicActio!.doP?dU,1
)ee a"so httpDCCydisa!to.deve"oppe<.comCtutorie"sC82seCc"o!ea$"eC
public class CssSelectorBox extends CssSelector implements Cloneable
{
private String $argin ;
private String padding ;
// . other 'easily copiable' fields
@Override
public Object clone() throws CloneNotSupportedException
{ return super.clone();
}
31
Or possi$"y eve!D
@Override
public CssSelectorBox clone() throws CloneNotSupportedException
{ return (CssSelectorBox) super.clone();
}
".1"Reflection )and .ider+
".1".1 Doc
httpDCCdo;!"oad.orac"e.comC8avaseCtutoria"Cref"ectCmem$erCmethod?!vocatio!.htm"
".1".2 >et name of current function
// Equivalent to PHP's __FUNCTION__
String method = Thread.currentThread().getStackTrace()[1].getMethodName();
".1"." ,all method dynamically
3.13.3.1 <ethod )6function+
public void debug (int level, String message)
{
Class<?> c = this.getClass();
try
{ Method method = c.getDeclaredMethod ("debug_" + level, String.class);
// (name of method, list of params): signature of the method
method.invoke (this, message);
// In static context, replace this by null
}
catch (Exception e)
{ //!"!
}
}
3%ceptio!sha!d"i!&
@?! ref"ectio! there is !o disti!ctio! i! the ha!d"i!& of chec5ed versus u!chec5ed e%ceptio!s. They are a"" ;rapped i! a!
InvocationTargetException T
9y!amic method i!vocatio! ;ith severa" paramsD
public static void main(String[] args) throws Exception
{
echo("============== TEST ==============");
Boolean bool = true;
String str = "I am a string";
formValidate("Form6"); // outputs "bool = null, str =null"
formValidate("Form6", bool); // outputs "bool = true, str =null"
formValidate("Form6", bool, str); // outputs "bool = true, str =I am a string"
formValidate("Form6", str); // causes Exception in thread "main"
java.lang.reflect.InvocationTargetException Caused by: java.lang.ClassCastException: java.lang.String cannot be
cast to java.lang.Boolean
}
public static void formValidate(String form_name, Object... args) throws Exception
{
Class c = Test.class;
{ /* */ echo("Invoking validate" + form_name + "method.invoke (this, args)");
Class[] argTypes = new Class[] { Object[].class };
Method method = c.getDeclaredMethod ("validate" + form_name, argTypes);
method.invoke (null, (Object)args); // null because static call
}
}
//#public static void validateForm6(Boolean bool) // does not work
public static void validateForm6(Object... args)
{ echo("I am validateForm6(Boolean bool)");
Boolean bool = null;
String str = null;
// We then have to "manually" extract our params from the array 'args':
// Users of this function will have to have knowledge of the expected structure of 'args'
if (args.length > 0)
bool = (Boolean) args[0];
if (args.length > 1)
32
str = (String) args[1];
echo("bool = " + bool + ", str =" + str );
}
3.13.3.2 tatic method
The VcorrectV ;ay seems to $eD
String err_msg = "Please check code, this sould not happen. All themes should have a public static getName()
function.";
err_msg+= " e was: " + e;
try
{ ret.put(e, (String) e.getCla>>().get0eclared1ethod("getName",(Class[]) null).invo=e(null, (Object[])
null));
}
catch (IllegalArgumentException e1)
{ throw new .unti$eException(e1.getClass().get)a$e() + " " + err_msg );
}
catch (SecurityException e1)
{ throw new .unti$eException(e1.getClass().get)a$e() + " " + err_msg );
}
catch (IllegalAccessException e1)
{ throw new .unti$eException(e1.getClass().get)a$e() + " " + err_msg );
}
catch (InvocationTargetException e1)
{ throw new .unti$eException(e1.getClass().get)a$e() + " " + err_msg );
}
catch (NoSuchMethodException e1)
{ throw new .unti$eException(e1.getClass().get)a$e() + " " + err_msg );
}
A"thou&h have !ot $ee! a$"e to ma5e this ;or5 #
".1".# ,all field dynamically
httpDCCdo;!"oad.orac"e.comC8avaseCtutoria"Cref"ectCmem$erCfie"dVa"ues.htm"
Class<?> c = book.getClass();
Field chap = c.getDeclaredField("chapters");
chap.setLong(book, 12);
chap.getLong
Other 3%amp"eD
Field inputSeuil;
/* */ try {
inputSeuil = c.getDeclaredField(String.for$at("inputSeuilD%sH%s", i, j));
int inputSeuilVal = inputSeuil.getInt(this);
if (inputSeuilVal < 0)
{ return false;
}
/* */ }
/* */ catch (SecurityException e)
/* */ { e.printStackTrace();
/* */ }
/* */ catch (NoSuchFieldException e)
/* */ { e.printStackTrace();
/* */ }
/* */ catch (IllegalArgumentException e)
/* */ { e.printStackTrace();
/* */ }
/* */ catch (IllegalAccessException e)
/* */ { e.printStackTrace();
/* */ }
Other e%amp"e
public TypeRightsAccessLevel #romString(String accessLevel)
{
/* */ String err_msg = "Error while converting string: " + accessLevel + " to type
TypeRightsAccessLevel.";
/* */ try
/* */ {
Class<?> c = this.getClass();
Field access_level = c.get0eclaredField(accessLevel);
return (TypeRightsAccessLevel) access_level.get(c);
/* */ }
/* */ catch (SecurityException e)
/* */ { throw new 3pe.ightsException(err_msg, e);
/* */ }
/* */ catch (NoSuchFieldException e)
33
/* */ { throw new 3pe.ightsException(err_msg, e);
/* */ }
/* */ catch (IllegalArgumentException e)
/* */ { throw new 3pe.ightsException(err_msg, e);
/* */ }
/* */ catch (IllegalAccessException e)
/* */ { throw new 3pe.ightsException(err_msg, e);
/* */ }
}
".1".% ,all constructor dynamically
httpDCCcommo!s.apache.or&C$ea!uti"sCcommo!sG$ea!uti"sG1.,.4CdocsCapiCor&CapacheCcommo!sC$ea!uti"sC(o!structorKti"s.htm"
httpDCCforums.devshed.comC8avaGhe"pG1Cref"ectio!Gdy!amicGc"assGcreatio!G'14'24.htm"
=MOT T3)T39>
// Retrieve an instance of the action:
BaseWithSessionAndAuthorizationsACT action = (BaseWithSessionAndAuthorizationsACT)
Class.for)a$e(node_item_action).getConstructor((Class[])null).newInstance();
Other e%amp"e =tested>
Constructor<?> constr = c.getConstructor(int.class, int.class);
Object o = constr.newInstance(10, 3);
".1#,astin!
".1#.1 Definition
(asti!& sho;s the use of a! o$8ect of o!e type i! p"ace of a!other type amo!& the o$8ects permitted $y i!herita!ce a!d
imp"eme!tatio!s
-httpDCCdo;!"oad.orac"e.comC8avaseCtutoria"C8avaC?a!d?Csu$c"asses.htm"0
3.14.1.1 Amplicit
// Class MountainBike extends Bike
MoutainBike mb = new MountainBike();
Bike b = mb; // implicit casting (and "upwards", i.e."upcasting") - A
// MoutainBike IS a Bike.
// Here the compiler is capable of figuring out that everything is
// in order: it does not need our promise.
b.toString() ; // which toString() is called ? The one from MountainBike:remember
// method calls are resolved at runtime, and at runtime, b is a
// MountainBike (see polymorphism)
b.functionFromBike() ;
b.functionFromMountainBike() ;
3.14.1.2 8&plicit
".1#.1.2.1 Bet.een o$Fects
Object obj = retrieveDynamically();
MountainBike myBike = (MountainBike) obj; // explicit casting: we make the promise to the compiler that
// obj will, at runtime, actually contain a MoutnainBike (subtype
// of Object)
// Here the compiler has no way to statically (i.e. at compile
// time) check that the code we're writing is correct. It therefore
// relies on this promise.
E,!licit casting is simp"y s&nctactic sugar a V!romiseV made to the compi"er ;he! it is u!a$"e to verify the
correct!ess of a! assi&!me!t =i.e. at com!ile time> that yes ;e are sure that at runtime the o$8ect ;eIre dea"i!& ;ith
=that ;e are casti!&> ;i"" effective"y $e of the a""e&ed type =or VfitV i!to it i! the case of casti!& primitve types> ;e ;a!t
to ma!ipu"ate. This promise is materia"ised to the compi"er $y the act of Vcasti!&V.
Of course if this promise ;ere to prove fa"se the pro&ram ;ou"d crash =at ru!time>. -7/?0
".1#.1.2.2 Bet.een primitives
Primitive types come i! differe!t si<es. 7or e%amp"e a! i!t is 32 $it ;hereas a "o!& is *4. ?f you are stic5i!& a sma""er
type i!to a "ar&er type =e&. a! i!t i!to a "o!&> there is !o !eed to cast si!ce there is !o ris5 that the va"ue ;i"" $e "ar&er
tha! its co!tai!er. /o;ever ;he! you &o i! the opposite directio! =e&. a "o!& i!to a! i!t> a compi"atio! error ;i"" occur
si!ce Java is afraid the va"ue ;i"" $e too "ar&e for its type. To Vsi"e!ceV the compi"er you ca! cast the va"ue to the
34
i!te!ded type. ?! doi!& so you ris5 the va"ue overf"o;i!& its co!tai!er.
-httpDCC;i5i.a!s;ers.comCQCOhe!Wcasti!&WisW!eededWi!W8ava0
int i = 0; // 32 bits
long lg = 0; // 64 bits
lg = i ; // valid
i = lg ; // compiler complains: "Type mismatch: cannot convert from long to int"
i = (int) lg ; // valid, however (at runtime) overflow might occur (see below)
i = (int) Long.1A<5'AL:E ; // valid, however (at runtime) overflow WILL occur. This however occurs silently:
// no Exception is thrown.
".1#.2 ,astin! null7
)ee a"so sectio! o! !u"".
3.14.2.1 to Boolean
(asti!& !u"" to a Boo"ea! ;i"" raise a MP3.
Object obj = null;
if ((Boolean) obj) // raises NPE
This ;i"" do the tric5 =a"thou&h have to admit it "oo5s a $it co!vo"uted>D
Object obj = null;
if ((new Boolean(true)).equals(obj)) // if obj is null this won't be validated
or
if (obj!= null && obj)
".1#." K,astin!L to an o$Fect it .as not )9Mconvertin!, Nconvert to su$9type conundrumN
40=A5+
Mo; ho; ;ou"d do if ;e had a Bike a!d ;a!ted to store it = @co!vertA it> to a MountainBikeP
This c!!o!t $e do!e $y simp"y casti!& the Bike i!to a MountainBike. A!d ;ith a &ood reaso!D a Bike is simp"y MOT a
MountainBike (;hereas the other ;ay rou!d is trueD a MountainBike ?) a Bike)
)o ho; come ;e ma!a&ed to do somethi!& "i5e it i! our previous e%amp"e P =remem$er D MountainBike myBike =
(MountainBike) obj ). Oe"" i! that particu"ar case ;e ;ere casti!& obj to a MountainBike. But that ;ou"d ;or5 o!"y if
obj actua""y co!tai!ed at ru!time a MountainBike i.e. some;here ear"ier a"o!& the "i!e somethi!& "i5e this occurredD
Object obj = new MountainBike();
)o tech!ica""y obj a"ready is a MountainBike. Oe o!"y !eed to "et the compi"er 5!o; that.
?f o$8 fai"ed at ru!time to co!tai! a MountainBike say obj e!ded up $ei!& a Bike casti!& ;ou"d!Ft ;or5
=ClassCastException thro;!>. Oe ;ou"d have to Eco!vertF the Bike i!to a MountainBike usi!& a copy fu!ctio!D
Bike b = new Bike();
MoutainBike mb = (MountainBike) b; // compiler won't coplain: it's simply relying on our promise that
b will at runtime contain a MountainBike [the compiler is not "smart" enough to realize that in this case, this
can't happen]. At runtime however, a ClassCastException will be thrown : because in effect, b contains a Bike
and not a MountainBike.
MountainBike mb = new MountainBike(b); // This would be the way to do it, with the constructor MoutainBike
(Bike b)
Bike
{ att1
att 2
.
Bike() // constructor
{ .
}
copyFrom(Bike b)
{ // Copy all relevant attributes that make the `identity' of the object:
this.att1 = b.att1;
This.att2 = b.att2;
3'
.
}
}
MountainBike() extends Bike
{ // Constructor
MountainBike()
{ .
}
// Constructor, converting from Bike
MountainBike(Bike b)
{ // here super() is called silently
this.copyFrom(b);
}
}
This practise may $e da!&erous. ?f duri!& deve"opme!t a! attri$ute is added to the c"ass o!e has to
remem$er to copy it a"so i! the copy fu!ctio!. This ca! easi"y $e for&otte! a!d "ead to $u&s difficu"t to
trace.
".1%Type6class of an o$Fect 4instanceof5
".1%.1 instanceof operator7
3%amp"eD
public !luginMenuEception(String err_msg, Throwable e, Object o)
{
this(err_msg, e);
String menu_name = null;
ILoggable user = null;
if (o instanceof HashMap)
{ //HashMap h = (HashMap) o;
menu_name = (String) ((HashMap) o).get("menu_name"); // may be null if key does not exist
user = (ILoggable) ((HashMap) o).get("user") ; // may be null if key does not exist
}
#
3%amp"eD
if (resource_bundle instanceof String)
{ this.load.esourceBundle((String) resource_bundle);
}
else if (resource_bundle instanceof InputStream)
{ this.load.esourceBundle((InputStream) resource_bundle);
}
else
{ throw new .unti$eException("Programming error: resource bundle is not of expected type, check code",
null);
}
Bike bike = new Bi=e();
BikeMoutain mbike = new Bi=e1outain(); // extends Bike
(mbike instanceof Bike) // true
".1%.2 Dynamic
The $e!eath is !ot possi$"e. The ri&ht opera!d of is!ta!ceof has to $e a type !ot a varia$"e.
public static Throwable getFirstCauseEception&#Type(Exception e, Class<?> causeType)
{
Throwable cause = e.getCause();
while (cause != null)
{ if (cause instanceof causeType )
{ return cause;
}
?!stead useD Class.isInstance(var_obj):
if (causeType.isInstance(cause)
3*
The Class c"ass ha ma!y other i!teresti!& fu!ctio!sD
as)u$c"ass=>
is?!sta!ce=#
(hec5 ;hether the c"ass is a! e%act c"ass a!d !ot a su$c"assD
if (causeType.getCanonical)a$e().equals(cause.getClass().getCanonicalName()))
(om$i!i!& the 2D
public static Throwable getFirstCauseEception&#Type(Exception e, Class<?> causeType, boolean exactClass)
{
Throwable cause = e.getCause();
while (cause != null)
{ boolean test = exactClass
? causeType.getCanonical)a$e().equals(cause.getClass().getCanonical)a$e())
: causeType.isInstance(cause);
if (test)
{ ...
".11,ovariant return type )returnin! a su$type in a implemented6e&tended method+
(a! a method =of a c"ass> imp"eme!ti!& the method of a! i!terface =or overridi!& the method of a pare!t c"ass>
retur! a su$type of the type retur!ed $y the i!terface method P
\3) this is possi$"e. This is ca""ed covariant return t&!e a!d is possi$"e si!ce Java '.4
\ou ca!!ot have t;o methods i! the same c"ass ;ith si&!atures that o!"y differ $y retur! type. K!ti" the J2)3 '.4 re"ease it
;as a"so true that a c"ass cou"d !ot override the retur! type of the methods it i!herits from a superc"ass. ?! this tip you ;i""
"ear! a$out a !e; feature i! J2)3 '.4 that a""o;s covaria!t retur! types. Ohat this mea!s is that a method i! a su$c"ass may
retur! a! o$8ect ;hose type is a su$c"ass of the type retur!ed $y the method ;ith the same si&!ature i! the superc"ass. This
feature removes the !eed for e%cessive type chec5i!& a!d casti!&.
-httpDCC;;;.8avaGtips.or&C8avaGseGtipsC8ava."a!&Ccovaria!tGretur!Gtypes.htm"0
# 8&ceptions
#.1 >et printtac/Trace in strin!
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
String my_string = sw.toString() ;
#.2 Anterestin! sites )on the su$Fect+
httpDCC8ava.deve"oppe<.comCfa6C8avaCPpa&eU"a!&a&eWdo!!ees
#." ,hained e&ceptions
public Exception(String message,Throwable cause)
A null va"ue is permitted for cause a!d i!dicates that the cause is !o!e%iste!t or u!5!o;!.
#.# <ulti catch )catchin! multiple e&ception in one catch $loc/+ 4multicatch5
Mot possi$"e =as of yetP>
?!teresti!& readD httpDCC;;;.8ava"o$$y.or&C8avaCforumsCt14'34,.htm"PstartU4
/ere is a! e%amp"e of the case of copyGpaste ;e ofte! ru! i!toD
3,
/* */ try
/* */ {
this.constructorSub(xml_config_file, resource_bundle);
/* */ }
/* */ // DESIGN NOTE: PLEASE JAVA introduce multi-catch !
/* */ // The following 3 DOM exceptions could all be grouped since they quite fortunately enough
/* */ // derive from the same parent DOM Exception.
/* */ // Yet that is not always the case when catching multiple exceptions and somehow I feel it is
/* */ // more explicit (and thus less error-prone) to detail how each exception explicitly thrown
/* */ // at lower level is dealt with.
/* */ catch (DOMDocumentLoadMalFormedException e)
/* */ { throw new 1enuLoadException(err_msg + "(config file load error)", null);
/* */ }
/* */ catch (DOMDocumentLoadIOException e)
/* */ { throw new 1enuLoadException(err_msg + "(config file load error)", null);
/* */ }
/* */ catch (DOMDocumentBuildException e)
/* */ { throw new 1enuLoadException(err_msg + "(config file load error)", null);
/* */ }
/o;ever here is a ;ay to factori<eD
/* */ try
/* */ {
myFunction()
/* */ }
/* */ catch (Exception e)
/* */ { if (e instanceof ExceptionType1 || e instanceof ExceptionType2)
/* */ { // All common processing
/* */ ...
/* */ }
/* */ else
/* */ throw (RuntimeException) e;
/* */ // Casting to a RuntimeException prevents the compiler to force us to declare
/* */ // throws Exception in the function signature.
/* */ // We must however handle with care (as always with casts) and remember this
/* */ // is a promise made to the compiler: we promise that at this point,
/* */ // any exception is a RuntimeException.
/* */ //
/* */ // Or, to be on the safe side, we could chose to wrap any remaining exception
/* */ // in a runtime exception:
/* */ // throw new RuntimeException(exception wrapped in runtime excp, e);
/* */ }
9o;!sideD ;e ;i"" $e o$"ivious to =i.e. the ?93 ;i"" !ot poi!t out> a!y cha!&es i! the si&!ature of the fu!ctio!
myFunction() for e%amp"e if a !e; e%ceptio! ExceptionType3 is i!troduced that shou"dCcou"d $e ha!d"ed appropriate"y
it ;i"" fa"" a!o!ymous"y i! the Exception cate&ory.
A!other possi$"e ;ay ;ou"d $e to add a! i!termediary "eve" e%ceptio! to $e rethro;! $y the severa" e%ceptio!s
a!d that i!termediary e%ceptio! ;ou"d $e cau&ht i! a surrou!di!& try catch $"oc5. Possi$"y a $it heavy.
#.% 0inally O
The finally $"oc5 always e%ecutes 3hen the try bloc# e,its. This e!sures that the finally $"oc5 is e%ecuted eve! if
a! u!e%pected e%ceptio! occurs. But finally is usefu" for more tha! 8ust e%ceptio! ha!d"i!& f it a""o;s the pro&rammer
to avoid havi!& c"ea!up code accide!ta""y $ypassed $y a return continue or break. Putti!& c"ea!up code i! a
finally $"oc5 is a";ays a &ood practice eve! ;he! !o e%ceptio!s are a!ticipated.
=...>
6m!ortant: The finally $"oc5 is a 5ey too" for preve!ti!& resource "ea5s. Ohe! c"osi!& a fi"e or other;ise recoveri!&
resources p"ace the code i! a finally $"oc5 to e!sure that resource is al%ays recovered.
-httpDCCdocs.orac"e.comC8avaseCtutoria"Cesse!tia"Ce%ceptio!sCfi!a""y.htm"0
?f a! e%ceptio! is thro;! i! the fi!a""y $"oc5 the! that e%ceptio! ;i"" sha'o3 a!y previous e%ceptio!
thro;! i! the try catch =i.e. that previous e%ceptio! ;i"" !ot appear i! the e%ceptio! stac5>
httpDCCstac5overf"o;.comC6uestio!sC4+144*Cthro;sGe%ceptio!Gi!Gfi!a""yG$"oc5s
httpDCCi""e&a"ar&ume!te%ceptio!.$"o&spot.frC244+C14C8avaGho;G!otGtoGma5eGmessGofGstream.htm" -?223:A2AR:0
3+
:ood e!ou&hD
try
{ stream.write(data);
}
finally
{ stream.close();
}
a"thou&h a!y e%ceptio! thro;! $y close ;i"" shado; a!y e%ceptio! thro;! $y write.
Better sti""D
try
{ stream.write(data);
}
catch (IOException e)
{ firstError = e;
}
finally
{ try
{ stream.close();
}
catch (IOException e)
{ if (firstError == null)
{ firstError = e;
}
}
}
if (firstError != null)
{ throw firstError;
}
"ets throu&h a!y e%ceptio! thro;! $y write =$ut !ot those thro;! $y close>
?f a"" e%ceptio!s are re6uired to $e reportedD
A composite e%ceptio! patter! must $e used $ecause ;e !eed to thro; a! e%ceptio! that has 2 causes =the o!e from
;rite the o!e from c"ose>. The co!structor 3%ceptio!=Thro;a$"e cause> is !o &ood here. )ee -?223:A2AR:0.
% 2P<, classloaders, security
%.1 ,lasspath
httpDCCdocs.orac"e.comC8avaseC1.'.4CdocsCtoo"docsC;i!do;sCc"asspath.htm"
Java c"asses are or&a!i<ed i!to pac5a&es ;hich are mapped to directories i! the fi"e system. But u!"i5e the fi"e system
;he!ever you specify a pac5a&e !ame you specify the %hole pac5a&e !ame GG !ever part of it.
U the path to the fo"der =or other> co!tai!i!& the root of the pac5a&e shou"d $e o! the c"asspath a!d the c"ass referred to
as rootpackage.subpackage.MyClass
C:> -ava .classpath &$/path/to/my/compiled/classes com(fhi(%y&lass
;ith .y("ass.c"ass $ei!& "ocated atD &$/path/to/my/compiled/classes/com/fhi/%y&lass(class
%.2 ,lassloaders
-7rom 7ormatio! Orsys Java )gcuritg 2413.4*.43 7/?0
?! the JV. the c"ass "oader "oads the 8ava c"asses =the $yte code>
?t ;i"" automatica""y reso"ve re"atio!ships =imports i!herita!ce> a!d "oad these too a!d $ui"d a map of "oaded
c"asses.
?t "oads c"asses from the c"asspath.
("ass "oaders are Va&!osticV to o!e a!other =Vair ti&htV>D if severa" c"ass "oaders are used physica""y differe!t $ut
e6ua""y !amed c"asses =e&. com.my.9emo> may $e "oaded i! each of the c"ass "oader. =This is !ot possi$"e
other;ise>
31
Passi!& the -verbose:class s;itch to the java comma!d ;i"" pri!t each c"ass "oaded a!d ;here it ;as "oaded
from.
%.2.1 8&tendin!6usin! ecure,lass?oader
java.security.SecureClassLoader e%te!ds ("ass2oader ;ith additio!a" support for defi!i!& c"asses ;ith a!
associated code source a!d permissio!s ;hich are retrieved $y the system po"icy $y defau"t.
public class SecretClassLoader extends SecureClassLoader
{
/**
* Allows us to load the class from a "secure" location or in a "secure" fashion.
*/
@SuppressWarnings("unchecked")
protected Class<?> #indClass(String name) throws ClassNotFoundException
{
byte[] b = loadClass0ata(name);
return defineClass(name, b, 0, b.length);
}
private byte[] loadClassData(String name) throws ClassNotFoundException
{
try
{ String filename = "//192.168.25.250/tp/enonces/" + name + ".class";
InputStream in = new FileInputStrea$(filename);
byte[] data = new byte[in.availa%le()];
in.read(data);
in.close();
return data;
}
catch (FileNotFoundException e)
{ throw new Class)otFoundException("Fichier classe non trouv", e);
}
catch (IOException e)
{ throw new Class)otFoundException("Erreur IO", e);
}
}
}
Ksa&e i! .ai!D
public class Main
{
private static SecretClassLoader scl = new SecretClassLoader();
private static Class<?> classesecrete;
/**
* @param args
*/
public static void main(String[] args)
{
// 1. Load the class:
// ---------------
String classToLoad = "HomogenousVector";
try
{
classesecrete = scl.loadClass(className);
}
catch (ClassNotFoundException e)
{
print("ERROR: class could not be loaded : " + classToLoad);
e.printStac=3race();
}
// 2. Instantiate it and call one of its method:
// ---------------
// Unfortunately we will have to resort to using (ugly) reflection
try
{
// 2.1. Retrieve the constructor by signature:
Constructor<?> constr = c.getConstructor(int.class, int.class);
// or, if we know it's the first to be defined, we might use:
//# Constructor<?> constr = c.getConstructors()[0];
// 2.2. Instantiate:
// Method 1:
classeSecreteInstance = constr.newInstance(10, 3);
44
//#// Method 2:
//#Integer[] params = new Integer[2];
//# params[0] = 10;
//# params[1] = 3;
//#classeSecreteInstance = constr.newInstance((Object[]) params);
/* */ print(" Dump Classe secrte = " + classeSecreteInstance);
// 2.3. Call method:
Method method = c.get1ethod("size", (Class<?>[]) null);
Integer methodCallResult = (Integer) method.invo=e (classeSecreteInstance);
/* */ print("rsultat = " + methodCallResult);
}
catch (Exception e)
{
print("ERREUR: dans testDeLaClasseSecrete() ");
e.printStac=3race();
}
%." ystem
%.".1 >et current6e&ecution directory
httpDCC;;;.8avapro&rammi!&forums.comC8avaGcodeGs!ippetsGtutoria"sC334Gho;G&etGcurre!tGdirectoryGpath.htm"
import java.io.File;

public class CurrentDir {

public static void main(String args[]) {
File dir1 = new File(".");
File dir2 = new File("..");
try {
System.out.println("Current dir: " + dir1.getCanonicalPath());
System.out.println("Parent dir: " + dir2.getCanonicalPath());
} catch (Exception e) {
e.printStackTrace();
}
}
httpDCC;;;.code&uru.comCforumCsho;thread.phpPtU41+*2
System.out.println( this.getClass().getName() + " is loaded from " +
getClass().getProtectionDomain().getCodeSource().getLocation()
);
%.".2 0unction call stac/ 4lo!!in!, de$u!!in!, thro.a$le5
// 1. Retrieve calling class, function etc.:
// -----------------------------------------
Throwable t = new Throwable();
t.fillInStackTrace();
// Get the exception stack trace in a string:
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
String t_str = sw.toString();
System.out.println("Reporting message: " + message + "\n" + t_str);
int levelTraceBack = 8 + addLevelTraceBack;
// Due to the several levels used to call this method (reflection + invoke) the
// stack element we want is in a far position
StackTraceElement ste = t.getStackTrace()[levelTraceBack];
String call_class_name= ste.getClassName();
String call_method = ste.getMethodName();
int call_line = ste.getLineNumber();
// Classes name are usually: package.subpackage.class ; get only that last bit:
String[] arr_call_class = call_class_name.split("\\.");
call_class_name= arr_call_class[arr_call_class.length - 1];
41
%.# ecurity
Access to ma!y fu!ctio!s ca! $e restricted at the JV. "eve". This is ho; itIs do!eD
G App"icatio! has to $e "au!ched ;ith security parameter o!D
java -Djava.security.manager -Djava.security.policy=policy.txt
Ksi!& 3c"ipse to ru! the appD
Oriti!&
-Djava.security.policy==policy.txt
;i"" Vover;riteV a!y previous po"icy fi"es =i.e. i!stead of "oadi!& i! a! additivity fashio!>
G The po"icy fi"e is as such =the e%te!sio! used is usua""y .po"icy rather tha! .t%t>D
grant codeBase "file:///C:/Documents and Settings/Administrateur/workspace/Formation_Securite_TP_2/bin/-"
{ // This is a comment
permission java.util.propertyPermission "java.class.path", "read";
permission java.util.property...
};
The sy!ta% isD
grant codeBase <container of class (jar, folder.>
{ list of permissions
}; // Do not forget the trailing ;
/- mea!s D&ra!t this =these> permissio!=s> to a"" c"asses u!der this path
The po"icy fi"e a$ove ;i"" a""o; the c"asses i! .../Formation_Securite_TP_2/bin/- to read the property java.class.path
The app"icatio! e%ecuted ;ithout the ri&ht permissio! ;i"" yie"dD
Exception in thread "main" java.security.AccessControlException: access denied ("java.util.PropertyPermission"
"java.class.path" "read")
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPropertyAccess(Unknown Source)
at java.lang.System.getProperty(Unknown Source)
at ReadPropertyWithPermissionTest.main(ReadPropertyWithPermissionTest.java:35)
Other e%amp"esD
grant codeBase "file:///C:/Documents and Settings/Administrateur/workspace/Formation_Securite_TP_3_RMI/bin/-"
{
permission java.net.SocketPermission "127.0.0.1:1099", "accept, connect, listen, resolve";
};
grant codeBase "file:///C:/Documents and Settings/Administrateur/workspace/Formation_Securite_TP_3_RMI/bin/-"
{
// Permet de se connecter au RMIRegistry:
permission java.net.SocketPermission "127.0.0.1:1099", "accept, connect, listen, resolve";
// Permet d'accepter les sockets entrantes (de la part du client (bootstrap):
// sur les ports depuis 1024 (en fait ici dans cet exemple on ne connat pas le port
// qui sera fourni par RMIregister pour le dialogue entre le client et le serveur. Il aurait fallu
// le spcifier si on avait voulu un port prcis)
permission java.net.SocketPermission "127.0.0.1:1024", "accept, listen, resolve";
42
};
%.#.1 =o. permission is calculated7
The permissio! re6uired to e%ecute some actio! i! a fu!ctio! func some;here i! the app has to $e &ra!ted to a"" ca""s i!
the ca"" stac5 ="eadi!& to the ca"" of func> D the i!tersectio! of permissio!s has to $e !o! empty.
1 'PAs and concerns
1.1 0iles 4path, -R?, -RA5
httpDCCdo;!"oad.orac"e.comC8avaseCtutoria"Cesse!tia"CioCi!de%.htm"
1.1.1 0iles and Paths
6.1.1.1 Bor/in! .ith files7 the 0ile class
8ava.io.7i"e D A! a$stract represe!tatio! of fi"e a!d directory path!ames
Kser i!terfaces a!d operati!& systems use systemGdepe!de!t pathname strin)s to !ame fi"es a!d directories. This c"ass
prese!ts a! a$stract systemGi!depe!de!t vie; of hierarchica" path!ames. A! abstract pathname has t;o compo!e!tsD
-Javadoc0
The 2 mai! co!structors areD
0ile(String pathname)
0ile(URI uri)
?f the a$so"ute path !ame of the fi"e is !ot 5!o;! itIs -pro$a$"y0 better to use the "+6 constructor.
Jump to that sectio!.
Other;ise the current user directory ;i"" $e i!vo"ved a!d -i! my opi!io!0 this comp"icates thi!&s.
1.1.1.1.1 ,reatin! a 0ile from a trin! pathname
1.1.1.1.1.1 .ith an a$solute path
File myFile2 = new File("/C:/.../myFileName.txt"); //absolute
1.1.1.1.1.2 .ith a relative path
File myFile = new File("myFileName.txt"); //relative - uses the current user directory
A re"ative path starts $y =or does!It start $y> TO9O
The re"ative path !ame is &ive! re"ative to the current user 'irector&:
A re"ative path!ame i! co!trast must $e i!terpreted i! terms of i!formatio! ta5e! from some other path!ame. By defau"t the
c"asses i! the java.io pac5a&e a";ays reso"ve re"ative path!ames a&ai!st the current user 'irector&. This directory is
!amed $y the system property user.dir a!d is t&!icall& the 'irector& in 3hich the Java virtual machine 3as invo#e'.
Pri!t ;hat the curre!t user directory isD
3%amp"eD
public class Runnable_Test
{
public static void main(String[] args) throws FileNotFoundException
{
File f=new File(".");
/* */ System.out.println("Current directory (.) is: " + f.getA%solute2ath());
}
...
43
OutputsD
Current directory (.) is: F:\02-COMPUTING\71-CODE\10-BY_LANGUAGE_[for_doc_purposes]\JAVA\Z-TESTS (Eclipse
project)\.
1.1.1.1.2 ,reatin! a 0ile from a -RA
This a""o;s us to specify the path re"ative"y to the curre!t c"assD
public class Runnable_Test
{
public static void main(String[] args) throws FileNotFoundException
{
String file_path = "palette.xml";
URI uri = Runnable_Test.class.get.esource(file_path).to:.I();
File monFichier = new File(uri);
1.1.1.1." <isc.
1.1.1.1.".1 ,onvertin! an -R? to a 0ile 6 ,reatin! from an -R?
)ometimes ;e ;i"" receive a! KR2 from a AP? fu!ctio! =e.&. ;he! "oadi!& a resourceD public URL
getResource(String resource_name) >. )o eve! thou&h ;eIve see! itIs prefera$"e to create a 7i"e from a! KR? ;eI""
have to ;or5 from that KR2.
Appare!t"y there is !o direct fu!ctio!
httpDCC;e$"o&s.8ava.!etC$"o&C5ohsu5eCarchiveC244,C44Cho;WtoWco!vert.htm" su&&estsD
File f;
try
{ f = new File(url.toURI());
}
catch(URISyntaxException e)
{ f = new File(url.getPath());
}
6.1.1.2 Readin!
1.1.1.2.1 Readin! from a file
?s do!e usi!& the o$8ect 7i"e?!put)tream =stream U se6ue!ce of data> a!d 7i"eOutput)tream.
// Method 1
InputStream f = new FileInputStrea$("C:/java/hello");
// Method 2
File f = new File("C:/java/hello");
InputStream f = new FileInputStrea$(f);
44
1.1.1.2.1.1 Panilla )to a $yte array+
try
{ String filename = "//192.168.25.250/tp/enonces/HomogenousVector.class";
InputStream in = new FileInputStrea$(filename);
byte[] data = new byte[in.availa%le()];
in.read(data);
in.close();
return data;
}
catch (FileNotFoundException e)
{ throw new Class)otFoundException("File not found", e);
}
catch (IOException e)
{ throw new Class)otFoundException("IO error", e);
}
1.1.1.2.1.2 Bith apache commons )to a trin! or $yte array+
httpDCCcommo!s.apache.or& 7i"eKti"s
To a )tri!&D
return FileUtils.readFile3oString(file);
To a byte[]
IOUtils.toByteArray(new FileInputStream(logoFile))
1.1.1.2.2 Readin! from a -R?
This sectio! may $e outdated. ?tIs pro$a$"y $etter to use KR? tha! KR2 =see a$ove>
httpDCCdocs.orac"e.comC8avaseCtutoria"C!et;or5i!&Cur"sCreadi!&KR2.htm"
3%amp"eD
String config_file_path = 0EFA:L351E):S5CO)FI;5.ESO:.CE;
URL config_url = this.getClass().get.esource(config_file_path);
// Open a stream to the file using the URL.
StringBuffer fBuf = new StringBuffer () ;
try
{
InputStream in = config_url.openStrea$ ();
BufferedReader dis = new Buffered.eader (new InputStrea$.eader (in));
String line;
while ( (line = dis.readLine ()) != null)
{ fBuf.append (line + "\n");
}
in.close ();
}
catch (IOException e)
{ return e.get1essage();
}
//return StringEscapeUtils.escapeHtml(fBuf.toString());
return fBuf.toString();
6.1.1.3 Britin!
FileOutputStream fos = new FileOutputStrea$("signature.txt");
fos.write(signature);
fos.close();
6.1.1.4 Bor/in! .ith paths
1.1.1.#.1 >et path of6inside a class
http://stackoverflow.com/questions/778187/getting-directory-path-to-class-file-containing-main
:et path of curre!t c"ass =.ai!.c"ass>D
URL main = Main.class.getResource("Main.class");
if (!"file".equalsIgnoreCase(main.getProtocol()))
4'
throw new IllegalStateException("Main class is not stored in a file.");
File path = new File(main.getPath());
:et path of fi"e re"ative to c"assD
This sectio! may $e outdated. ?tIs pro$a$"y $etter to use KR? tha! KR2
public class Main
{
public static void main(String[] args)
{
String file_path = "scrapbook.rdf";
URL url = Main.class.getResource(a_xml_path_in);
// File is now accessible:
myDocument.load(/*String*/ url.getPath()); // returns the full path of the url
1.1.1.#.2 Basename, e&tension name
httpDCCstac5overf"o;.comC6uestio!sC4'4'13,C8avaGsp"itti!&GtheGfi"e!ameGi!toGaG$aseGa!dGe%te!sio!
6.1.1.5 Bor/ .ith the file system )directories+
1.1.1.%.1 Print contents of current directory
public static void printContents()
{
File f=new File(".");
System.out.println(f.getA%solute2ath());
String[] liste=f.list();
for (int i=0; i<liste.length; i++)
{ File ff=new File(liste[i]);
if (ff.is0irector()) System.out.println("Dossier \t"+liste[i]);
else System.out.println(""+ff.length()+" \t"+liste[i]);
}
}
Output e%amp"eD
F:\02-COMPUTING\71-CODE\10-BY_LANGUAGE_[for_doc_purposes]\JAVA\Z-TESTS (Eclipse project)\.
Dossier .settings
Dossier bin
Dossier src
892 .classpath
383 .project
32 00-Description.txt
Dossier lib
6.1.1.6 'pache ,ommons Ao
httpDCCcommo!s.apache.or&CioC
1.1.2 -sin! the class?oader to load a resource 4class loader, locate file5
6.1.2.1 Doc )to sort out+
httpDCCco&!itivecache.$"o&spot.comC244+C4,C8avaG"oadi!&G%m"Gfi"eGfromGc"asspath.htm"
httpDCC;;;.8ava;or"d.comC8ava;or"dC8ava6aC2443G4+C41G6aG4+4+Gproperty.htm"Ppa&eU2
httpDCC"itt"etutoria"s.comC244+C43C2*C"ocati!&GresourcesGi!G8avaC
httpDCC;;;.codera!ch.comCtC3+4+1'C8avaC8avaCc"ass"oaderG&etResource
httpDCCstac5overf"o;.comC6uestio!sC'113,+*Cho;GtoGuseGc"ass"oaderG&etresourcesGcorrect"y
@There is !o ;ay to recursive"y search throu&h the c"asspath. \ou !eed to 5!o; the 7u"" path!ame of a resource to $e
a$"e to retrieve it i! this ;ay. The resource may $e i! a directory i! the fi"e system or i! a 8ar fi"e so it is !ot as simp"e as
performi!& a directory "isti!& of Vthe c"asspathV. \ou ;i"" !eed to provide the fu"" path of the resource e.&.
ICcomCmypathC$"a.%m"I.A
=httpDCCstac5overf"o;.comC6uestio!sC'113,+*Cho;GtoGuseGc"ass"oaderG&etresourcesGcorrect"y>
4*
@use a";ays ECF i! the path a!d !ot File.separatorChar. O! Oi!do;s the File.separatorChar ;i"" provide
some positive resu"ts $ut for sure the so"utio! is !ot porta$"e a!d !ot safe.A
=httpDCC"itt"etutoria"s.comC244+C43C2*C"ocati!&GresourcesGi!G8avaC>
6.1.2.2 =o.to
)earchi!& for a resource is al3a&s 'one in the en'5 b& the class loa'er.
/o;ever some !re-!rocessing ;i"" $e do!e if ca""i!& <class>.getResource() i!stead of
<class>.getClassLoader().getResource()
1.1.2.2.1 Pia class
i.e. usi!&D <class>.getResource(resource)D some !re-!rocessing is 'one
1.1.2.2.1.1 2avadoc
httpDCCdocs.orac"e.comC8avaseC1.'.4CdocsCapiC8avaC"a!&C("ass.htm"c&etResourced2+8ava."a!&.)tri!&d21
pu$"ic *1) &etResource=String resourceW!ame>

=#> de"e&ates the search to this o$8ectIs c"ass "oader. =#>.
Before de"e&atio! -to the the c"ass"oaderFs getResource(absolute_resource_name)0 a! a$so"ute resource !ame is
co!structed from the &ive! resource !ame usi!& this a"&orithmD
G if the !ame $e&i!s ;ith a ICI the! the a$so"ute !ame of the resource is the portio! of the !ame fo""o;i!& the ICI.
G other;ise the a$so"ute !ame is of the fo""o;i!& formD
modified_package_name/resource_name
;here modified_package_name is the pac5a&e !ame of this o$8ect -7/? i.e. of the c"ass0 ;ith ICI su$stituted for I.I
Conse7uenceD if passed a resource !ame !ot $e&i!!i!& ;ith @CA the resource ;i"" appear to $e searched for at the root
of the pac5a&e of the c"ass.
1.1.2.2.1.2 8&ample7
pac2age com.sfr.fwl.plugins.plugin_menu.action_plugins;
public class PluginMenu extends Plugin
{
private MenuLoader getMenu'oader()
{ ...
String config_file_path = "menus.config.xml";
URL config_url = this.getClass().get.esource(config_file_path);
The fo""o;i!& ;ou"d a"so ;or5D
String config_file_path = "../conf/menus.config.xml";
;ith the co!fi& fi"e $ei!& p"aced i! fo"der (...)/plugin_menu/conf
1.1.2.2.2 via ,lass?oader
i.e. usi!&D <class>.getClassLoader().getResource()
T/0/: re%rite section
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("monfichier.txt ");
URL monFichierURL = getClass().getClassLoader().getResource("monfichier.txt");
File monFichier = new File(monFichierURL.getFile());
4,
1.1.2.2." An a static conte&t
MyClass.class.get.esource(2.O2E.345FILE);
6.1.2.3 8&ample 6 ,ode to do some resource9loadin! testin!
ArrayList<String> resources = new ArraList () ;
resources.add("MenuMain.config.xml");
resources.add("/MenuMain.config.xml");
resources.add("com/sfr/webapp/project/act/MenuMain.config.xml");
resources.add("/com/sfr/webapp/project/act/MenuMain.config.xml");
for (String resource : resources)
{ /* */ this.logger.de%ug("Looking for resource: " + resource);
/* */ this.logger.de%ug("-with currentThread.contextClassLoader: ");
URL url = Thread.current3hread().getContextClassLoader().get.esource(resource);
if (url == null)
{ /* */ this.logger.de%ug("--NOT FOUND " );
}
else
{ String fileName = url.getFile();
/* */ this.logger.de%ug("--FOUND ! " + url.get2ath());
}
/* */ this.logger.de%ug("-with getClass().getResource: ");
url = getClass().get.esource(resource);
if (url == null)
{ /* */ this.logger.de%ug("--NOT FOUND ");
}
else
{ String fileName = url.getFile();
/* */ this.logger.de%ug("--FOUND ! " + url.get2ath());
}
}
7or e%amp"e the fo""o;i!& a$ove yie"dedD
Looking for resource: MenuMain.config.xml
-with currentThread.contextClassLoader:
--FOUND ! /C:/Documents%20and
%20Settings/fhill/Eclipse_workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/edf_pro_crc/
WEB-INF/classes/MenuMain.config.xml
-with getClass().getResource:
--NOT FOUND
Looking for resource: /MenuMain.config.xml
-with currentThread.contextClassLoader:
--FOUND ! /C:/Documents%20and
%20Settings/fhill/Eclipse_workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/edf_pro_crc/
WEB-INF/classes/MenuMain.config.xml
-with getClass().getResource:
--FOUND ! /C:/Documents%20and
%20Settings/fhill/Eclipse_workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/edf_pro_crc/
WEB-INF/classes/MenuMain.config.xml
Looking for resource: com/sfr/webapp/project/act/MenuMain.config.xml
-with currentThread.contextClassLoader:
--FOUND ! /C:/Documents%20and
%20Settings/fhill/Eclipse_workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/edf_pro_crc/
WEB-INF/classes/com/sfr/webapp/project/act/MenuMain.config.xml
-with getClass().getResource:
--NOT FOUND
Looking for resource: /com/sfr/webapp/project/act/MenuMain.config.xml
-with currentThread.contextClassLoader:
--FOUND ! /C:/Documents%20and
%20Settings/fhill/Eclipse_workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/edf_pro_crc/
WEB-INF/classes/com/sfr/webapp/project/act/MenuMain.config.xml
-with getClass().getResource:
--FOUND ! /C:/Documents%20and
%20Settings/fhill/Eclipse_workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/edf_pro_crc/
WEB-INF/classes/com/sfr/webapp/project/act/MenuMain.config.xml
1.1." Properties
6.1.3.1 ?oadin! properties
3%amp"e $T/0/ sort out&
/**
* )oad a properties file from the classpath
4+
* @param propsName
* @return Properties
* @throws Exception
*/
public static Properties load(String propsName) throws Exception {
Properties props = new Properties();
URL url = ClassLoader.getSystemResource(propsName);
props.load(url.openStream());
return props;
}
/**
* )oad a 'roperties 0ile
* @param propsFile
* @return Properties
* @throws IOException
*/
public static Properties load(File propsFile) throws IOException {
Properties props = new Properties();
FileInputStream fis = new FileInputStream(propsFile);
props.load(fis);
fis.close();
return props;
}
3%amp"eD
URL url = this.getClass().get.esource(pluginConfFile2ath);
/* */ if (null == url) throw new 2luginSupporterException(msg, null);
pluginConf2roperties = new 2roperties();
pluginConf2roperties . load(url.openStrea$());
String property = pluginConf2roperties.get2ropert(key);
6.1.3.2 Overrida$le properties
Kse org.apache.commons.configuration.CompositeConfiguration
http://commons.apache.org/configuration/index.html
http://commons.apache.org/configuration/userguide/user_guide.html
3%amp"e of useD
/**
* Return a properties object loaded from a properties file, with an overrding mechanism.
* Example of use: file 'my_properties.PROD.properties' should override file 'my_properties.properties'
*
* @param fileName as used by org.apache.commons.configuration.PropertiesConfiguration(fileName). Full
file path is
* probably a good option.
* @param overridingMidfix Part between the file base and the file suffix (aka postfix), all parts
being separated by
* a dot (.), indicating the overriding strategy, i.e. the properties file with
this midfix
* will override the properties file without the midfix.
* The actual mechanism of loading the files and defining the overriding is
delegated to
* org.apache.commons.configuration.PropertiesConfiguration.
* Ex: properties defined in
* my_properties.PROD.properties
* will override properties defined in
* my_properties.properties
* provided that passed 'fileName' and 'overridingMidfix' are resp.:
'my_properties.properties
* and 'PROD'.
* The overriding properties file is optional.
* @return the resulting Properties file, or an equivalent object (see also
org.apache.commons.configuration.PropertiesConfiguration)
*/
public static CompositeConfiguration loadCon#iguration (String fileName, String overridingMidfix)
{
/* */ String err_msg = "Error loading the properties for the given property file and
midfix = {"
41
/* */ + fileName + "," + overridingMidfix + "}";
/* */ try
/* */ {
// 1. Compute the overriding file's name: by insert the midfix:
LinkedList<String> fileNameSplits = new
Lin=edList<String>(Arrays.asList(fileName.split("\\.")));
String pop = fileNameSplits.re$oveLast();
fileNameSplits . addLast(overridingMidfix);
fileNameSplits . addLast(pop);
String fileName_overriding =
org.apache.commons.lang.StringUtils.*oin(fileNameSplits, ".");
// 2. Load
CompositeConfiguration config = new Co$positeConfiguration();
// Careful with the order for composite: commons.configuration searches for the property in the
added files,
// in THE ORDER in which they are added. -> overriding files first !
// The following bhoth throw ConfigurationException:
// We'll silent the fist because an overriding properties file is optional
// but we'll let the second one go through.
/* */ try
/* */ {
config . addConfiguration(new
2ropertiesConfiguration(fileName_overriding));
/* */ }
/* */ catch (ConfigurationException e)
/* */ { String msg = "Could not load properties file: {" + fileName_overriding +
"}. This MAY be perfectly all right.";
/* */ if (de%ugOn) slogger.de%ug(msg);
/* */ }
config . addConfiguration(new 2ropertiesConfiguration(fileName
));
return config;
/* */ }
/* */ catch (ConfigurationException e)
/* */ {
/* */ if (de%ugOn) slogger.de%ug(err_msg);
/* */ throw new Overrida%le2ropertiesException(err_msg, e);
/* */ }
/* */ catch (Exception e)
/* */ {
/* */ if (de%ugOn) slogger.de%ug(err_msg);
/* */ throw new Overrida%le2ropertiesException(err_msg, e);
/* */ }
}
/**
* Convenience. Returns a java.util.Properties rather than a org.apache.commons.configuration
*/
public static Properties load!roperties (String fileName, String overridingMidfix)
{
// Convert from a Configuration to a java.util.Properties:
return ConfigurationConverter.get2roperties(loadConfiguration (fileName, overridingMidfix));
}
// ==========================================================================
// LOGGING
// ==========================================================================
private static Log slogger= LogFactory.getLog("com.fhi.fjl.properties");
/**
* Use if in need to use a different logger than the default one.
* Default logger is log4j logger of name "com.fhi.fjl.properties".
'4
* @return
* @used#by IoC (e.g. spring) if in need of slogger other than the default one specified above
*/
public static void setSlogger(Log logger)
{ slogger = logger;
}
/**
* Activate or deactivate logs of debug level for this class
* To deactivate debugging for this class, set to false. This is final i.e. in that case, there will be
no logging of level debug.
* To activate debugging for this class, set to true. The decision of logging of level debug will be
left to higher levels.
*/
protected static boolean de%ugOn = true
&& slogger.is0e%ugEna%led();
6.1.3.3 ,onvert resource $undle to properties
public static Properties convert1esourceBundleo'roperties(ResourceBundle resource)
{
Properties properties = new Properties();
Enumeration<String> keys = resource.getKeys();
while (keys.hasMoreElements())
{ String key = keys.nextElement();
properties.put(key, resource.getString(key));
}
return properties;
}
Or useD httpDCCdocs.orac"e.comC8avaseC1.4.2CdocsCapiC8avaCuti"CPropertyResourceBu!d"e.htm" i!stead
1.1.# ResourceBundle
httpDCCdocs.orac"e.comC8avaseC1.4.2CdocsCapiC8avaCuti"CResourceBu!d"e.htm"c&etBu!d"e=8ava."a!&.)tri!& 8ava.uti".2oca"e
8ava."a!&.("ass2oader>
6.1.4.1 !etBundle)+
.esourceBundle 8ava.uti"..esourceBundle.&etBu!d"e=String $aseMame Locale "oca"e>
:ets a resource $u!d"e usi!& the specified $ase !ame a!d "oca"e a!d the ca""erIs c"ass "oader. #
1arametersD
baseName the $ase !ame of the resource $u!d"e a fu""y 6ua"ified c"ass !ame
-8avadoc0
A fu""y 6ua"ified c"ass !ame U pac5a&e !ame. 3%amp"eD com.fhi.package.myClass com.fhi.package.myResource
=for the fi"e /com/fhi/package/myResource.properties>.
:et the pac5a&e !ame of a c"ass U getClass().getCanonical)a$e();
)tarti!& from 8ava versio! P it seems getBundle() !o "o!&er accepts a fi"e path for ar&ume!t basename.
Kse this fu!ctio! to co!vertD
pac2age com.fhi.fjl.util;
public class PropertiesUtil
{
/**
* Converts a file path, e.g. "/com/fhi/fjl/my_props.properties",
* to a package path, e.g. "com.fhi.fjl.my_props", so as to be readily usable by
* such functions as java.util.ResourceBundle.getBundle(String baseName, Locale locale).
* The ".properties" extension will be stripped. (it needs to be that exact extension).
*
* @param filePath
* @param absolute if true, add a leading "/"
*/
public static String con(ertFile!athTo!ackage!ath(String filePath)
{ String ret = filePath.replace("/", ".");
// Strip any leading / :
filePath = Filename.stripLeadingSlash(filePath);
'1
filePath = StringUtils.re$oveEnd(filePath, ".properties");
return filePath;
}
#
3%amp"e of useD
ResourceBundle def_res_bundle =
ResourceBundle.getBundle(PropertiesUtil.convertFile2ath3o2ac=age2ath(def_res_file_path), locale);
1.2 Anputstreams, BufferedReaders & co
They are a! i""ustratio! of the VdecoratorV patter! G this is ;hy there are so ma!y
3
-- convert String into InputStrea$
InputStream is = new ByteArrayInputStream(str.getBytes());

-- read it with Buffered.eader
BufferedReader br = new BufferedReader(new InputStreamReader(is));

String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
1." DO<, Q<?
1.".1 Doc & Ref
Tutoria"D httpDCCdo;!"oad.orac"e.comC8avaeeC1.4Ctutoria"CdocCi!de%.htm" chapter *
AP? docD httpDCCdo;!"oad.orac"e.comC8avaseC1.4.2CdocsCapiCi!de%.htm" pac5a&e or&.;3c.dom
httpDCCdo;!"oad.orac"e.comC8avaseC*CdocsCtech!otesC&uidesC%m"Ci!de%.htm"
3%amp"esD httpDCC8ava.su!.comCdeve"operCcodesamp"esC%m".htm"cdom
1.".2 (ode types and values
httpDCCdo;!"oad.orac"e.comC8avaseC1.4.2CdocsCapiCi!de%.htm"
no'eT&!e
no'eT&!e val
=to chec5>
no'eName no'e8alue $in Java% attributes
Attr 2 !ame of attri$ute va"ue of attri$ute !u""
(9ATA)ectio! 4 "#cdata-section" co!te!t of the (9ATA )ectio! !u""
(omme!t + "#comment" co!te!t of the comme!t !u""
9ocume!t 1 "#document" !u"" !u""
9ocume!t7ra&me!tP V V !u"" !u""
9ocume!tTypeP docume!t type !ame !u"" !u""
3"eme!t 1 ta& !ame !u"" MamedMode.apP
3!tity * e!tity !ame !u"" !u""
3!tityRefere!ceP ' !ame of e!tity refere!ced !u"" !u""
Motatio! !otatio! !ame !u"" !u""
Processi!&?!structio!P , tar&et e!tire co!te!t e%c"udi!& the tar&et !u""
Te%t 3 "#text" co!te!t of the te%t !ode !u""
3
/ead 7irst 9esi&! Patter!s
'2
1."." ?oad Q<? document, Duery a QPath
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import fjl.dom.DOMXPath;
Document document;
String xmlFileName = "example.xml";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//factory.setValidating(true); -> use if xml document is to be validated against a provided dtd
factory.setNamespaceAware(true);
/* */ try
/* */ {
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse( new File(xmlFileName) );
fjl.dom.DOMXPath xpath = new DOMXPath(document);
/* */ try
/* */ {
NodeList nl = xpath.query("//person");
/* */ logger.debug("node list length=" + nl.getLength());
/* */ logger.debug("node list =" + fjl.dom.Util.printNodeList(nl));
/* */ }
/* */ catch (XPathExpressionException e)
/* */ {
/* */ // !"! Auto-generated catch block
/* */ e.printStackTrace();
/* */ }
/* */ }
/* */ catch (SAXParseException e)
/* */ {
/* */ // Error generated by the parser
/* */ String err_msg = "Error occurred while parsing file {" + filename + "}, line " +
e.getLineNumber() + ", uri " + e.getSystemId();
/* */ String exp_msg = "Exception: " + e.getClass().getName() + ", message: " +
e.getMessage();
/* */ logger.debug(err_msg);
/* */ logger.debug(exp_msg);
/* */ throw new RdfDocumentLoadException(err_msg, e);
/* */ }
/* */ catch (SAXException e)
/* */ {
/* */ // Error while parsing:
/* */ String err_msg = "Error occurred while parsing file {" + filename + "}";
/* */ logger.debug(err_msg);
/* */ throw new RdfDocumentLoadException(err_msg, e);
/* */ }
/* */ catch (ParserConfigurationException e)
/* */ {
/* */ // Parser with specified options can't be built
/* */ String err_msg = "Error: parser with specified options can't be built for file {" +
filename + "}";
/* */ logger.debug(err_msg);
/* */ throw new RdfDocumentLoadException(err_msg, e);
/* */ }
/* */ catch (IOException e)
/* */ {
/* */ // I/O error
/* */ String err_msg = "I/O Exception while loading file {" + filename + "}";
/* */ logger.debug(err_msg);
/* */ throw new RdfDocumentLoadException(err_msg, e);
/* */ }
'3
1.".# ?oop throu!h (ode?ist and (amed(ode<ap
)ee f8".dom.Kti".pri!tMode a!d pri!tMode2ist
1.".% (ode values
9epe!di!& o! the !ode type the !odeVa"ue ta5es o! differe!t va"ues
(arefu" R This is differe!t from P/P !odeVa"ue R
httpDCCdocs.orac"e.comC8avaseC,CdocsCapiCor&C;3cCdomCMode.htm"
?f a !ode co!tai!s te%tD
<elem>this is text content<elem>
?f !ode correspo!ds to ]e"emH to retrieve the co!te!tD
node.getTextValue();
or
node.getFirstChild().getNodeValue();
6.3.5.1 !etTe&t,ontent)+
This attri$ute retur!s the te%t co!te!t of this !ode an' its 'escen'ants
1.".1 >et (ode value )as in P=P+
The fu!ctio! &etModeVa"ue=> i! P/P retur!s the co!te!t =i! $et;ee! the ta&s> of the !ode if itFs a 9O.3"eme!t. ?!
Java it retur!s !u"". OeF"" have to "oop throu&h the chi"d !odes a!d co!cate!ate their co!te!tsD
public static String getNodeValue(Node node)
{
StringBuffer buf = new StringBuffer();
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++)
{
Node textChild = children.item(i);
if (textChild.getNodeType() != Node.TEXT_NODE)
{ System.err.println("Mixed content! Skipping child element " + textChild.getNodeName());
continue;
}
buf.append(textChild.getNodeValue());
}
return buf.toString();
}
'4
1.".3 Q<? parsin!
httpDCC;;;.8ava2s.comC(odeCJavaCJ)PCJ)PParsi!&usi!&the9O..htm
1.".@ Q?T
httpDCC;;;.orei""y!et.comCpu$CaCorei""yC8avaC!e;sC8ava%s"tW4+41.htm"
1.# (et
httpDCCstac5overf"o;.comC6uestio!sC2,131'4Cho;GtoGuseG8avaG!etGur"co!!ectio!GtoGfireGa!dGha!d"eGhttpGre6uests
1.% Other 'PAs
1.%.1 ,olor
6.5.1.1 Bor/in! .ith ,olor
// makes a color object for R:255, G:0, B:150
Color aColor = new Color(0xFF0096); // Use the hex number syntax
// Alternatively, use Color.decode
Color bColor = Color.decode("#" + "FF0096");
public String print)eColor(Color col)
{ // a direct conversion to hex from the int returned by col.getRGB() gives us problematic
results if int returned is negative
String col_hex = java.lang.Integer.toHexString( col.get.ed() ) +
java.lang.Integer.toHexString( col.get;reen() ) +
java.lang.Integer.toHexString( col.getBlue() );
return "#" + col_hex;
}
6.5.1.2 ,olor manipulation li$rary :
)tra!&e"y e!ou&h there does!It seem to e%ist a!y.
1.1 ,ipherin!, crypto!raphy, security
1.1.1 >eneratin! a /ey
// Shared (symmetric) key:
SecretKeySpec s=epSpec;
// Create a key generator based upon the Blowfish cipher:
KeyGenerator keyGenerator = KeyGenerator.getInstance("Blowfish");
keyGenerator.init(128);
// Create secret key:
SecretKey secretkey = keyGenerator.generate(e();
// Get the key in its primary encoding format:
byte[] raw = secretkey.getEncoded();
// Generate a (stronger ?) secret key based on our the array of bytes provided by our first key, using
BlowFish:
s=epSpec = new Secret(eSpec(raw, "Blowfish");
1.1.2 8ncryptin!
Ksi!& 5ey &e!erated a$ove.
// Create a cipher based upon Blowfish
Cipher cipher = Cipher.getInstance("Blowfish");
// Initialise cipher with secret key
cipher.init(Cipher.E)C.42351O0E, s=epSpec);
// Get the text to encrypt: read it from console input:
Scanner in = new Scanner(System.in);
''
String inputText = in.nextLine(); // Reads a single line from the console:
// Encrypt message
byte[] encrypted = cipher. doFinal(inputText.getBtes());
/* */ Sste$AoutAprintln ("Encrypted message : " + new String(encrypted, "ISO-8859-1"));
Ksi!& 5ey &e!erated a$ove.
// Create a cipher based upon Blowfish
Cipher cipher = Cipher.getInstance("Blowfish");
// Initialise cipher with secret key
cipher.init(Cipher.0EC.42351O0E, s=epSpec);
// Decrypt message
byte[] decryptedText = cipher.doFinal(messageToDecrypt.getBtes());
/* */ Sste$AoutAprintln ("Decrypted message : " + new String(decryptedText, "ISO-8859-1"));
1.1." i!nin! a messa!e )!uaranteein! inte!rity+
3
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
...
static PrivateKey priv ;
static PublicKey pu% ;
/**
* Sign a message with a private key
*/
private static void sign() throws
NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException, SignatureException, IOException
{
Signature rsa = Signature.getInstance("MD5withRSA");
rsa.initSign(priv);
// Read message to encrypt: a single line from console input:
/* */ print ("Message to sign?");
Scanner in = new Scanner(System.in);
String inputText = in.nextLine();
// Sign message:
rsa.update(inputText.getBtes());
byte[] signature = rsa.sign();
/* */ print ("Signature of message is: " + new String(signature, "ISO-8859-1"));
// Store signature in file for our next test function (signature verification function)
...
}
/**
* verify the integrity of a received message, using the public key
*/
private static void (eri#ySignature() throws
NoSuchAlgorithmException, InvalidKeyException, SignatureException, IOException
{
// 1.Read "received" message from input (simulate reception):
/* */ print ("Message received?");
Scanner in = new Scanner(System.in);
String received_message = in.nextLine();
// 2.Read "received" signature (simulate reception) via file rather than via Console input
// which seems to exhibit problems with encoding
FileInputStream fis = new FileInputStrea$("signature.txt");
byte[] received_signature = new byte[fis.availa%le()];
fis.read(received_signature);
fis.close();
// 3. Check if signature is OK:
Signature rsa = Signature.getInstance("MD5withRSA");
rsa . init'erif(pu%) ;
rsa . update (received_message.getBtes());
boolean is_integrity_ok = rsa.verif(received_signature);
'*
/* */ print (is_integrity_ok ? "OK" : "NOK: MESSAGE HAS BEEN TAMPERED WITH.");
}
1.1.# Reystores and permission
/**
* Dans ce TP:
* 1. On gnre un keystore (= magasin de certificats) avec l'outil (ligne de commande keytool):
* et avec un premier certificat ("fhi") (la commande ci-dessous fait les 2 en mme temps).
*
* > keytool -keystore fhiKeyStore -genKey -keyalg RSA -alias fhi
* Tapez le mot de passe du Keystore : 123456
* Ressaisissez le nouveau mot de passe : 123456
* Quels sont vos prnom et nom ?
* [Unknown] : Francois Hill
* Quel est le nom de votre unit organisationnelle ?
* [Unknown] : FHI CORP
* Quelle est le nom de votre organisation ?
* [Unknown] : FHI CORP
* Quel est le nom de votre ville de rsidence ?
* [Unknown] : TOULOUSE
* Quel est le nom de votre tat ou province ?
* [Unknown] : FRANCE
* Quel est le code de pays deux lettres pour cette unit ?
* [Unknown] : FR
* Est-ce CN=Francois Hill, OU=FHI CORP, O=FHI CORP, L=TOULOUSE, ST=FRANCE, C=FR ?
* [non] : O
* Spcifiez le mot de passe de la cl pour <fhi>
* appuyez sur Entre s'il s'agit du mot de passe du Keystore) :
*
*
* 2. On cre du code "tiers" (simul) que l'on va jariser en le signant avec un certificat (issu du keystore
cr ci-dessus).
* Signer le jar: via la commande en ligne:
* (doc: http://docs.oracle.com/javase/tutorial/deployment/jar/signing.html)
* > jarsigner -keystore <url> -storepass <password> -keypass <password> <pathname of the JAR file that's to
be signed> <alias>
* soit:
* > cd "C:\Documents and Settings\Administrateur\workspace\Formation_Securite_TP_6_Keystore_et_Permissions"
* > jarsigner "fhi_third_party_code.jar" "fhi" -keystore "file:///C:/Documents%20and
%20Settings/Administrateur/workspace/fhiKeyStore" -storepass "123456" -keypass "123456"
*
* 3. On cre une appli client (simul) qui va utiliser le jar "tiers" en lui octroyant
* certains droits seulement si le jar est sign par "fhi".
* L'appli client doit avoir accs un keystore contenant le certificat "fhi" (pour les besoins du TP on
* utilisera le mme keystore qu' l'tape prcdente) et vrifier, donc, que le jar est bien "legit".
*
* 4. Ou alors pour automatiser les 2 oprations ci-dessus, utiliser un ant: voir build.xml
*
* 5. On lance ce Main, avec
* 5.1 Le fichier Main.policy qui autorise la suppression de fichier (c'est ce que fait fhi.ThirdParty)
* 5.2. Le mme fichier, rdit pour ne PAS autoriser la suppression de fichier
*
* @author fhi
* @since 2013.06.05
*/
public class Main
{
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, SignatureException, IOException
{
/* */ print("yo");
',
// Execute "3rd party code" (with permission controls)
fhi.ThirdPartyCode.sensitiveOperation();
}
public class ThirdPartyCode
{
static public void sensiti(e&peration()
{
// E.g. delete files
print("OPERATION SENSIBLE");
deleteFile("fichiers_sensibles/FicSensible");
}
public static void deleteFile(String fileName)
{ print("Deleting file : " + fileName);
...
To simp"ify testi& operatio!s the fo""o;i!& a!t ca! $e usedD
<?xml version="1.0" encoding="UTF-8" ?>
<project name="HelloWorld" basedir="." default="sign">
<property name="jdk.home" value="C:/Program Files/Java/jdk1.6.0_30" />
<property name="jar" value="my.jar" />
<property name="class.dir" value="./bin" />
<property name="keystore" value="myKeystore"/>
<property name="alias" value="moi"/>
<property name="storepass" value="myPassword"/>
<path id="classpath">
<fileset dir="${jdk.home}" includes="lib/*.jar" />
</path>
<target name="sign">
<delete file="${keystore}"/>
<genkey alias="${alias}" keystore="${keystore}" storepass="${storepass}">
<dname>
<param name="CN" value="Leuville Objects"/>
<param name="OU" value="Java division"/>
<param name="O" value="leuville.com"/>
<param name="C" value="FR"/>
</dname>
</genkey>
<delete file="${jar}"/>
<jar destfile="${jar}" basedir="${class.dir}"/>
<signjar jar="${jar}"
signedjar="${jar}"
alias="${alias}"
keystore="${keystore}"
storepass="${storepass}"
lazy="true"
>
</signjar>
</target>
</project>
.ai!.po"icyD
keystore "file://C:/Documents and Settings/Administrateur/workspace/fhiKeyStore";
grant signedBy "fhi", codeBase "file:///C:/Documents and
Settings/Administrateur/workspace/Formation_Securite_TP_6_Keystore_et_Permissions/fhi_third_party_code.jar"
{ // Ici on accorde la permission au jar signs par fhi de supprimer les fichiers sensibles
permission java.io.FilePermission "./fichiers_sensibles/*", "delete";
// Ici, on n'accorde que la permission de lecture (dcommenter pour les tests et commenter au-dessus)
//permission java.io.FilePermission "C:/Documents and
Settings/Administrateur/workspace/Formation_Securite_TP_6_Keystore_et_Permissions/fichiers_sensibles/*",
"read";
};
1.1.% 2''
JAA) $ui"ds o! the permissio! system see! previous"y =po"icy fi"es> a!d i!troduces the co!cepts of rea"ms su$8ects =h
users ro"es #>
'+
1.3 Anternationalisation 4i1@n5
httpDCCdo;!"oad.orac"e.comC8avaseCtutoria"Ci1+!Ci!de%.htm"
1.@ ?o!!in!
1.@.1 ?o!!in! .ith lo!#F
6.8.1.1 Doc
httpDCC"o&&i!&.apache.or&C"o&48C1.2Cma!ua".htm"
httpDCC"o&&i!&.apache.or&C"o&48C1.2Cfa6.htm"
6.8.1.2 ?i$rary )Far+
6.8.1.3 -sa!e
// Imports for log4j
import org.apache.log4j.Logger;
public class Main
{
static Logger logger5lB* = Logger.getLogger("LOGGER_L4J");
public static void main(String[] args)
{
System.out.println("Hello world !");
/* */ Main.logger5lB*.debug("I am the l4j logger");
}
}
6.8.1.4 ,onfi!uration
There are severa" ;ays to co!fi&ure "o&48 amo!& ;hichD usi!& a .properties fi"e or a %m" fi"e.
9o !ot for&et to add the co!f fi"e to the $ui"d path. 2o&48 ;i"" automatica""y "ocate it.
'1
1.@.1.#.1 Q<? e&ample
<?xml version=C8A7C encoding=C:3F,DC ?>
<!DOCTYPE log4j:configuration PUBLIC "-//LOGGER"
"http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<!-- ==========================================================================
/**
* Project: FWL
* Client:
*
* @author fhi
* @since 2011.07
* @copyright SFR 2011
*/
========================================================================== -->
<log4j:configuration xmlns:log4j=Chttp/--*a=artaAapacheAorg-logB*-C>
<!-- APPENDERS (i.e. outputs) -->
<!-- ========================== -->
<!-- DOC: http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html -->
<!-- The chosen following layout is designed to facilitate log file post-processing (search, grep,
filtering ...)
Elements used:
[D:<date>]
[N:<name of logger>]
[C:<contextual info, e.g. UN: name of user, RA: remote address...>]
[L:<debug level>]
[O:<occurred at (place in code (class, method, line) where log occurred)>]
[M:<message>]
Patterns (memo):
%C : whole class name
%C{1} : short class name
%c : logger name (aka "category")
%c{n} : n last dot-separated name-components of logger name
%-5p : log level, width of 5 characters
-->
<appender name=CS30O:3C class=CorgAapacheAlogB*AConsoleAppenderC>
<layout class=CorgAapacheAlogB*A2atternLaoutC>
<!-- Short pattern for use while developing: -->
<!-- <param name="ConversionPattern" value="[N:%c{3}] %-5p %C{1}:%M(),%L - %m%n"/>-->
<!-- Full length pattern, for production: -->
<param name=CConversion2atternC value=CE0/FdGE)/FcHIJGEC/F<H:)J&F<H.AJGEL/F,KpGEO/FCH8J&
F1!#&FLGE1/F$GFnC/>
</layout>
</appender>
<appender name=CFILEC class=CorgAapacheAlogB*A0ail.ollingFileAppenderC>
<param name=CFileC value =CLHcatalinaAho$eJ-logs-fwl5de$o-dail5rollingAlogC />
<layout class=CorgAapacheAlogB*A2atternLaoutC>
<param name=CConversion2atternC value=CE0/FdGE)/FcHIJGEC/F<H:)J&F<H.AJGEL/F,KpGEO/FCH8J&
F1!#&FLGE1/F$GFnC/>
</layout>
</appender>
<!-- LOGGERS (aka "categories" ) -->
<!-- =========================== -->
<!-- Loggers inherit from "ancestors" as defined by the package-style name
"root" is the ancestor of all loggers.
-->
*4
<logger name=Cco$Aopens$phonC>
<level value=CI)FOC />
</logger>
<logger name=CorgAapacheAstruts6C>
<level value=CI)FOC />
</logger>
<logger name=CorgAapacheA*spC>
<level value=CI)FOC/>
</logger>
<logger name=CorgAspringfra$ewor=C>
<level value=CI)FOC/>
</logger>
<logger name=ClogB*AloggerAco$Ai%atisC>
<level value=CI)FOC/>
</logger>
<logger name=CsqlAresponseAti$eC>
<level value=CI)FOC/>
</logger>
<logger name=C*avaAsqlC>
<level value=CI)FOC/>
</logger>
<logger name=Cco$AfhiAf*lC>
<level value=CI)FOC />
</logger>
<logger name=Cco$AfhiAfwlC>
<level value=CI)FOC />
</logger>
<logger name=Cco$AfhiAfwlAcoreAutilAStruts:tilC>
<level value=CI)FOC />
</logger>
<logger name=Cco$AfhiAfwlAplugin5supportC>
<level value=CI)FOC />
</logger>
<logger name=Cco$AfhiAfwlApluginsC>
<level value=CI)FOC />
</logger>
<logger name=Cco$AfhiAfwlApluginsAplugin5sessionC>
<level value=CI)FOC />
</logger>
<logger name=Cco$AfhiAfwlApluginsAplugin5loginC>
<level value=CI)FOC />
</logger>
<logger name=Cco$AfhiAfwlApluginsAplugin5rightsC>
<level value=CI)FOC />
</logger>
<logger name=Cco$AfhiAfwlApluginsAplugin5$enuC>
<level value=CI)FOC />
</logger>
<logger name=Cco$AfhiAfwlApluginsAplugin5$e$5urlC>
<level value=CI)FOC />
</logger>
<logger name=Cco$AfhiAfwlApluginsAplugin5page5errorC>
<level value=CI)FOC />
</logger>
<logger name=Cco$AfhiAfwlApluginsAplugin5de%ugC>
<level value=CI)FOC />
</logger>
<logger name=Cco$AsfrApro*ectAconcernsAuserC>
<level value=CI)FOC />
</logger>
<logger name=Cco$AfhiAfwlApluginsAplugin5logB*C>
<level value=CI)FOC />
</logger>
<logger name=Cco$AfhiAfwlApluginsAplugin5de$oC>
*1
<level value=C0EB:;C />
</logger>
<logger name=Cco$AsfrApro*ectC>
<level value=CI)FOC />
</logger>
<logger name=Cco$AsfrApro*ectAcoreC>
<level value=CI)FOC />
</logger>
<logger name=Cco$AsfrApro*ectAconcernsAde%ugC>
<level value=C0EB:;C />
</logger>
<!-- Root logger, parent of all loggers
Any logger with no specific instructions will 'inherit' the root logger's settings.
-->
<root>
<priority value=CI)FOC/>
<appender-ref ref=CS30O:3C />
</root>
</log4j:configuration>
1.@.1.#.2 Properties format e&ample
# <!-- APPENDERS (i.e. outputs) -->
# <!-- ========================== -->
#
# <!-- DOC: http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html -->
#
# <!-- The chosen layout conversion pattern is designed to facilitate log file post-processing (search,
grep, filtering ...)
# Elements used:
# [D:<date>]
# [N:<name of logger>]
# [C:<contextual info, e.g. UN: name of user, RA: remote address...>]
# [L:<debug level>]
# [O:<occurred at (place in code (class, method, line) where log occurred)>]
# [M:<message>]
# Patterns (memo):
# %C : whole class name
# %C{1}: short class name
# %c : logger name (aka "category")
# %c{n}: n last dot-separated name-components of logger name
# %-5p : log level, width of 5 characters
# -->
log4j.appender.STDOUT = org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout = org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern = [D:%d][N:%c456][C:%X{UN},%X{RA}][L:%-5p][O:%C476,%M(),%L][M:
%m]%n
#log4j.appender.STDOUT.layout.ConversionPattern = [N:%c{3}] %-5p %C{1}:%M(),%L - %m%n
log4j.appender.FILE = org.apache.log4j.DailyRollingFileAppender
log4j.appender.FILE.file = ${catalina.home}/logs/fwl_demo/daily_rolling.log
log4j.appender.FILE.layout = org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern = [D:%d][N:%c456][C:%X{UN},%X{RA}][L:%-5p][O:%C476,%M(),%L][M:%m]
%n
# <!-- LOGGERS (aka "categories" ) -->
# <!-- =========================== -->
#
# <!-- Loggers inherit from "ancestors" as defined by the package-style name
# "root" is the ancestor of all loggers.
# -->
log4j.logger.com.foo = WARN
log4j.logger.com.opensymphony = INFO
log4j.logger.org.apache.struts2 = INFO
log4j.logger.org.apache.jsp = INFO
log4j.logger.org.springframework = INFO
log4j.logger.log4j.logger.com.ibatis = INFO
log4j.logger.sql.response.time = INFO
*2
log4j.logger.java.sql = INFO
log4j.logger.com.fhi.fjl = INFO
log4j.logger.com.fhi.fwl = INFO
log4j.logger.com.fhi.fwl.core.util.StrutsUtil = INFO
log4j.logger.com.fhi.fwl.plugin_support = INFO
log4j.logger.com.fhi.fwl.plugins = INFO
log4j.logger.com.fhi.fwl.plugins.plugin_session = INFO
log4j.logger.com.fhi.fwl.plugins.plugin_login = INFO
log4j.logger.com.fhi.fwl.plugins.plugin_rights = INFO
log4j.logger.com.fhi.fwl.plugins.plugin_menu = INFO
log4j.logger.com.fhi.fwl.plugins.plugin_mem_url = INFO
log4j.logger.com.fhi.fwl.plugins.plugin_page_error= INFO
log4j.logger.com.fhi.fwl.plugins.plugin_debug = INFO
log4j.logger.com.sfr.project.concerns.user = INFO
log4j.logger.com.fhi.fwl.plugins.plugin_log4j = INFO
log4j.logger.com.fhi.fwl.plugins.plugin_demo = DEBUG
log4j.logger.com.sfr.project = INFO
log4j.logger.com.sfr.project.core = INFO
log4j.logger.com.sfr.project.concerns.debug = WARN
log4j.rootLogger =INFO, STDOUT
1.@.1.#." Bhat happens if an undefined lo!!er )a/a cate!ory+ !ets called :
1.@.1.#.# ?ayouts
httpDCC"o&&i!&.apache.or&C"o&48C1.2CapidocsCor&CapacheC"o&48CPatter!2ayout.htm"
)ee a! e%amp"e i! sectio! o! M9(C.9(.
1.@.1.#.% Property e&pansion6interpolation 4system varia$les, I la 'nt5
1.@.1.#.1 Overridin! confi!uration file 4cascadin!5
A! e%amp"e of imp"eme!tatio! ca! $e fou!d i! the pro8ect 7O2.
http://stackoverflow.com/questions/4258849/override-log4j-properties
http://logging.apache.org/log4j/1.2/manual.html sectio! V9efau"t ?!itia"i<atio! ProcedureVD
// Configure Log4j with environment specific settings (if not already done)
// (It is assumed the underlying implementation of the 'org.apache.commons.logging.Log' returned
// is of type Log4j.)
Log4jConfigurer.configureLogB*(SystemUtil.getSste$Env());
public class SystemUtil
{
private static final String environ$ent2ropert)a$e = "env";
/**
* Get the system (or Tomcat server-defined) variable named "env".
*/
public static String getSystemEn(()
{
String env = java.lang.System.getenv().get(environ$ent2ropert)a$e);
return env;
}
)o it is possi$"e to have the fo""o;i!& setupD
*3
.
6.8.1.5 Positionnin! the confi! file
?t seems the co!fi& fi"e has to $e p"aces i! the same source fo"der as the piece of code that ca""s sets up the "o&&erD
/ere the set up ca"" is made i! f8".mai!..ai! =f8"Cf8"Cmai!C.ai!.8ava> a!d co!fi& fi"e is f8"C"o&48.%m"
Oith the same fi"es as a$ove the fo""o;i!& ;o!Ft ;or5 =2o&4J fai"s to "ocate "o&48.%m">D
*4
6.8.1.6 'dvanced
1.@.1.1.1 Brappin! lo!#F
)ee further a"o!&
1.@.1.1.2 ,reatin! oneLs o.n lo!#F lo!!in! levels
httpDCC8ai5ira!.;ordpress.comC244*C4,C12CcreateGyourGo;!G"o&&i!&G"eve"Gi!G"o&48C
(reati!& a "o&48 spri!& $ea!
<bean id=Clogger5$ainC class=CorgAspringfra$ewor=A%eansAfactorAconfigACo$$onsLogFactorBeanC>
<property name=Clog)a$eC value=Cco$AsfrAfwlC />
</bean>
<bean id=Cho$e5actC class=Cco$AsfrAfwlApagesAho$eAactAHo$eAC3C scope=CprototpeC>
<property name=CloggerC ref=Clogger5$ainC/>
</bean>
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class BaseACT extends ActionSupport implements SessionAware
{
// ==========================================================================
// LOGGING
// ==========================================================================
protected Log logger = LogFactory.getLog("com.sfr.fwl");
/**
* Static logger. Use in constructor methods when logger is possibly not set yet.
* Once one logger of one instance of this class has been set, this static logger
* becomes available (see setLogger).
* Since despite this, requests for logging can still be made before any sort
* initialisation of both loggers, the following attribute initialisation insures
* that the call will fail silently (and not throw a NPE)
*/
protected static Log slogger= LogFactory.getLog("com.sfr.fwl");
/**
* @used#by IoC (e.g. spring) if in need of logger other than the default one specified above
*/
public void set'ogger(Log logger)
{ this.logger = logger;
slogger = logger;
}
/**
* Activate logs of debug level for this class
* (Use in dev phase)
*/
protected boolean de%ugOn = true;
1.@.1.1." -sin! (D,6<D, to distin!uish clients 4users6threads5
Mested 9ia&!ostic (o!te%ts
*'
)ee httpDCC"o&&i!&.apache.or&C"o&48C1.2Cma!ua".htm"
3%amp"e of use i! the co!te%t of a ;e$appD
Oe ;a!t to trace the !ame of the user a!d or at "east his ?P address.
?! a struts2 i!terceptor ;e ca"" the fo""o;i!&D
public String intercept(ActionInvocation invocation) throws Exception
{
.
org.apache.log4j.MDC.put("RA", invocation.getAction().getRequest().get.e$oteAddr());
org.apache.log4j.MDC.put("UN", user_name);
a!d ;e co!fi&ure the "o&48 co!fi& fi"e as fo""o;sD
<log4j:configuration xmlns:log4j=Chttp/--*a=artaAapacheAorg-logB*-C>
<!-- The layout is designed to facilitate text processing (search, grep, filtering ...)
Elements used:
[D:<date>]
[N:<name of logger>]
[C:<contextual info, e.g. UN: name of user, RA: remote address...>]
[L:<debug level>]
[O:<occurred at (place in code (class, method, line) where log occurred)>]
[M:<message>]
Patterns (memo):
%C : whole class name
%C{1}: short class name
%c : logger name (aka "category")
%c{n}: n last dot-separated name-components of logger name
%-5p : log level, width of 5 characters
-->
<appender name=CS30O:3C class=CorgAapacheAlogB*AConsoleAppenderC>
<layout class=CorgAapacheAlogB*A2atternLaoutC>
<param name=CConversion2atternC value=CE0/FdGE)/FcHIJGEC/F<H:)J&F<H.AJGEL/F,KpGEO/FCH8J&
F1!#&FLGE1/F$GFnC/>
</layout>
.
1.@.1.1.# Blueprint for use .ith Ao, )prin!+
MyClass
{
#
// ==========================================================================
// LOGGING
// ==========================================================================
/**
* In case there is no logger injected through IoC via setLogger(), this is the logger that will be
* used in effect.
*/
protected Log logger = LogFactory.getLog("com.fhi.mypackage.myClass");
/**
* Static logger. Use in constructor methods when logger is possibly not set yet.
* Once one logger of one instance of this class has been set, this static logger
* becomes available (see setLogger).
* Since despite this, requests for logging can still be made before any sort
* initialisation of both loggers, the following attribute initialisation insures
* that the call will not throw a NPE. (indicate the name of real logger or not)
*/
protected static Log slogger = LogFactory.getLog("com.fhi.mypackage.myClass ");
/**
* @used#by IoC (e.g. spring) if in need of logger other than the default one specified above
*/
public void set'ogger(Log logger)
{ this.logger = logger;
slogger = logger;
// isDebugEnabled() is a check performed by the logger at the highest level: if debug is not
// enabled, this saves the overhead of computing the messages.
de%ugOn = de%ugOn && logger.is0e%ugEna%led();
**
}
/**
* Activate or deactivate logs of debug level for this class - statically (i.e. this decision is made
* at compile time)
*
* To deactivate debugging for this class, set to false. This will be is final i.e. there
* will be no logging of debug-level calls - provided all debug calls are shielded with the check:
* if (debugOn) .
* To allow (rather than 'activate') debugging for this class, set to true. The decision of actually
* logging debug-level calls will be left to higher levels (notably log4j settings).
*/
protected static boolean de%ugOn = true
&& slogger.is0e%ugEna%led();
// ==========================================================================
// BUSINESS
// ==========================================================================
public String myFunnction(.)
{ /* */ if (de%ugOn) logger.de%ug("<<");
// By shielding with the debugOn check, we save the cost of a costly message computation,
// unnecessary in the cases where the debug level is set to a higher than just DEBUG.
/* */ if (de%ugOn) logger.de%ug("This might incur unnecessary computing: " +
complicatedObject.evaluate() );
...
/* */ if (de%ugOn) logger.de%ug(">>");
return "";
}
1.@.2 ?o!!in! .ith common lo!!in!s
httpDCCcommo!s.apache.or&C"o&&i!&Ccommo!sG"o&&i!&G1.1.1C&uide.htm"
Ja5arta =Apache> (ommo!s 2o&&i!& =J(2> provides a "o&&i!& i!terface =a$stractio!> o!e "eve" a$ove "o&48. ?t e%poses
the usua" "o&&i!& fu!ctio!s a!d re"ies o! a choice amo!& a !um$er of imp"eme!ti!& "o&&i!& so"utio!sCtoo"5its ="o&48
)imp"e"o& Ava"o! #>
6.8.2.1 ?i$rary )Far+
The 8ar for the u!der"yi!& "o&&i!& so"utio! used shou"d a"so $e i!c"uded =here "o&48>.
6.8.2.2 -sa!e
// Imports for JCL:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
// Imports for the implementing logger used underneath:
// NO NEED, included in JCL
public class Main
{
static Log logger5*cl = LogFactory.getLog("LOGGER_JCL");
public static void main(String[] args)
{
System.out.println("Hello world !");
/* */ Main.logger5*cl.debug("I am the JCL logger");
}
}
LogFactory.getLog!# re"ies o! IdiscoveryI mecha!isms to determi!e ;hat u!der"yi!& imp"eme!tatio! it actua""y retur!s.
?f a "o&48 co!fi&uratio! fi"e is prese!t some;here the! a 2o&48 "o&&er ;i"" $e retur!ed.
*,
=httpDCCcommo!s.apache.or&C"o&&i!&CapidocsCor&CapacheCcommo!sC"o&&i!&C2o&7actory.htm">
=?t ;ou"d !eed more de"vi!& i!to doc to 5!o; ;hat the $ehaviour i! case of c"ash ;ou"d $e>
6.8.2.3 Result
Hello world !
2011-06-06 18:57:03,934 [LOGGER_JCL] DEBUG Main:main(),45 - I am the JCL logger
6.8.2.4 ,onfi!uration
?f to $e used o! top of "o&48 J(2 ;i"" automatica""y detect the prese!ce of "o&48 =prese!ce of a "o&48 co!fi& fi"e> a!d use
it as its imp"eme!tatio!. 2o&48 shou"d $e co!fi&ured =see a$ove>.
1.@." Brappin! lo!#F )lo!!in! .ith a custom interface, as used in our struts proFects+
3%amp"eD
?! a pro8ect ;ith i!8ectio! =e.&. struts2 a!d spri!&> ;e have defi!ed a 2o&&i!& i!terfaceD
public interface ILogger
{
public void #atal(Object message);
public void #atal(Object message, Throwable t);
public void error(Object message);
public void error(Object message, Throwable t);
public void $arn(Object message);
public void $arn(Object message, Throwable t);
public void in#o(Object message);
public void in#o(Object message, Throwable t);
public void debug(Object message);
public void debug(Object message, Throwable t);
a!d have made o!e imp"eme!tatio! of it usi!& a 2o&48 "o&&erD
$2ota: T/0/ see if definin) one3s o%n 4o))in) interface cannot be replaced by usin) the lo))in) interfaces provided
by 5pache +ommons& $still( the follo%in) displays ho% to %rap a 4o)6! lo))er&
public class LoggerLog4jWrap implements ILogger
{
public final String O2E)="<<";
public final String CLOSE=">>";
/**
* The encapsulated log4j logger
*/
protected Logger logger;
/**
* The encapsulated log4j logger's name
*/
protected String logger)a$e;
// --------------------------------------------------------------------------
// Construction
// --------------------------------------------------------------------------
/**
* Constructor
* @param log4j_logger_name The name of the log4j logger to use (aka the "category").
* See log4j config file.
*/
public 'ogger'og*+,rap(String log4j_logger_name)
{ this.construct(log4j_logger_name);
}
public 'ogger'og*+,rap()
{
}
public void construct(String log4j_logger_name)
{ this.logger)a$e = log4j_logger_name;
//this.logger = LogFactory.getLog(this.loggerName);
this.logger = Logger.getLogger(log4j_logger_name);
}
*+
// --------------------------------------------------------------------------
// "Wire" the encapsulated logger's functions:
// --------------------------------------------------------------------------
public void #atal(Object message)
{ this.logger.log(LoggerLog4jWrap.class.get)a$e(),
Level.FA3AL,
message,
null);
}
public void #atal(Object message, Throwable t)
{ this.logger.log(LoggerLog4jWrap.class.get)a$e(),
Level.FA3AL,
message,
t);
}
public void error(Object message)
{ this.logger.log(LoggerLog4jWrap.class.get)a$e(),
Level.E..O.,
message,
null);
}
public void error(Object message, Throwable t)
{ this.logger.log(LoggerLog4jWrap.class.get)a$e(),
Level.E..O.,
message,
t);
}
public void $arn(Object message)
{ this.logger.log(LoggerLog4jWrap.class.get)a$e(),
Level.WA.),
message,
null);
}
public void $arn(Object message, Throwable t)
{ this.logger.log(LoggerLog4jWrap.class.get)a$e(),
Level.WA.),
message,
t);
}
public void in#o(Object message)
{ this.logger.log(LoggerLog4jWrap.class.get)a$e(),
Level.I)FO,
message,
null);
}
public void in#o(Object message, Throwable t)
{ this.logger.log(LoggerLog4jWrap.class.get)a$e(),
Level.I)FO,
message,
t);
}
public void debug(Object message)
{ this.logger.log(LoggerLog4jWrap.class.get)a$e(),
Level.0EB:;,
message,
null);
}
public void debug(Object message, Throwable t)
{ this.logger.log(LoggerLog4jWrap.class.get)a$e(),
Level.0EB:;,
message,
t);
}
public void trace(Object message)
{ this.logger.log(LoggerLog4jWrap.class.get)a$e(),
Level.3.ACE,
message,
null);
}
public void trace(Object message, Throwable t)
{ this.logger.log(LoggerLog4jWrap.class.get)a$e(),
Level.3.ACE,
*1
message,
t);
}
public void debug&pen()
{ this.de%ug(this.O2E));
}
public void debugClose()
{ this.de%ug(this.CLOSE);
}
A c"ass i! the pro8ect usi!& the "o&&erD
public class MyAction (.)
{
// ==========================================================================
// Peripheral concerns
// ==========================================================================
/**
* The main logger.
* Here we choose to initialise with a default logger in case method setLogger()
* is not called by the injection process (spring or other), or until it is.
* (If it weren't initialised, until it were set by injection we'd be getting
* NullPointerExceptions). This initialisation is done by making a desperate attempt
* to latch on a logger referenced by the passed string.
*
* If we know for sure the injection will indeed set the logger, we may want to
* ignore any log calls until then.
* In that case, leaving the logger uninitialized won't do the trick since this would lead
* to NPEs as exposed above.
* We could instead use the same initialisation construct, but instead pass a
* reference we're sure is not used (e.g.
* new LoggerLogB*Wrap("fail_silently");
* this returns a logger object that does not do anything.
*/
protected ILogger logger = new LoggerLogB*Wrap("com.sfr.webapp");
// instead of:
// protected Log logger = LogFactory.getLog("com.sfr.webapp");
// For injection (Spring)
public void set'ogger(ILogger logger)
{ this.logger = logger;
}
public static ILogger getSlogger()
{ return slogger;
}
1.C R<A
-3%trait de "a formatio! )gcuritg Java 2413.4*.430
/**
* Ordre d'excution:
* 1. Lancer C:\Program Files\Java\jdk1.6.0\jre\bin\rmiregistry.exe (il s'agit du RMI registry)
* Le serveur a besoin de se binder avec lui pour ensuite offrir les services RMI au client.
*
* 2. Lancer le serveur (projet ..._server/serveur/HighTunesServer) avec la config JVM:
* -Djava.security.manager
* -Djava.security.policy=all.policy
* (la scurit est obligatoire avec RMI. Ici on commence avec un fichier de policies permissif pour
mettre en place le projet)
* (Nota: si on met == la place de =, cela veut dire que les policies sont charges en mode "non
additif" (crase toutes les autres permissions dfinies par les appelants dans la pile d'appel))
* -Djava.rmi.server.codebase="file:///C:/Documents%20and
%20Settings/Administrateur/workspace/Formation_Securite_TP_3_RMI_server/bin/"
* Ce dernier param indique au serveur quel est le path ou chercher l'appli fournir au bootstrap
*
* 3. Lancer le client (projet ..._client/client/bootstrap) avec la config JVM:
* -Djava.security.manager
* -Djava.security.policy=all.policy (ibid.)
* -Djava.rmi.server.codebase="file:///C:/Documents%20and
%20Settings/Administrateur/workspace/Formation_Securite_TP_3_RMI_server/bin/"
* Ce dernier param indique au bootstrap (client) quel est le path de l'appli que le serveur doit lui
fournir.
* Le client (bootstrap) et le serveur doivent avoir la mme valeur pour ce param, sinon a ne marchera pas.
* Le bootstrap demande l'applui suivante: "client.Appli" (cf code ci-dessous) donc il require du serveur
,4
* la classe suivante: file:///C:/Documents%20and
%20Settings/Administrateur/workspace/Formation_Securite_TP_3_RMI_server/bin/client/Appli"
*
* Le bootstrap tlcharge Appli et l'excute.
* Il faut que le bootsrap dfinisse les permissions avec lesquelles il s'excute (et qui sont
* donc "transmises" au contexte d'excution de Appli) puisque Appli est un code 3rd party potentiellement
* non sr.
*
* @author fhi
*
*/
/i&hTu!es)erver.po"icyD
grant codeBase "file:///C:/Documents and Settings/Administrateur/workspace/Formation_Securite_TP_3_RMI/bin/-"
{
// Permet de se connecter au RMIRegistry:
permission java.net.SocketPermission "127.0.0.1:1099", "accept, connect, listen, resolve";
// Permet d'accepter les sockets entrantes (de la part du client (bootstrap):
// sur les ports depuis 1024 (en fait ici dans cet exemple on ne connat pas le port
// qui sera fourni par RMIregister pour le dialogue entre le client et le serveur. Il aurait fallu
// le spcifier si on avait voulu un port prcis)
permission java.net.SocketPermission "127.0.0.1:1024", "accept, listen, resolve";
};
3 'round
3.1 2avadoc
httpDCC;;;.orac"e.comCtech!et;or5C8avaC8avaseCdocume!tatio!Ci!de%G13,+*+.htm"
httpDCCdocs.orac"e.comC8avaseC*CdocsCtech!otesCtoo"sC;i!do;sC8avadoc.htm"
3.1.1 Displayin! code
httpDCCstac5overf"o;.comC6uestio!sC'41124Cmu"tip"eG"i!eGcodeGe%amp"eGi!G8avadocGcomme!t
Kse the fo""o;i!& sy!ta%D ]preHJbcode # _]CpreH
)tra!&e"y ho;ever the c"osi!& $race of bcode ;i"" =possi$"y> $e disp"ayed.
3%amp"eD
A"so some of the i!de!ti!& is !ot ;e"" re!dered.
To &et correct i!de!tatio! correct"y the first "eve" shou"d !ot $e i!de!tedD
,1
A"so the 8avadoc does !ot seem to ha!d"e o&!" sy!ta% chars ;e""D
A!other e%amp"e =)6".ap from i$atis>D
* <b>The following example will demonstrate the use of SqlMapClient.</b>
* <pre>
* <i><font color="green">
* //
* // autocommit simple query --these are just examples...not patterns
* //
,2
* </font></i>
* Employee emp = (Employee) <b>sqlMap.queryForObject("getEmployee", new Integer(1))</b>;
* <i><font color="green">
* //
* // transaction --these are just examples...not patterns
* //
* </font></i>
* try {
* <b>sqlMap.startTransaction()</b>
* Employee emp2 = new Employee();
* // ...set emp2 data
* Integer generatedKey = (Integer) <b>sqlMap.insert ("insertEmployee", emp2)</b>;
* emp2.setFavouriteColour ("green");
* <b>sqlMap.update("updateEmployee", emp2)</b>;
* <b>sqlMap.commitTransaction()</b>;
* } finally {
* <b>sqlMap.endTransaction()</b>;
* }
Re!dersD
3.1.2 8lements
7.1.2.1 ?in/
/**
* See {@link #getBusinessLevelMessage(int, boolean)}
* @see #getBusinessLevelMessage(int, boolean)
*/
public void set"usiness'e(elMessage(String businessLevelMessage)
{.
public String get"usiness'e(elMessage(int remove, boolean remove)
Result:
3.2 Deploy, pac/a!e a li$rary, ma/e e&ecuta$le
,3
3.2.1 2ars
httpDCC;;;.ava8ava.comCtutoria"sC"esso!sCho;GdoGiG$ui"dGaG8arGfi"eGthatGco!tai!sGitsGdepe!de!cies.htm"
httpDCC;;;.i$m.comCdeve"oper;or5sC"i$raryC8G'thi!&s*Ci!de%.htm"
3.2.2 Pac/a!e files meant to act as a li$rary in a Far.
?! 3c"ipse se"ect pro8ect i! pro8ect e%p"orer the! i! top me!uD 7i"e H 3%port se"ect @Jar fi"eA the! se"ect a"" fi"es to
i!c"ude i! 8ar. =GH resu"tD f8".8ar>
?tIs $est to $e i! Vpac5a&e e%p"orerV vie; to do that. Bei!& i! VMavi&atorV ;i"" pote!tia""y add u!;a!ted
pare!t fo"ders i! the 8ar.

,4
.u"tip"e se"ect is do!e $y se"ecti!& =c"ic5i!&> the pare!t fo"der.
.a!ifest usedD =;ritte! $y ha!d>
,'
3.2." Pac/a!e files6Fars meant to act as a li$rary 8clipse li$rary
This a""o;s us to pac5a&e o! top of the 8ar descri$ed a$ove its depe!de!ciesD
To edit =addCremove 8ar #> a!d to e%port the "i$ i! a sta!da"o!e fi"e =a""o;i!f for reuse e"se;here i! a!other ;or5space
or o! a!other machi!e>D ri&ht c"ic5 o! the "i$rary a!d @PropertiesA
the! se"ect the "i$rary a!d @Kser 2i$rariesA GH access the 2i$rary ma!a&er
,*
3.2.# Pac/a!e6deploy app as a runna$le, standalone e&ecuta$le Far file
?! 3c"ipse se"ect pro8ect i! pro8ect e%p"orer the! i! top me!uD 7i"e H 3%port se"ect @Ru!!a$"e Jar fi"eA
The pac5a&i!& app ;i"" as5 for some co!fi&sD
="au!ch co!fi&uratio!D ho; to ca"" the app i.e. ;ith a"" depe!de!cies etc. this is the e6uiva"e!t of the H 8ava Goptio!s
Gc"asspath etc. "i!e>
Ru!!i!& the 8arD
,,
@ Desi!n, practises
@.1 Doc
httpDCCe!.;i5ipedia.or&C;i5iCJoshuaWB"och
Boo5D 3sse!tia" Java $y Joshua B"och
@.2 >ood practises
@.2.1 ecure de$u! functions
9o !ot "et de$u& a!d other co!cer!s fu!ctio!s thro; u!ha!d"ed errors.
public String toString()
{
String msg = "";
/* */ try
/* */ {
String super_msg = super.toString();
msg = String.for$at(super_msg.substring(0, super_msg.length()-1) + ", %s)", this.deptId);
/* */ }
/* */ catch (Exception e)
/* */ { // This function is used for debug reasons, do not let an error in it make
// everything else fail
/* */ }
return msg;
}
Other 3%amp"eD
public String getId() throws RdftreeInternalRuntimeException
{ .
Return this.id; // may throw RuntimeException
}
/**
* Same as getId(), only if an error occurs, returns a error string instead of raising an exception.
* Use for debug functions. (debug should not be the cause of failures ...)
* @return
*/
public String getIdSafe()
{
/* */ try
/* */ {
return this.getId();
/* */ catch (Exception e)
/* */ {
/* */ return "ERROR GETTING ID";
/* */ }
}
@." hould li$rary classes $e made static or not:
3%amp"e of staticD .aths.a$s=>
)tatic GH more difficu"t to i!corporate i! a depe!de!cy i!8ectio! system =spri!&>
httpDCCstac5overf"o;.comC6uestio!sC1+443''C8avaGstaticGc"ass
httpDCC8ava.d<o!e.comCartic"esCstaticGmethodsGareGdeathGtesta
@.# ,ontrollin! access to attri$utes )read, .rite, r.+
.a5i!& a! attri$ute private a!d usi!& pu$"icCprivate &ettersCsetters a""o;s us to co!tro" =simu"ate> its r; setti!&s.
3%amp"eD
/ere our attri$ute pare!tMode is reada$"e from the outside GH pu$"ic &etPare!tMode=> $ut !ot ;rita$"e from outsideD
setPare!tMode=> does !ot e%ist =or it cou"d e%ist a!d $e private>.
,+
/**
* Description of the attribute
*
* Assigning to the getter the javadoc relative to the attribute insures that javadoc is
* available from outside (with IDE) - Since from outside we'll be using the getter and not the
* attribute.
*/
public fjl.scrapbook.rdf.Document getOwnerDocument()
{
// Perform all required checks
fjl.scrapbook.rdf.Document od = this.ownerDocument;
if (od == null)
{
// And in case something wrong was detected, handle
String err_msg = "Owner document is null, and should not be. Insure it is initialised.";
logger.debug("ERROR: " + err_msg);
// here we throw a RunTime exception indicating that some poor programming occurred:
throw new ProgrammingRuntimeException(err_msg);
}
// If everything OK, just act as a normal getter
else
{ return od;
}
}
// The attribute .
// NOTA: there is no (no easy ?) way of preventing direct access to this attribute from WITHIN the current //
class
private fjl.scrapbook.rdf.Document ownerDocument ;
Ksi!& the &etters to access pu$"icCprivate attri$utes from ;ithi! the c"ass i! order to $e!efit form the chec5s is
de$ata$"eD if the outcome of the chec5 resides so"e"y i! the thro;i!& of a Ru!Time3%ceptio! =the error is !ot
recovera$"e> the! there is "itt"e adva!ta&e over "etti!& Java fai" o! its o;! =;ith a!y f"avour of Ru!Time3%ceptio! out
Mu""Poi!ter3%ceptio! ?""e&a"Ar&ume!3%ceptio! etc.> apart from may$e providi!& $etterCcustomised i!formatio! o! the
co!te%t of that error throu&h the e%ceptio! messa&e.
@.% Bor/in! .ith e&ceptions
@.%.1 Doc
A .K)T readD httpDCC;;;.orac"e.comCtech!et;or5Cartic"esCe!tarchCeffectiveGe%ceptio!sG41234'.htm" -RK[3N0
@.%.2 >eneral
-7/?3L(P0
09canisme 'es e,ce!tions U S (a!a" de commu!icatio! T dgdig par "e6ue" u! g"gme!t de code dgc"are D
avoir re!co!trg des circo!sta!ces dFe%gcutio! !articuli:res(anormales
6uFi" !e sait !as traiter
et do!t i" '9l:gue "e traiteme!t au !iveau su!9rieur.
E,ce!tion i $u& i co!ditio! S au% fro!tijres T =3O7 fi! de $ouc"e etc.>
E,ce!tion ; co'e 'e retour D moi!s de code e! S arrijreGp"a! T !Faccapare pas "a p"ace de "a va"eur retour
Java four!it 2 c"asses de $ase B gte!dre pour se crger ses propres e%ceptio!s D
Exception
RuntimeException
-Exception =et ses S hgritiers T> est u!e e%ceptio! dite S chec#e' T
-RuntimeException =et ses S hgritiers T> est u!e e%ceptio! dite S unchec#e' T
Pour "es e%ceptio!s chec#e' =C unchec7ed> o! 'oit< =C on peut> soit D a D o$"i&atio! du compi"o
2es !ro!ager $throws% de ma!ijre sim!le
,1
=i.e. redgc"arer "Fe%ceptio! da!s "a si&!ature de "a fo!ctio! appe"a!te>
2es ca!turer =try ... catch > pour D
G 2es traiter
soit "o&uer soit rgsoudre "e pro$"jme
G 2es !ro!ager avec e!capsu"atio!
uti"iser "e co!structeur Exception(String message, Throwable cause)
Pour "es e%ceptio!s unchec#e' o! !Fa pas cette o$"i&atio!. O! peut si o! veut mais e! &g!gra" o! D
ne )ait rien D o! "aisse "Fe%ceptio! S $u""er T 8us6uFB "a surface
=i.e. 8us6uFau sommet de "a pi"e dFappe" 6ui devra e! der!ier "ieu dgcider 6ue faire. )i e! ce
"ieuG"B rie! !Fest fait "Fapp"i p"a!tera D S Uncaught Exception # T>
@.%." >ood practises ).idely pu$lici;ed+
8.5.3.1 (ever s.allo. an e&ception
(atch a!d dea" ;ith it or rethro; =or "et $u$$"e if u!chec5ed>
8.5.3.2 -se e&ceptions for errors and not for Kcontrol flo.L
=i.e. remar5a$"e states yet sti"" "e&a">
3%amp"eD if ;e ;a!t to retrieve the co!te!t of a !ode a!d the !ode is empty do !ot thro; a! e%ceptio!. A !ode (AM
$e empty it is perfect"y accepta$"e.
8.5.3.3 Do not erase the cause e&ception
Kse hierarchy or e!capsu"ate
8.5.3.4 Do not lo! several time the same e&ception )as an error+
?!side your o;! code. At the $ou!daries of your code =topG"eve" fu!ctio! that ;i"" $e used $y others> the 6uestio!
remai!s. Ohat are the users &oi!& to do ;ith the e%ceptio!s that ? thro; at topG"eve" P ca! ? trust them to dea" ;ith them
i! a! appropriate fashio! P Ohat if they 8ust s;a""o; it P .ay$e ? shou"d "o& a! error 8ust to $e o! the safe side P
8.5.3.5 tore relevant conte&t info in e&ception
@.%.".%.1 Adea
3%amp"e usi!& a /ash.ap to provide severa" o$8ects.
#
catch (Exception e)
{ // Context info:
HashMap<String, Object> context_info = new Hash1ap<String, Object>();
context_info.put("menu_name", menu_name);
context_info.put("user" , user) ;
throw new 2lugin1enuException("Failed to load menu {" + menu_name + "}", null,
context_info);
}
#
public class PluginMenuException extends RuntimeException
{
/**
* Object being processed when exception arose
*/
protected Object onO%*ect;
public !luginMenuEception(String err_msg, Throwable e)
{ super(err_msg, e);
}
/**
+4
*
* @param err_msg
* @param e
* @param o May be a hashmap of several objects. Possibly in our case : keys "menu_name", "user"
*/
public !luginMenuEception(String err_msg, Throwable e, Object o)
{
this(err_msg, e);
this.onO%*ect = o;
}
public Object get&n&b+ect()
{ return this.onO%*ect;
}
@Override
public String getMessage()
{
String menu_name = null;
ILoggable user = null;
if (this.onO%*ect instanceof HashMap)
{ //HashMap h = (HashMap) o;
menu_name = (String) ((HashMap) this.onO%*ect).get("menu_name"); // may be null if
key does not exist
user = (ILoggable) ((HashMap) this.onO%*ect).get("user") ; // may be null if
key does not exist
}
String err_msg_final = "Failed to load menu {menu_name=" +
(menu_name == null ? "null": menu_name) +
"} for {user =" +
(user == null ? "null": user) +
"}. Further error information: " + super.get1essage();
return err_msg_final;
}
K!fortu!ate"y thou&h this tech!i6ue ca!!ot $e used to $ui"d a precise fi!a" error messa&e as the fo""o;i!& e%amp"e
cou!terGdemo!stratesD
9am!ed first stateme!t i! co!structor R =see ;hy i! a previous sectio!>
=The same i! se"ectio!!a$"e te%tD
String menu_name = null;
ILoggable user = null;
if (o instanceof HashMap)
{ //HashMap h = (HashMap) o;
menu_name = (String) ((HashMap) o).get("menu_name"); // may be null if key does not exist
user = (ILoggable) ((HashMap) o).get("user") ; // may be null if key does not exist
+1
}
String err_msg_final = "Failed to load menu {menu_name=" +
menu_name == null ? "null": menu_name +
"} for {user =" +
user == null ? "null": user +
"}. Error message: " + err_msg;
>
@.%.".%.2 0Fl class
This idea has $ee! made i!to a f8" c"assD =as of 2412.11.21>
pac2age com.fhi.fjl.exceptions;
/**
* Exception defining a context object to store info that can subsequently be
* used to create highly informative exception messages. <br />
* <br />
* Example of use: <br />
* <pre>
* MyMenuException extends WithContextException
* { ...
* //Override
* public String getMessage()
* {
* String menu_name = null;
* ILoggable user = null;
*
* if (this.context instanceof HashMap)
* { //HashMap h = (HashMap) o;
* menu_name = (String) ((HashMap) this.onObject).get("menu_name"); // may be null if
key does not exist
* user = (ILoggable) ((HashMap) this.onObject).get("user") ; // may be null if
key does not exist
* }
*
* String err_msg_final = "Failed to load menu: " +
* (menu_name == null ? "null": menu_name) +
* " for user: " +
* (user == null ? "null": user) +
* "."
* " Further information: " + super.getMessage(); // will print the parent
exception message
*
* return err_msg_final;
* }
* }
* </pre>
* Call:
* <pre>
* try
* { // do this or that
* }
* catch (Exception e)
* { // Context info:
* HashMap<String, Object> context_info = new HashMap<String, Object>();
* context_info.put("menu_name", menu_name);
* context_info.put("user" , user) ;
*
* throw new MyMenuException("while doing this or that...", null, context_info);
* }
* </pre>
* Output:
* <pre>
* Failed to load menu: side_bar_menu for user: Jeremy Osborne. Further information: while doing this or
that...
* </pre>
*
*
* @author fhill
* @since 2012.11
*
*/
@SuppressWarnings("serial")
public class WithContextException extends Exception
{
/**
* Context object
*
* May be a map of several objects.
+2
* Can be used ad libitum to create customized getMessage() functions (in extending classes). See class
doc.
*/
protected Object context;
public ,ithContetEception(String err_msg)
{ super(err_msg);
}
/**
*
* @param err_msg
* @param cause Accepts null if no cause (just like parent, Exception)
*/
public ,ithContetEception(String err_msg, Throwable cause)
{ super(err_msg, cause);
}
/**
*
* @param err_msg
* @param cause Accepts null if no cause (just like parent, Exception)
* @param subject Context object (possibly a map of objects) processed when exception arose
*/
public ,ithContetEception(String err_msg, Throwable cause, Object context)
{ this(err_msg, cause);
this.context = context;
}
/**
* Return the context. Useful to create custom getMessage() functions (in extending classes)
* @return
*/
public Object getContet()
{ return this.context;
}
}
8.5.3.6 tay layer9consistent
2o;er "eve" e%ceptio!s shou"d $e ;rapped i! "ayerGco!siste!t e%ceptio!s. -B"och item *10
?f i! pu$"ic fu!ctio! a!d part of a co!tract =e.&. api> e%ceptio!s thro;! must $e co!siste!t ;ith the fu!ctio!Fs puprose
="ayer co!siste!cy>. As httpDCC;;;.i$m.comCdeve"oper;or5sC8avaC"i$raryC8G8tp4'2'4Ci!de%.htm" puts itD @5 method %hose !ob it is to
load a user profile should thro% )oSuch:serException %hen it can8t find the user( not SMLExceptionN
GH if e%ceptio! thro;! i! code is tech!ica" a!dCor ;i"" !ot spea5 to c"ie!t ;rap up that e%ceptio! i! a =from pov of
c"ie!t> mea!i!&fu" e%ceptio!
public Element append&hild(Element element) throws RdftreeDocumentOperationException
{
/* */ String err_msg = "While appending %s";
/* */ String exp_msg = "Exception";
/* */ try
/* */ {
(...)
/* */ }
/* */ catch (Exception e)
/* */ { err_msg = String.for$at(err_msg, this.toString());
/* */ err_msg += ": ";
/* */ exp_msg += ": " + e.getClass().getName() + ", message: " + e.getMessage();
/* */ logger.debug("ERROR:" + err_msg);
/* */ logger.debug("ASSOCIATED EXCEPTION: " + exp_msg);
/* */ throw new RdftreeDocumentOperationException(err_msg, e);
/* */ }
}
=*>6? >o3ever i) in !rivate )unction =ca""ed $y a pu$"ic fu!ctio! some;here e"se i! c"ass>
o "et e%ceptio! $u$$"e up a!d catchC;rap i! pu$"ic fu!ctio! usi!& that private fu!ctio!.
o or ;rap over"y @tech!ica"A e%ceptio! i! a more &e!eric e%ceptio! easi"y u!dersta!da$"eCAha!d"a$"eA i! ca""i!&
fu!ctio!s
o or ;rap i! a! e%ceptio! to add co!te%tua" i!formatio!
E,ce!tionD if private method is a factorisatio! of code that is used i! severa" pu$"ic fu!ctio!sD do!Ft $other ;rap the
e%ceptio! as if i! the pu$"ic fu!ctio!
+3
>o3ever stayi!& "ayerGco!siste!t &ar!ers some share of a cou!terGar&ume!t
o httpDCC;;;.seGradio.!etCtra!scriptG,GerrorGha!d"i!&
=the " la&er !attern : httpDCCsteve!$"ac5.comCPTMG2ayers.htm" >
@.%.# >ood practises )not so .idely pu$lici;ed+
These practises are either !ot as pu$"ici<ed as the a$ove or possi$"y too evide!t to $e voiced =P> or devised $y myse"f
-7/?0.
8.5.4.1 Be precise in thro.in! )chec/ed e&ceptions+
Thro; a! e%act e%ceptio! c"ass !ot 8ust 3%ceptio!=messa&e descri$i!& pro$"em>. )ee re"eva!t hierarchy
App"ies to chec5ed e%ceptio!sD $ecause it he"ps the ca""i!& code to ide!tify the pro$"em =if it see5s to ha!d"e it>
8.5.4.2 Be precise in catchin! )chec/ed e&ceptions+
(atch the e%act e%ceptio!s !ot 8ust @3%ceptio!A. 7actorisi!& catches ;ith a @catch 3%ceptio! eA ;i"" a"so catch a!y
ru!time 3%ceptio! a!d preve!t it from $u$$"i!& up. =the e%ceptio! &ets @s;a""o;edA>.
8.5.4.3 Do not define a hierarchy for unchec/ed e&ceptions
)ee -RK[3N0
?f unchec#e' e,ce!tion itIs best to use a general t&!e =Ru!time3%ceptio! e.&.>D si!ce i! the e!d they ;i"" a"" $e
ha!d"ed i! the same ;ayD "o&&ed a!d K? disp"ays Vsorry tech!ica" pro$"emV. =see -RK[3N0>
8.5.4.4 Define a relevant e&ception hierarchy for chec/ed e&ceptions
@.%.#.#.1 >eneral doNs & donNts
@o not use error Aco'esB i!side a! e%ceptio! -7/?0
One !ossible cause or thi!& that cou"d &o ;ro!& U one e,ce!tion class -7/?0
A &ood hierarchy a""o;s for po;erfu" a!d mea!i!&fu" fi"teri!&
@.%.#.#.2 =ave a parent e&ception for filterin!
This a""o;s a""eviati!& if desired the $urde! of ha!d"i!& !umerous chec5ed e%cptio!s o! the part of c"ie!t codeD a""
e%ceptio!s ca! $e ha!d"ed i! o!e try catch. -7/?0
)ee !e%t item.
@.%.#.#." Do not use the parent e&ception for the !eneral case
(arefu" ;he! providi!& a su$set of e%ceptio!s a!d a V&e!era" caseVD -7/?0
o 2hen 3riting the )unction signatureD ;rite the e%act types of e%ceptio!s thro;! a!d !ot a superc"ass
The user of the AP? may pote!tia""y a!d ;ro!&"y $e &ive! the opportu!ity to catch severa" mea!i!&fu"
e%ceptio!s i! o!e =usi!& the pare!t e%ceptio!> thus defyi!& the purpose of the hierarchy. )ure this is
a";ays possi$"e $y catchi!& 3%ceptio! $ut i! that case the user ;ou"d $e doi!& that 5!o;i!&"y. ?! the
case detai"ed here the user mi&ht $e o$"ivious to the fact he ;ou"d $e i&!ori!& more precise error cases.
.; 'o not use the !arent e,ce!tion )or the general case
3%D CarEngineException, CarTyreException $oth e%te!di!& CarException
drive(Car car) throws CarEngineException, CarTyreException, CarException
{ if engine nok throw CarEngineException;
if tyre nok throw CarTyreException;
if other problem throw CarException
}
Ohe! ;riti!& the AP? the deve"oper may =specia""y if theyIre usi!& a! ?93 ;ith adva!ced comp"etio! features>
&o throu&h such sce!arios ;here they ;ou"d e!d up ;ith 8ust the "ast e%ceptio! o! the fu!ctio! si&!atureD
drive(Car car) throws CarException
+4
This is 144d va"id $y the compi"er si!ce CarException e%te!ds $oth the other e%ceptio!s. /o;ever this ;ou"d
forever shado; =o$"iterate> the e%iste!ce of the 2 more precise e%ceptio!s to the user of the (ar AP?. =u!"ess
they 5!e; a$out them>
?!stead a $etter e%ceptio! hierarchy ;ou"d have $ee!D
CarEngineException, CarTyreException a!d CarOtherException a"" e%te!di!& CarException.
drive(Car car) throws CarEngineException, CarTyreException, CarOtherException
{ if engine nok throw CarEngineException;
if tyre nok throw CarTyreException;
if other problem throw CarOtherException
}
The user of the (ar AP? ca! sti"" catch a"" e%ceptio!s at o!ce $y catchi!& the pare!t e%ceptio! CarException.
A &ood idea may $e to use e%ceptio! superc"asses mea!t o!"y for fi"teri!& purposes a!d !ot mea!t to $e direct"y
i!sta!ciated. ?! that case ma5e the co!structors protected.
/**
* Business Logic Exception.
*
* This is a superclass. To be used for filtering purposes only. When throwing use one of the extending
classes. Use AsBusLogOtherException for the general case.
*
* @author fhill
* @since 2012.09
*
*/
@SuppressWarnings("serial")
public class AsBusLogException extends AsException
{
// Constructors made protected because extending exceptions should be thrown and not this class
directly
protected As"us'ogEception()
{
}
protected As"us'ogEception(String err_msg)
{ super(err_msg);
}
@.%.#.#.# 8&ception namin! 6 proposed hierarchy
3%te!d Vo! the ri&htV UH affi"iated e%ceptio!s start the same -7/?0
DomainException extends Exception
DomainCaseException extends DomainException
DomainCaseSubcase1Exception extends DomainCaseException
DomainCaseSubcase2Exception extends DomainCaseException
DomainCaseOthersubcaseException extends DomainCaseException
9o !ot redu!d
AsDaOpBusinessRulesPreconditionsFailedException is redu!da!t.
AsDaOpBusinessRulesPreconditionsException suffices. A! e%ceptio! a"ready mea!s somethi!& has fai"ed.
@.%.% ,hec/ed e&ception OR unchec/ed e&ception : usin! one or the other
8.5.5.1 Definition
Chec#e' e,ce!tion U dec"ared a!d havi!& to $e e%p"icit"y cau&ht or rethro;! $y usi!& code. =The error cases they
represe!t are chec#e' $y the compi"er>
"nchec#e' e,ce!tion U !ot dec"ared @si"e!tA =e%. Mu""Poi!ter3%ceptio!>. They are su$c"asses of
Ru!Time3%ceptio! =The error cases they represe!t are not chec#e' $y the compi"er>
+'
Before ru"i!& ;hat type of e%ceptio! to use i! ;hat case "etIs di& i!to the matterD
8.5.5.2 Different natures of e&ceptions
Broad"y spea5i!& there are three differe!t situatio!s that cause e%ceptio!s to $e thro;!D
E,ce!tions 'ue to !rogramming errors =in /16?: ?! this cate&ory e%ceptio!s are &e!erated due to pro&rammi!& errors
=e.&. NullPointerException a!d IllegalArgumentException>. The c"ie!t code usua""y ca!!ot do a!ythi!&
a$out pro&rammi!& errors.
E,ce!tions 'ue to client co'e errors: ("ie!t code attempts somethi!& !ot a""o;ed $y the AP? a!d there$y vio"ates its
co!tract. The c"ie!t ca! ta5e some a"ter!ative course of actio! if there is usefu" i!formatio! provided i! the e%ceptio!. 7or
e%amp"eD a! e%ceptio! is thro;! ;hi"e parsi!& a! L.2 docume!t that is !ot ;e""Gformed. The e%ceptio! co!tai!s usefu"
i!formatio! a$out the "ocatio! i! the L.2 docume!t that causes the pro$"em. The c"ie!t ca! use this i!formatio! to ta5e
recovery steps.
E,ce!tions 'ue to resource )ailures: 3%ceptio!s that &et &e!erated ;he! resources fai". 7or e%amp"eD the system ru!s out
of memory or a !et;or5 co!!ectio! fai"s. The c"ie!tIs respo!se to resource fai"ures is co!te%tGdrive!. The c"ie!t ca! retry the
operatio! after some time or 8ust "o& the resource fai"ure a!d $ri!& the app"icatio! to a ha"t.
-9O)/?0
8.5.5.3 (ot the same audience
-RK[3N0 seems to &ive a &ood ratio!a"eD eitherD
3rror is i!te!ded for c"ie!tCa$ove "ayer=s> U 5!o;i!& of the error is of i!terest to themD they ca! either try
somethi!& differe!t or ha!d"e. -RK[3N0 ca""s these VcontingenciesV.
Chec#e' e,ce!tion
3rror is i!te!ded for system admi!Cdeve"oper U $ecause it is a! errorC$u& that ;i"" have to $e fi%ed $y i!terve!tio!
i! code. -RK[3N0 ca""s these V)aultsV. The error shou"d shoot ri&ht up =V$u$$"es upV>D c"ie!t a!d a$ove "ayers have
!o $usi!ess ;ith it. GH the error $ypasses them. 3ve!tua""y that error reaches the V7au"t $arrierV ;hich dea"s ;ith
these errors =mai!"y "o&&i!& for u"terior mai!te!a!ce i!terve!tio!>
"nchec#e' e,ce!tion
+*
*igure C =+"DEE?
3.&. i! )truts the 7au"t $arrier is the 3%ceptio! /a!d"er.
8.5.5.1 Bhat happens6should happen to runtime e&ceptions in the end
The importa!t thi!& is to u!dersta!d that unchec#e' e,ce!tions ;i"" !ot !ecessari"y =shou"d !ot actua""y> cause the
app"icatio! or pro&ram to crash =this has $ee! the erro!eous assumptio! u!der ;hich decidi!& $et;ee! chec5ed a!d
u!chec5ed has $ee! so e%cruciati!& for me>. ?! the app"icatio! architecture there shou"d $e a V7au"t BarrierV =see
-RK[3N0 i! a! upper "ayer a&ai!st ;hich A22 u!chec5ed e%ceptio!s ;i"" $rea5 =8ust "i5e a ;ave a&ai!st a 8etty> a!d $e
ha!d"ed a!d a! appropriate respo!se issued ="o& disp"ay VsorryV messa&e to e!d user etc.>.
O!ce this is u!derstood thi!&s are easier.
+,
8.5.5.2 <y 40=A5 $ottom line7 chec/ed OR unchec/ed
As of 2412C14 6 consi'er the above !oints $=@OS>6?5 =+"DEE?% to mostl& settle the 'istinction bet3een
unchec#e' an' chec#e' !roblem ;ith additio! ofD
E,ce!tions 'ue to client co'e errors .; unchec#e' e,ce!tion:
use ru!time e%ceptio!s to i!dicate pro&rammi!& errors. The &reat ma8ority if ru!time errors i!dicate preco!ditio! vio"atio!s.
A preco!ditio! vio"atio! is simp"y a fai"ure $y the c"ie!t of a! AP? to adhere to the co!tract esta$"ished $y the AP?
specificatio!
-B"och item '+0
E,ce!tions 'ue to resource )ailures
.; chec#e' i) client can 'o something $allocate mem5 !ro'uce a alternative in!ut etc%
.; unchec#e' other3ise $eg connection 'o3n
The cases for usi!& either chec5ed or u!chec5ed e%ceptio!s are !o; c"ear"y mapped out. ThatIs assumi!& ;eIre
usi!& chec5ed e%ceptio!s at a"". =see sectio! (hec5ed V) K!chec5ed for a discussio! o! the su$8ect>
8.5.5.1 hould unchec/ed e&ceptions $e declared in function si!nature :
Java does !ot e!force this. ?!deed the poi!t of u!chec5ed e%ceptio!s is to a""eviate code. /o;ever it is possi$"e to
dec"are themD
the compi"er does !ot re6uire that you catch or specify ru!time e%ceptio!s =a"thou&h you ca!>
-8ava doc0
3%amp"eD
protected boolean setParentNode() throws RdftreeDocumentMalFormedException, RdftreeInternalRuntimeException
{ .
B"och advocates a&ai!stD
9o !ot dec"are u!chec5ed e%ceptio!s i! fu!ctio! si&!ature. /o;ever dec"are them i! 8avadoc =bthro;s>.
-B"och 3ffective Java0D
/o;ever dec"ari!& u!chec5ed e%ceptio!s i! fu!ctio! si&!aturesD
G may $e of i!terest if co!sidered the fact that it ;i"" remi!d users of this fu!ctio! that such a! e%ceptio! may arise
G ;i"" offer the support from the ?93D automatio! =if e%ceptio! is !ot thro;! $y code a!ymore#> refactori!&
=re!ami!&>#
8.5.5.2 Other ta/es6thou!hts on chec/ed OR unchec/ed
:e!era""y spea5i!& do !ot thro; a +untimeE,ce!tion or create a su$c"ass of Ru!time3%ceptio! simp"y $ecause you do!It
;a!t to $e $othered ;ith specifyi!& the e%ceptio!s your methods ca! thro;.
/ereIs the $ottom "i!e &uide"i!eD 6) a client can reasonabl& be e,!ecte' to recover )rom an e,ce!tion5 ma#e it a chec#e'
e,ce!tion 6) a client cannot 'o an&thing to recover )rom the e,ce!tion5 ma#e it an unchec#e' e,ce!tion.
-httpDCCdo;!"oad.orac"e.comC8avaseCtutoria"Cesse!tia"Ce%ceptio!sCru!time.htm"0
MBD ?! that "ast se!te!ceD @?f a c"ie!t ca!!ot do a!ythi!& to recover from the e%ceptio!A U @?f a c"ie!t is !ot
e%pected to 5!o; ho; to recover from the e%ceptio!#A
+untime e,ce!tions represe!t pro$"ems that are the resu"t of a !rogramming !roblem -7/?D !rogram-level !roblem as
opposed to fu!ctio!a" pro$"em0 a!d as such the AP? client co'e cannot reasonabl& be e,!ecte' to recover )rom them or
to ha!d"e them i! a!y ;ay. )uch pro$"ems i!c"ude arithmetic e%ceptio!s such as dividi!& $y <eroe poi!ter e%ceptio!s such
as tryi!& to access a! o$8ect throu&h a !u"" refere!cee a!d i!de%i!& e%ceptio!s such as attempti!& to access a! array e"eme!t
throu&h a! i!de% that is too "ar&e or too sma"".
+untime e,ce!tions ca! occur a!y;here i! a pro&ram a!d i! a typica" o!e they ca! $e very !umerous. /avi!& to add
ru!time e%ceptio!s i! every method dec"aratio! ;ou"d re'uce a !rogramFs clarit&. Thus the compi"er does !ot re6uire that
you catch or specify ru!time e%ceptio!s =a"thou&h you ca!>.
++
-httpDCCdocs.orac"e.comC8avaseCtutoria"Cesse!tia"Ce%ceptio!sCru!time.htm"0
K!chec5ed ru!time e%ceptio!s represe!t co!ditio!s that &e!era""y spea5i!& ref"ect errors i! your pro&ramIs "o&ic a!d ca!!ot
$e reaso!a$"y recovered from at ru! time.
-The 9ava :ro)rammin) 4an)ua)e $y :os"i!& Ar!o"d a!d /o"mes0
-7/?0 Vpro&ram "o&icV # this is va&ueR
K!chec5ed e%ceptio!s shou"d o!"y $e co!sidered for V"o!&Gdista!ceV e%ceptio! propa&atio!. =To e!a$"e reporti!& of fair"y
catastrophic eve!ts ;ithi! the system.>
-httpDCC;;;.octopu"".demo!.co.u5C8avaC3%ceptio!a"Java.htm"0
Kse runtime e,ce!tions to in'icate !rogramming errors. The &reat ma8ority if ru!time errors i!dicate preco!ditio!
vio"atio!s. A preco!ditio! vio"atio! is simp"y a )ailure b& the client o) an /16 to a'here to the contract esta$"ished $y the
AP? specificatio!
-item '+ 3ffective Java0
)upporti!& this poi!t of vie;D
o @O!e shou"d!Ft try to &uard the c"ie!t a&ai!st himse"fA -7/?0 or said differe!t"yD
\ou ;i"" receive a! u!chec5ed e%ceptio! ;here you as a pro&rammer shou"d have chec5ed for i! your code
-httpDCC;;;.octopu"".demo!.co.u5C8avaC3%ceptio!a"Java.htm"0
3%amp"eD if the c"ie!t tries to reach a! i!de% =of array or other> out of $ou!ds thro;i!& a chec5ed
OutOfBoundsException ;i"" force him to perform actio!s he shou"d have i! a!y case performed $efore
ca""i!& the AP? =i.e. ca""i!& a size() fu!ctio! or e6uiva"e!t>.
o E,ce!tions are not a means to insure the client uses the /16 right5 an' correct him 3hen he 'oes not .
\ou ;ou"d eve!tua""y =i! the AP?> $e doi!& the ;or5 of every$ody e"se =the comp"ete "ayers of c"ie!t
e!ve!tua""y ca""i!& your AP?>. -7/?0
Pro&rammi!& errors do occure $ut ;e shou"d !ot $e creati!& a desi&! to cater for themR =Tryi!& to cater for $u&s o!"y "eads to
hard to test code that is itse"f a $reedi!& &rou!d for $u&s.>
-httpDCC;;;.octopu"".demo!.co.u5C8avaC3%ceptio!a"Java.htm"0
.; although i) client can recover5 chec#e' o!eration =-- *>6 GHCCCGGI?
?t is !ot co!ceiva$"e that the pro&ram 8ust crashes i! the ha!ds of the e!d user upo! a ru!time 3%ceptio!.
)ome;here a"o!& the ca"" stac5 the e%ceptio! ;i"" have to $e ha!d"ed &racefu""yD
@#some;here far up the ca"" stac5 there ;i"" $e some code that ma!a&es the -ru!time0 errorA
@.%.%.2.1 Determination procedure proposed $y 0=A 4D8PR8,'T8D5
93PR3(AT39 G )ee sectio! a$ove
1. 1rogram-level )ailure =e.&. diviso! $y 4 !u"" o$8ect> U Resu"t of a $u&
'angerous for c"ie!t P
UH unchec#e': it is pro$a$"y $etter =safer> that app fai"s
not 'angerous for c"ie!t P
UH chec#e' or unchec#e' =it cou"d $e ar&ued that thro;i!& chec5ed e%ceptio!s for "o;G"eve" fai"ures
;ou"d "ead to c"utter>. K!chec5ed pro$a$"y $etter as user most pro$a$"y ;o!Ft 5!o; ;hat to do ;ith a chec5ed.
2. S&stem-level )ailure -7/?0D !ot direct"y a pro&ramG"o;G"eve" pro$"em yet somethi!& is ;ro!& ;ith the pro&ram
"o&ic a!dCor system e!ters a !o! e%pected state.
)ame choice as for !rogram-level )ailure
+1
3. +esource )ailure =e.&. co!!ectio! fai" fi"e is missi!& memory fu"">
UH chec#e'
4. Client co'e error
UH unchec#e' -B"och '+0
8.5.5.3 8&amples
3%amp"e of ru!time e%ceptio!
/**
* This exception is a RuntimeException (unchecked exception): the Rdftree api is responsible for it
* and the contract (api) offered to the client is broken (as opposed to checked Exception where the
* client is responsible for breaking the contract).
* The client is not expected to know how to recover from it.
*
* @author fhill
* @since 20 juin 2011
*
*/
public class RdftreeInternalRuntimeException extends RdftreeRuntimeException
{
A!other e%amp"e of ru!time e%ceptio!
String node_item_action = . // Retrieved from a static config file
// We then try to load the class corresponding to node_item_action. This process may yield exceptions (e.g. the
class is not found, value is erroneous etc.)
BaseWithSessionAndAuthorizationsACT action = (BaseWithSessionAndAuthorizationsACT)
SpringAppContextProvider.getBean(node_item_action);
// The call above generates several RunTime Exceptions.
// We COULD still catch them, and for example ignore them.
// But here, we will choose not to: we'll let any bean-load exception bubble up to top: node_item_action being
retrieved from a static config file, an error needs to be fixed fixed during development: it should be
detected.
3%amp"e of ru!timeD
* @throws PluginSupporterException if conf file was not found e.g. . It is debatable whether we should
throw a checked or an
* unchecked exception. Unchecked puts the emphasis on the fact that the caller will have to
proactively handle this error case:
* no compiler obligation to handle it. Checked suggests that it is more of an immediate
problem, suggesting the conf file can't
* be non existent and that we don't fall back on default values.
*/
public String getCon#!roperty(String key)
{
if (pluginConf2roperties == null) set2luginConf2roperties();
String prop = pluginConf2roperties.get2ropert(key);
if (null == prop)
{ // Don't do anything - Just let the level above deal with this possibility and decide
what to do
}
return prop;
}
A!other e%amp"e of ru!time e%ceptio!
public static Map<ETypeTheme, String> getMapEnumValue()
{ Map<ETypeTheme, String> ret = new Hash1ap<ETypeTheme, String>();
for (ETypeTheme e : ETypeTheme.values())
{ //ret.put(e, e.getValue());
String err_msg = "Please check code, this sould not happen. All themes should have a
public static getName() function.";
try
{ ret.put(e, (String) e.getCla>>().get0eclared1ethod("getName").invo=e(null));
}
catch (IllegalArgumentException e1)
{ throw new .unti$eException(err_msg);
}
catch (SecurityException e1)
{ throw new .unti$eException(err_msg);
}
catch (IllegalAccessException e1)
{ throw new .unti$eException(err_msg);
14
}
catch (InvocationTargetException e1)
{ throw new .unti$eException(err_msg);
}
catch (NoSuchMethodException e1)
{ throw new .unti$eException(err_msg);
}
}
return ret;
8.5.5.1 The theory put in practise7 pro$lems 48<A9D8PR8,'T8D5
-httpDCC;;;.octopu"".demo!.co.u5C8avaC3%ceptio!a"Java.htm"0
-7/?0
@e)ine the chec#e' an' unchec#e' e,ce!tions )or the )ollo3ing scenario
@e)ine a e,ce!tion hierarch&
\ou are respo!si$"e for ma!a&i!& a "i$rary a!d provide a service to users that ;a!t to access $oo5s.
\our 8o$ ca! $e resumed $y the fo""o;i!& fu!ctio!D
Book borrowBook (String bookTitle, LibraryCard card )
Pai!ti!& the picture a $it further ;e cou"d ima&i!e $ei!& used i! the fo""o;i!& ;ayD -TO9O see if this is re"eva!tD from
the AP? 2i$rary POV ;e do!Ft 5!o; ;ho a!d ho; is &oi!& to $e usi!& us0
Student
{
writeEssay()
{ getKnowledge()
writeDraft()
writePaper()
}
getKnowledge()
{
book = borrowBook (title, card)
knowledge = readBook(book)
organizeKnowledge(knowledge)
}
}
/o; ;i"" you $e dea"i!& ;ith error casesP
3rror case T&!e o) error Chec#e' "nchec#e'
$oo5 ;ith &ive! tit"e does !ot
e%ist i! "i$rary ="i$rary does
!ot o;! that $oo5>
=hitem !ot fou!d i! data$ase>
+esource )ailure Boo#NotE,istsE,ce!tion
=more precise tha! 8ust
Boo5Mot7ou!d>
$oo5 is out +esource )ailure Boo#6sOutE,ce!tion
This is re"eva!t i!fo as user
may decide to come $ac5 "ater.
Oe ca! eve! pass i! e%ceptio!
the e%pected retur! date
$oo5 is dama&ed ca!Ft $e "e!t
out i! that sate
+esource )ailure Boo#Not/vailableE,ce!tion
Possi$"y mer&e =or superc"ass
;ith same> ;ith
Boo5?sOut3%ceptio!
to reduce c"utter =i.e. amou!t of
3%ceptio!s to dea" ;ith>
$oo5 !ot fou!d ="i$rary
re&ister says ;e have yet ;e
S&stem-level )ailure
This sou!ds "i5e a -
11
ca!Ft fi!d it k "ost or other> $u& i! our system it
;ou"d pro$a$"y have
to $e i!spected $y
mai!te!a!ce.
/o;ever
co!se6ue!ces are !ot
da!&erous for user
Boo#ErrorE,ce!tion
Possi$"y chec5ed si!ce !ot da!&erous
/o;ever it cou"d $e ar&ued a&ai!st =thro;i!& chec5ed
e%ceptio!s for "o;G"eve" fai"ures ;ou"d "ead to c"utter>
perso! ;ho &oes a!d retrieves
the $oo5 i! the rai"i!&s is !ot
here =h data$ase do;!>
+esource )ailure Librar&@o3nE,ce!tion
2ote 2012.10 " %ould ma7e it
unchec7ed no%
user has $ee! $"ac5"isted +esource )ailure "ser+ightsE,ce!tion
card is !ot a va"id 2i$rary(ard
=user has &ive! us his
Oa""mart card>
=h !u"">
Client co'e error 6llegal/rgumentE,ce!tion
user has reached ma% !um$er
of $oo5s o! his card
+esource )ailure Car'0a,e'OutE,ce!tion
Possi$"y mer&e =or superc"ass
;ith same> ;ith
"ser+ightsE,ce!tion
card reader is $ro5e! or
u!avai"a$"e
S&stem-level )ailure
-
card is dama&edCu!reada$"e
=hchec5s performed o! data
sho; it has $ee! corrupted>
Client co'e error
This o!e mi&ht $e a
$it tric5y. \et it is
c"ear"y out of rea"m
;e ca!Ft $e $"amed
for a dama&ed card.
6llegal/rgumentE,ce!tion
"i$rary is c"osed =re&u"ar
hours>
+esource )ailure %
"i$rary is c"osed =e%ceptio!a">D
stri5e o! fire #
S&stem-level )ailure
This sou!ds "i5e a
$u& i! our system. ?s
it da!&erous for our
c"ie!t P hmmm
-
"i$rary ?T system
ma"fu!ctio!i!& a!d readi!&
userFs card re!ders a"" their
perso!a" detai"s pu$"ic
1rogram or S&stem-
level )ailure
Pote!tia""y da!&erous
state user ca!!ot $e
e%pected to recover
6llegalStateE,ce!tion
or other !ame
?! order to a""eviate the ;or5 o! the part of the c"ie!t i! terms of e%ceptio! ha!d"i!& =o!e of the fre6ue!t reaso!s ;hy
e%ceptio! &et misGused or i&!ored> o!e cou"d have a"" chec5ed e%ceptio!s derive from o!e superGe%ceptio! for e%amp"e
Borro;Boo53%ceptio!.
That ;ay ;e "eave it up to the c"ie!t if he ;a!ts to do some fi!e fi"teri!& or 8ust catch a"" e%ceptio!s i! o!e &o =mu"tiG
catch does !ot e%ist yet as of time of ;riti!&>
Proposed hierarchyD =suffi%es @3%ceptio!A have $ee! dropped off for the sa5e of c"arity>
12
?f strict"y app"yi!& the 8ava orthodo%y the u!decided cases i! the error sce!ario ta$"e a$ove k a!d represe!ted i! the
cor!er i! the proposed hierarchy G shou"d $e made u!chec5ed.
@.%.1 ,hec/ed P unchec/ed )a/a the de$ate ra!es on+
=This sectio! is !ot a$out the 6uestio! shou"d ;e use a chec5ed OR a! u!chec5ed e%ceptio!. ?tIs a$out the 6uestio!
shou"d ;e use chec5ed e%ceptio!s at all. ?! other terms a $etter !ame for the sectio! tit"e ;ou"d $eD chec5ed &
u!chec5ed V) o!"y u!chec5ed.>
Rece!t"y there has $ee! a ;i!d of re$e""io! a&ai!st chec5ed e%ceptio!s. Java ;as the first "a!&ua&e to i!troduce chec5ed
e%ceptio!s =after (XX had i!troduced the co!cept of e%ceptio! a! improveme!t o! the retur!G$ased error ma!a&eme!t
i! (> i! ;hat some !o; deem a Vfai"edV e%perime!t.Popu"ar ope! source frame;or5s "i5e )pri!& a!d /i$er!ate have
rece!t"y cha!&ed their e%ceptio! mode" from chec5ed to u!chec5ed.
(o!te!ders opposeD
G (ode c"utter
G 9eve"oppers too "a<yC do!It u!dersta!d e%ceptio!C do!It ;a!t to $e $othered GH ofte! si"e!ce e%ceptio!s
ResourcesD
G httpDCC;;;.i$m.comCdeve"oper;or5sC8avaC"i$raryC8G8tp4'2'4Ci!de%.htm"
? !o; $e"ieve that chec5ed e%ceptio!s encourage !eo!le to ma#e them vanish. P"us they ma5e much less rea'able co'e.
But ? do remem$er o!e of the ear"y ar&ume!ts for e%ceptio! ha!d"i!& i! (XX ;as that it ;ou"d a""o; the pro&rammer to
separate the sectio!s of code ;here you 8ust ;a!ted to &et ;or5 do!e from the sectio!s ;here you ha!d"ed errors a!d it
seems to me that chec5ed e%ceptio!s do !ot do thise i!stead they te!d to i!trude =a "ot> i!to your V!orma" ;or5i!& code
-Bruce 3c5e" httpDCC;;;.mi!dvie;.!etC3tcC9iscussio!sC(hec5ed3%ceptio!s0
8.5.6.1 chec/ed6unchec/ed and 'PA desi!n
GPovidi!& a! AP? ;ith chec5ed e%ceptio!sD
(OM)D ?f a !e; chec5ed e%ceptio! is added a"" the code usi!& the AP? is $ro5e! a!d has to $e revised to ha!d"e the
!e; e%ceptio!.
Borro; Borro;Ru!time
Boo5 2i$rary Ri&hts
Boo5?sOut
2i$rary9o;! 2i$rary("osed
(ardRi&hts KserRi&hts
?""e&a"Ar&ume!t
Boo5MotAvai"a$"e
Boo53rror
(ardReader3rror
2i$rary3rror
13
?""e&a")tate
@.%.3 ?o!!in! errors )or does the e&ception suffice :+
?! midd"e of stac5 ca"" =some;here i! the midd"e of the code ;here the e%ceptio! is passed a"o!& or ;rapped a!d
passed a"o!& to ca""i!& code> D
G "o& a de$u& messa&e =a!d !ot a! error messa&eD log error onl& once at top of ca"">
G possi$"y "o& =a de$u& messa&e> the causi!& e%ceptio!Fs messa&e
G $ut MOT the causi!& e%ceptio!Fs stac5 trace =this ;e "eave to the top of the ca"">
/* */ catch (MalformedURLException e)
/* */ { String err_msg = "Passed url is faulty: " + strURL;
/* */ logger.debug("Exception: " + e.getClass().getName() + ": " + err_msg + " --- Mother
error: " + e.getMessage());
/* */ throw new CopyUrlException(err_msg, e);
/* */ }
OrD
/* */ catch (SAXParseException e)
/* */ {
/* */ String err_msg = "Error occured while parsing file ... ";
/* */ String exp_msg = "Exception: " + e.getClass().getName() + ", message: " + e.getMessage();
/* */ logger.debug(err_msg);
/* */ logger.debug(exp_msg);
/* */ throw new CopyUrlException(err_msg, e);
/* */ }
Pro&rammatica" error =u!chec5ed e%ceptio!>
String err_msg = "While trying to load document from file {" + filename +"}: ";
String exp_msg = "Exception: ";
/* */ catch (XPathExpressionException e)
/* */ {
/* */ err_msg += "Unexpected Xpath error while looking for root node ... ";
/* */ exp_msg += e.getClass().getName() + ", message : " + e.getMessage();
/* */ logger.debug("ERROR:" + err_msg);
/* */ logger.debug("ASSOCIATED EXCEPTION: " + exp_msg);
/* */ // Unexpected programmatical error -> unchecked exception
/* */ throw new RuntimeException(err_msg, e);
/* */ }
At the top of the ca"" =;here ;e ;i"" fi!a""y receive the e%ceptio! i! a!y fashio! of ;rapped form>D
G "o& a! error messa&e
G possi$"y "o& the e%ceptio!Fs stac5 traceD
/* */ catch (Exception e)
/* */ { String err_msg = String.for$at("Something went wrong trying to copy {%s} to {%s}", url,
dest);
/* */ StringWriter sw = new StringWriter();
/* */ PrintWriter pw = new PrintWriter(sw);
/* */ e.printStackTrace(pw);
/* */ String stackTrace = sw.toString();
/* */ logger.error(err_msg + "\nException Stack: " + stackTrace);
/* */ logger.info("Skipping to next gallery...");
/* */ brea2;
/* */ }
8.5.7.1 ?o! only once, or :
Oe said 8ust a$ove that "o&&i!& shou"d $e do!e o!"y o!ce at hi&hest "eve" of e%ceptio! catchi!&.
Or shou"d it P /ere is some i!teresti!& food for thou&ht
H Oh a!d $y the ;ay ? $e"ieve the e%amp"e sho; i! the artic"e is a! a!tipatter!. \ou shou"d 3?T/3R "o& OR
H rethro; $ut !ot $oth.
?Ive thou&ht a$out this issue myse"f. The pro$"em is of course ho; do you 5!o; ;hether a hi&her "eve" e%ceptio! ha!d"er
;i"" "o& the e%ceptio!P ?f you do!It "o& it it mi&ht !ot $e "o&&ed at a""e if you do it mi&ht $e "o&&ed t;ice. Perhaps 3%ceptio!
!eeds a f"a& to record the fact that it has $ee! "o&&ed.
Just $ecause ?Ive "o&&ed a! e%ceptio! doe!It mea! ?Ive Vha!d"edV it it seems perfect"y va"id to me to "o& it a!d the! re6uire
the ca""er to ma5e the fi!a" decisio! a$out ;hat to do.
=httpDCC;;;.8ava"o$$y.or&C8avaCforumsCt14'34,.htm"PstartU34 >
14
O!e mi&ht derive the fo""o;i!& ru"eD -7/?0
?f ;eFre at the top of OKR e%ceptio! f"o; =i.e. i! pu$"ic AP? fu!ctio!> GH "o&
?f !ot =private or protected fu!ctio!> GH do !ot "o&
8.5.7.2 Or!anisin! lo! and e&ception messa!es7
3%amp"e 1
protected boolean setParentNode() throws RdftreeDocumentMalFormedException, RdftreeInternalRuntimeException
{ /* */ logger.debug(fjl.logging.Log.OPEN);
/* */ // The message stub used to describe the context of the error:
/* */ String err_msg = "While trying to set parent Node for %s";
/* */ // Instead of:
/* */ // String err_msg = "While trying to set parent Node for " + this.toString();
/* */ // Since we're not sure this message will indeed be used, for the sake of performance
/* */ // it's best to keep the costly calculations till the moment we know we'll be needing
/* */ // them.
/* */ // The message stub used to describe the exception caught (in log):
/* */ String exp_msg = "Exception";
/* */ // These 2 stub messages above have to be declared out of the try catch block
/* */ // since they will be used inside a catch block.
/* */ try
/* */ {
// Throwing an exception due to some business logic failure:
if (node_list.getLength() == 0 )
{
err_msg = "No parent node found, and node is not root.";
throw new RdftreeDocumentMalFormedException(err_msg, null);
}
else if (node_list.getLength() > 1 )
{
err_msg = "Several parent nodes found for node of id .";
throw new RdftreeDocumentMalFormedException(err_msg, null);
}
(...)
/* */ }
/* */ // Here we will catch the business logic exception and throw it again, but in between
/* */ // we'll add just a bit of processing to it.
/* */ // It would otherwise have been perfectly `legal' to just let it bubble up from where
/* */ // it was thrown in the code.
/* */ catch (RdftreeDocumentMalFormedException e)
/* */ {
/* */ // Here we inject the remaining now sure-to-be-used info in the err_msg:
/* */ err_msg = String.format(err_msg, this.toStringMinimal());
/* */ // and complete it with the info from the original business logic exception:
/* */ err_msg += ": " + e.getMessage();
/* */ throw new RdftreeDocumentMalFormedException(err_msg);
/* */ }
/* */ catch (XPathExpressionException e)
/* */ { err_msg = String.format(err_msg, this.toStringMinimal());
/* */ err_msg += ": unexpected Xpath error while looking for'list of children'node";
/* */ exp_msg += ": " + e.getClass().getName() + ", message: " + e.getMessage();
/* */ logger.debug("ERROR:" + err_msg);
/* */ logger.debug("ASSOCIATED EXCEPTION: " + exp_msg);
/* */ // Unexpected programmatical error -> unchecked exception
/* */ throw new RdftreeInternalRuntimeException (err_msg, e);
/* */ }
}
3%amp"e 2D
@SuppressWarnings("serial")
public class FwlMvcRuntimeException extends Exception
{
private final String err1essage = "A 'FWL MVC' error occurred, most probably due to a structural flaw
in the ACT-BO-DTO-DAO chain ";
@Override
public String getMessage()
{ return err1essage + ". Further info: " + super.get1essage();
}
1'
}
3%amp"e 3D
@SuppressWarnings("serial")
public class FwlExtensionConfigurationException extends RuntimeException
{
private String extension)a$e = "";
public F$lEtensionCon#igurationEception(String msg)
{ super(msg);
}
public F$lEtensionCon#igurationEception(String msg, Exception e)
{ super(msg, e);
}
public F$lEtensionCon#igurationEception(String msg, Exception e, String extension_name)
{ this(msg, e);
this.extension)a$e = extension_name;
}
@Override
public String getMessage()
{ return "Extension configuration error on extension = { " + this.extension)a$e + "}. " +
super.get1essage();
}
}
/ere ;e have !ot e%tracted the $ase error messa&e si!ce it !eeds to $e i!tert;i!ed ;ith some other varia!t dy!amica""y.
@.%.@ 0urther
8.5.8.1 To crash or not to crash :
httpDCC;;;.seGradio.!etCtra!scriptG,GerrorGha!d"i!&
Okay, so just one comment on that; I think stopping the program in case an error is sometimes certainly useful, for
example, in the embedded world, where people better stop doing whatever you do than doing it wrongly . So one
strategy of handling errors can actually be to stop the program in certain special environments.
0efinitely( you are definitely ri)ht there. "t8s often better to !ust not to do anythin) than to do the %ron) thin) but that is
usually the case in non;interactive systems or not directly interactive systems li7e in the embedded %orld.
@.1 'PA60rame.or/ Desi!n
@.1.1 8&tract from 2oschua BlochLs G=o. To Desi!n ' >ood 'PA and Bhy it <atters
http://lcsd05.cs.tamu.edu/slides/keynote.pdf
Design and Document for Inheritance or Else Prohibit it
Inheritance violates encapsulation !nyder" #$%&
' !ubclass sensitive to implementation details of superclass
If you allo( subclassing" document self-use
' )o( do methods use one another*
+onservative policy, all concrete classes final
-ad, .any concrete classes in /0!E libraries
1ood, AbstractSet" AbstractMap
0inimiJe 0utabilit&
1*
("asses shou"d $e immuta$"e u!"ess thereFs a &ood reaso! to do other;ise
W Adva!ta&esD simp"e threadGsafe reusa$"e
W 9isadva!ta&eD separate o$8ect for each va"ue
?f muta$"e 5eep stateGspace sma"" ;e""Gdefi!ed
W .a5e c"ear ;he! itIs "e&a" to ca"" ;hich method
@onFt use string i) a better t&!e e,ists
)tri!&s are cum$ersome errorGpro!e a!d s"o;
@onFt use )loating !oint )or monetar& values
Bi!ary f"oati!& poi!t causes i!e%act resu"tsR
"se 'ouble $KL bits% rather than )loat $MG bits%
Precisio! "oss is rea" performa!ce "oss !e&"i&i$"e
Aoid !eturn "alues that Demand E#ceptional Processing
return 2ero-length array or empty collection" not null
$hro% E#ceptions to Indicate E#ceptional &onditions
3on4t force client to use exceptions for control flo(,
[i.e. 5normal6 use of an ob7ect8function should not force client to handle possible exceptions]
+onversely" don4t fail silently
'aor (nchecked E#ceptions
+hec9ed : client must ta9e recovery action
;nchec9ed : [for] programming error
<veruse of chec9ed exceptions causes boilerplate
Include 'ailure)&apture Information in E#ceptions
=llo(s diagnosis and repair or recovery
For unchec9ed exceptions" message suffices
For chec9ed exceptions" provide accessors
@.1.2 ,onvenience methods
Ta5e a "oo5 at this e%amp"eD
/**
* @param action pass null if non applicable
*/
public static String getEtension-es!rop(String resPropertyName, ActionSupport action, Locale locale)
{ ...
}
/**
* Convenience. Same as 'getExtensionResProp(resPropertyName, invocation.getAction(), locale)'
* @param action pass null if non applicable
*/
public static String getEtension-es!rop (String resPropertyName, ActionInvocation invocation, Locale locale)
{ ...
}
?f ;e ca"" getExtensionResProp(something, null, something) the compi"er ;i"" comp"ai! it ca!!ot decide ;hich
to use. Ohich is fu""y u!dersta!da$"e.
Possi$"e so"utio!sD
G (ha!&e !ame of co!ve!ie!ce fu!ctio! to getExtensionResPropInvoc for e%amp"e
G Ohe! ca""i!& ;ith null cast null to o!e of the determi!i!& typesD
getExtensionResProp(something, (ActionSupport) null, something)
Remem$er that casti!& does !othi!& i! particu"ar it 8ust he"ps the compi"er to choose $et;ee! severa"
over"oaded methods.
O! casti!& !u""D see sectio! o! !u"".
1,
@.1." 'llo.in!6desi!nin! e&tensi$ility 4plu!in, e&tension point5
httpDCC;;;.8ava;or"d.comC8avatipsC8;G8avatip,4.htm"Ppa&eU1
@.3 Boo//eepin! code
U code that is !ot part of the $usi!ess "o&ic $ut is i!ter"eaved ;ith it i! order to 5eep data structures updated or ha!d"e
seco!dary aspects of the pro&ram -;i5ipedia0
)ee a"soD $oi"erp"ate code
@.@ ,lass template
// ==========================================================================
// LOGGING
// ==========================================================================
private Log logger = LogFactory.getLog("com.fhi.fwl.plugin_support");
/**
* For use in static context
*/
private static Log slogger= LogFactory.getLog("com.fhi.fwl.plugin_support");
/**
* @used#by IoC (e.g. spring) if in need of logger other than the default one specified above
*/
public void set'ogger(Log logger)
{ this.logger = logger;
slogger = logger;
// isDebugEnabled() is a check performed by the logger at the highest level: if debug is not
// enabled, this saves the overhead of computing the messages.
de%ugOn = de%ugOn && logger.is0e%ugEna%led();
}
/**
* @return
* @used#by IoC (e.g. spring) if in need of slogger other than the default one specified above
*/
public static void setSlogger(Log logger)
{ slogger = logger;
}
/**
* Activate or deactivate logs of debug level for this class
* To deactivate debugging for this class, set to false. This is final i.e. in that case, there will be
* no logging of level debug.
* To activate debugging for this class, set to true. The decision of logging of level debug will be
* left to higher levels.
*/
protected static boolean de%ugOn = true
&& slogger.is0e%ugEna%led();
C Suips
Mo e%tract su$Garray from array method PP
1+
There is )ystem.arraycopy $ut ;hatFs it doi!& i! )ystem P /o; am ? supposed to fi!d it P =? ;ou"d have $ee! "oo5i!&
i! Arrays #>
1J 'dd6Research
Re&u"ar e%pressio!s
2o&48 memo
1J.1Research
1J.1.1 Bhen .rappin! a class6o$Fect
ho; to redirect a"" ;rappi!& methods to the ;rapped c"ass ;ithout havi!& to e%p"icita""y re;rite them P
3%D
public class DOMDocument implements org.w3c.dom.Document
{
/**
* Wrapped org.w3c.dom.Document
*/
private org.w3c.dom.Document document;
// ----------------------------------------------------------------
// Implement Document -> Forward these to wrapped element
// ----------------------------------------------------------------
public Node appendChild(Node newChild) throws DOMException
{ return this.document.appendChild(newChild);
}
public Node cloneNode(boolean deep)
{ return this.document.cloneNode(deep);
}
etc.
11
1J.1.2 ,an A override a method and add6chan!e e&ceptions that are thro.n:
=it seems yes>
1J.1." =elper classes & composition pattern7 access to composite features
This is very &ood to rep"ace mu"tip"e i!herita!ce $ut composited o$8ects do !ot E!atura""yF have access to the attri$utes
& methods compositee o$8ect. =u!"ess they are pu$"ic>. Mo; if ;e do!Ft ;a!t to ma5e everythi!& pu$"ic is there a ;ay
to dec"are the composited o$8ect Efrie!d"yF a!d "et him have access to attri$utes that ;ou"d $e defi!ed ;ith a certai!
access "eve" P
1J.2Brite a$out
- Java:
-Reflection
-Class parametrization (Class<?>) Generics
-Class loaders
-Threads
-Error reporting
- environment:
-Log4j (2011.03)
-apache commmons
-unit tests
-Eclipse
-Create/run a project
-svn extension
-other extensions
- compilation and how it all works
java.sql.SQLException: ORA-01401: inserted value too large for column
java.sql.SQLException: Exception d'E/S: The Network Adapter could not establish the connection
11 Bi$lio!raphy
-RK[3N0 Barry Ru<e5 244, V3ffective Java 3%ceptio!sV httpDCC;;;.orac"e.comCtech!et;or5Cartic"esCe!tarchCeffectiveGe%ceptio!sG
41234'.htm"
-9O)/?0 :u!8a! 9oshi 2443 VBest Practises for Java 3%ceptio! /a!d"i!&V
httpDCCo!8ava.comCpu$CaCo!8avaC2443C11C11Ce%ceptio!s.htm"
-7/?3L(P07ra!cois /i"" 2411 V2es 3%ceptio!sV Po;erpoi!t prese!tatio!
144

También podría gustarte