The document provides an overview of Java basics including primitive types, operators, classes, objects, inheritance, polymorphism and more. It covers topics such as initialization, auto-boxing, strings, arrays, maps, loops, generics, access modifiers, fields, methods, constructors, abstraction, null values, reflection and casting.
Download as DOC, PDF, TXT or read online on Scribd
Download as doc, pdf, or txt
0 ratings0% found this document useful (0 votes)
750 views100 pages
Memo Java
The document provides an overview of Java basics including primitive types, operators, classes, objects, inheritance, polymorphism and more. It covers topics such as initialization, auto-boxing, strings, arrays, maps, loops, generics, access modifiers, fields, methods, constructors, abstraction, null values, reflection and casting.
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&les * // 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&les )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&le7 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ðer 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&le (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&le7 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&le 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&le <?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&le # <!-- 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&les 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