/usr/share/doc/aspectj-doc/adk15notebook/printable.html is in aspectj-doc 1.8.8-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 | <html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>The AspectJTM 5 Development Kit Developer's Notebook</title><link rel="stylesheet" type="text/css" href="aspectj-docs.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><meta name="description" content="This guide describes the changes to the AspectJ language in AspectJ 5. These include support for Java 5 (Tiger) features, support for an annotation-based development style for aspects, and new reflection and tools APIs. If you are new to AspectJ, we recommend you start by reading the programming guide."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book"><div class="titlepage"><div><div><h1 class="title"><a name="idp58907744"></a>The AspectJ<sup>TM</sup> 5 Development Kit Developer's Notebook</h1></div><div><div class="authorgroup"><div class="author"><h3 class="author"><span class="othername">the AspectJ Team</span></h3></div></div></div><div><div class="legalnotice"><a name="idp62614448"></a><p>
Copyright (c) 2004, 2005 Contributors,
All rights reserved.
</p></div></div><div><div class="abstract"><p class="title"><b>Abstract</b></p><p>
This guide describes the changes to the AspectJ language
in AspectJ 5. These include support for Java 5 (Tiger) features,
support for an annotation-based development style for aspects,
and new reflection and tools APIs.
If you are new to AspectJ, we recommend you start
by reading the programming guide.
</p></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="chapter"><a href="#jpsigs">1. Join Point Signatures</a></span></dt><dd><dl><dt><span class="sect1"><a href="#join-point-matching">Join Point Matching</a></span></dt><dt><span class="sect1"><a href="#join-point-signatures">Join Point Signatures</a></span></dt><dd><dl><dt><span class="sect2"><a href="#method-call-join-point-signatures">Method call join point signatures</a></span></dt><dt><span class="sect2"><a href="#method-execution-join-point-signatures">Method execution join point signatures</a></span></dt><dt><span class="sect2"><a href="#field-get-and-set-join-point-signatures">Field get and set join point signatures</a></span></dt></dl></dd><dt><span class="sect1"><a href="#join-point-modifiers">Join Point Modifiers</a></span></dt><dt><span class="sect1"><a href="#join-point-matching-summary">Summary of Join Point Matching</a></span></dt></dl></dd><dt><span class="chapter"><a href="#annotations">2. Annotations</a></span></dt><dd><dl><dt><span class="sect1"><a href="#annotations-inJava5">Annotations in Java 5</a></span></dt><dd><dl><dt><span class="sect2"><a href="#using-annotations">Using Annotations</a></span></dt><dt><span class="sect2"><a href="#retention-policies">Retention Policies</a></span></dt><dt><span class="sect2"><a href="#accessing-annotations-at-runtime">Accessing Annotations at Runtime</a></span></dt><dt><span class="sect2"><a href="#annotation-inheritance">Annotation Inheritance</a></span></dt></dl></dd><dt><span class="sect1"><a href="#annotations-aspectmembers">Annotating Aspects</a></span></dt><dt><span class="sect1"><a href="#annotations-pointcuts-and-advice">Join Point Matching based on Annotations</a></span></dt><dd><dl><dt><span class="sect2"><a href="#annotation-patterns">Annotation Patterns</a></span></dt><dt><span class="sect2"><a href="#type-patterns">Type Patterns</a></span></dt><dt><span class="sect2"><a href="#signaturePatterns">Signature Patterns</a></span></dt><dt><span class="sect2"><a href="#example-pointcuts">Example Pointcuts</a></span></dt><dt><span class="sect2"><a href="#runtime-type-matching-and-context-exposure">Runtime type matching and context exposure</a></span></dt><dt><span class="sect2"><a href="#package-and-parameter-annotations">Package and Parameter Annotations</a></span></dt><dt><span class="sect2"><a href="#annotation-inheritance-and-pointcut-matching">Annotation Inheritance and pointcut matching</a></span></dt><dt><span class="sect2"><a href="#matchingOnAnnotationValues">Matching based on annotation values</a></span></dt></dl></dd><dt><span class="sect1"><a href="#annotations-decp">Using Annotations with declare statements</a></span></dt><dd><dl><dt><span class="sect2"><a href="#declare-error-and-declare-warning">Declare error and declare warning</a></span></dt><dt><span class="sect2"><a href="#declare-parents">declare parents</a></span></dt><dt><span class="sect2"><a href="#declare-precedence">declare precedence</a></span></dt></dl></dd><dt><span class="sect1"><a href="#annotations-declare">Declare Annotation</a></span></dt><dt><span class="sect1"><a href="#annotations-itds">Inter-type Declarations</a></span></dt></dl></dd><dt><span class="chapter"><a href="#generics">3. Generics</a></span></dt><dd><dl><dt><span class="sect1"><a href="#generics-inJava5">Generics in Java 5</a></span></dt><dd><dl><dt><span class="sect2"><a href="#declaring-generic-types">Declaring Generic Types</a></span></dt><dt><span class="sect2"><a href="#using-generic-and-parameterized-types">Using Generic and Parameterized Types</a></span></dt><dt><span class="sect2"><a href="#subtypes-supertypes-and-assignability">Subtypes, Supertypes, and Assignability</a></span></dt><dt><span class="sect2"><a href="#generic-methods-and-constructors">Generic Methods and Constructors</a></span></dt><dt><span class="sect2"><a href="#erasure">Erasure</a></span></dt></dl></dd><dt><span class="sect1"><a href="#generics-inAspectJ5">Generics in AspectJ 5</a></span></dt><dd><dl><dt><span class="sect2"><a href="#matching-generic-and-parameterized-types-in-pointcut-expressions">Matching generic and parameterized types in pointcut expressions</a></span></dt><dt><span class="sect2"><a href="#inter-type-declarations">Inter-type Declarations</a></span></dt><dt><span class="sect2"><a href="#declare-parents">Declare Parents</a></span></dt><dt><span class="sect2"><a href="#declare-soft">Declare Soft</a></span></dt><dt><span class="sect2"><a href="#generic-aspects">Generic Aspects</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#autoboxing">4. Autoboxing and Unboxing</a></span></dt><dd><dl><dt><span class="sect1"><a href="#boxing-inJava5">Autoboxing and Unboxing in Java 5</a></span></dt><dt><span class="sect1"><a href="#autoboxing-in-aspectj5">Autoboxing and Join Point matching in AspectJ 5</a></span></dt><dt><span class="sect1"><a href="#autoboxing-and-method-dispatch">Inter-type method declarations and method dispatch</a></span></dt></dl></dd><dt><span class="chapter"><a href="#covariance">5. Covariance</a></span></dt><dd><dl><dt><span class="sect1"><a href="#covariance-inJava5">Covariance in Java 5</a></span></dt><dt><span class="sect1"><a href="#covariance-and-join-point-matching">Covariant methods and Join Point matching</a></span></dt></dl></dd><dt><span class="chapter"><a href="#varargs">6. Varargs</a></span></dt><dd><dl><dt><span class="sect1"><a href="#varargs-inJava5">Variable-length Argument Lists in Java 5</a></span></dt><dd><dl><dt><span class="sect2"><a href="#calling-methods-and-constructors-with-variable-length-arguments">Calling Methods and Constructors with variable-length arguments</a></span></dt></dl></dd><dt><span class="sect1"><a href="#varargs-in-pcds">Using Variable-length arguments in advice and pointcut expressions</a></span></dt><dd><dl><dt><span class="sect2"><a href="#matching-signatures-based-on-variable-length-argument-types">Matching signatures based on variable length argument types</a></span></dt><dt><span class="sect2"><a href="#exposing-variable-length-arguments-as-context-in-pointcuts-and-advice">Exposing variable-length arguments as context in pointcuts and advice</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#enumeratedtypes">7. Enumerated Types</a></span></dt><dd><dl><dt><span class="sect1"><a href="#enums-in-java5">Enumerated Types in Java 5</a></span></dt><dt><span class="sect1"><a href="#enums-in-aspectj5">Enumerated Types in AspectJ 5</a></span></dt></dl></dd><dt><span class="chapter"><a href="#pertypewithin">8. The pertypewithin Aspect Instantiation Model</a></span></dt><dt><span class="chapter"><a href="#ataspectj">9. An Annotation Based Development Style</a></span></dt><dd><dl><dt><span class="sect1"><a href="#ataspectj-intro">Introduction</a></span></dt><dt><span class="sect1"><a href="#ataspectj-aspects">Aspect Declarations</a></span></dt><dd><dl><dt><span class="sect2"><a href="#limitations">Limitations</a></span></dt></dl></dd><dt><span class="sect1"><a href="#ataspectj-pcadvice">Pointcuts and Advice</a></span></dt><dd><dl><dt><span class="sect2"><a href="#pointcuts">Pointcuts</a></span></dt><dt><span class="sect2"><a href="#advice">Advice</a></span></dt></dl></dd><dt><span class="sect1"><a href="#ataspectj-itds">Inter-type Declarations</a></span></dt><dd><dl><dt><span class="sect2"><a href="#atDeclareParents">@DeclareParents</a></span></dt><dt><span class="sect2"><a href="#atDeclareMixin">@DeclareMixin</a></span></dt></dl></dd><dt><span class="sect1"><a href="#ataspectj-declare">Declare statements</a></span></dt><dt><span class="sect1"><a href="#ataspectj-aspectof">aspectOf() and hasAspect() methods</a></span></dt></dl></dd><dt><span class="chapter"><a href="#reflection">10. New Reflection Interfaces</a></span></dt><dd><dl><dt><span class="sect1"><a href="#reflection_api">Using AjTypeSystem</a></span></dt></dl></dd><dt><span class="chapter"><a href="#miscellaneous">11. Other Changes in AspectJ 5</a></span></dt><dd><dl><dt><span class="sect1"><a href="#pointcuts">Pointcuts</a></span></dt><dt><span class="sect1"><a href="#declare-soft">Declare Soft</a></span></dt></dl></dd><dt><span class="chapter"><a href="#ltw">12. Load-Time Weaving</a></span></dt><dd><dl><dt><span class="sect1"><a href="#ltw-introduction">Introduction</a></span></dt></dl></dd></dl></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="jpsigs"></a>Chapter 1. Join Point Signatures</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="sect1"><a href="#join-point-matching">Join Point Matching</a></span></dt><dt><span class="sect1"><a href="#join-point-signatures">Join Point Signatures</a></span></dt><dd><dl><dt><span class="sect2"><a href="#method-call-join-point-signatures">Method call join point signatures</a></span></dt><dt><span class="sect2"><a href="#method-execution-join-point-signatures">Method execution join point signatures</a></span></dt><dt><span class="sect2"><a href="#field-get-and-set-join-point-signatures">Field get and set join point signatures</a></span></dt></dl></dd><dt><span class="sect1"><a href="#join-point-modifiers">Join Point Modifiers</a></span></dt><dt><span class="sect1"><a href="#join-point-matching-summary">Summary of Join Point Matching</a></span></dt></dl></div><p>
Many of the extensions to the AspectJ language to address the new features of
Java 5 are derived from a simple set of principles for join point
matching. In this section, we outline these principles as a foundation
for understanding the matching rules in the presence of annotations,
generics, covariance, varargs, and autoboxing.
</p><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="join-point-matching"></a>Join Point Matching</h2></div></div></div><p>AspectJ supports 11 different kinds of join points. These are
the <code class="literal">method call, method execution, constructor call,
constructor execution, field get, field set, pre-initialization,
initialization, static initialization, handler,</code> and
<code class="literal">advice execution</code> join points.</p><p>The <span class="emphasis"><em>kinded</em></span> pointcut designators match
based on the kind of a join point. These are the <code class="literal">call,
execution, get, set, preinitialization, initialization,
staticinitialization, handler,</code> and <code class="literal">adviceexecution</code>
designators.</p><p>A kinded pointcut is written using patterns, some of which
match based on <span class="emphasis"><em>signature</em></span>, and some of which
match based on <span class="emphasis"><em>modifiers</em></span>. For example, in
the <code class="literal">call</code> pointcut designator:</p><pre class="programlisting">
call(ModifierPattern TypePattern TypePattern.IdPattern(TypePatternList) ThrowsPattern)
</pre><p>the modifiers matching patterns are <code class="literal">ModifierPattern</code>
and <code class="literal">ThrowsPattern</code>, and the signature matching patterns
are <code class="literal">TypePattern TypePattern.IdPattern(TypePatternList)</code>.
</p><p>
A join point has potentially multiple signatures, but only one set of
modifiers. <span class="emphasis"><em>A kinded primitive pointcut matches a particular join point
if and only if</em></span>:
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">They are of the same kind</li><li class="listitem">The signature pattern (exactly) matches at least one
signature of the join point</li><li class="listitem">The modifiers pattern matches the modifiers of the
subject of the join point</li></ol></div><p>These rules make it very easily to quickly determine whether a
given pointcut matches a given join point. In the next two sections,
we describe what the signature(s) of a join point are, and what the
subjects of join points are.</p></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="join-point-signatures"></a>Join Point Signatures</h2></div></div></div><p>Call, execution, get, and set join points may potentially have multiple
signatures. All other join points have exactly one signature. The
following table summarizes the constituent parts of a join point
signature for the different kinds of join point.</p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col><col><col><col><col><col><col></colgroup><thead><tr><th>Join Point Kind</th><th>Return Type</th><th>Declaring Type</th><th>Id</th><th>Parameter Types</th><th>Field Type</th><th>Exception Type</th></tr></thead><tbody><tr><td>Method call</td><td>+</td><td>+</td><td>+</td><td>+</td><td> </td><td> </td></tr><tr><td>Method execution</td><td>+</td><td>+</td><td>+</td><td>+</td><td> </td><td> </td></tr><tr><td>Constructor call</td><td> </td><td>+</td><td> </td><td>+</td><td> </td><td> </td></tr><tr><td>Constructor execution</td><td> </td><td>+</td><td> </td><td>+</td><td> </td><td> </td></tr><tr><td>Field get</td><td> </td><td>+</td><td>+</td><td> </td><td>+</td><td> </td></tr><tr><td>Field set</td><td> </td><td>+</td><td>+</td><td> </td><td>+</td><td> </td></tr><tr><td>Pre-initialization</td><td> </td><td>+</td><td> </td><td>+</td><td> </td><td> </td></tr><tr><td>Initialization</td><td> </td><td>+</td><td> </td><td>+</td><td> </td><td> </td></tr><tr><td>Static initialization</td><td> </td><td>+</td><td> </td><td> </td><td> </td><td> </td></tr><tr><td>Handler</td><td> </td><td> </td><td> </td><td> </td><td> </td><td>+</td></tr><tr><td>Advice execution</td><td> </td><td>+</td><td> </td><td>+</td><td> </td><td> </td></tr></tbody></table></div><p>Note that whilst an advice excetution join point has a
signature comprising the declaring type of the advice and the
advice parameter types, the <code class="literal">adviceexecution</code>
pointcut designator does not support matching based on this
signature.</p><p>The signatures for most of the join point kinds should be
self-explanatory, except for field get and set, and method call and execution
join points, which can have multiple signatures. Each signature of
a method call or execution join point has the same id and parameter
types, but the declaring type and return type (with covariance) may vary.
Each signature of a field get or set join point has the same id and field
type, but the declaring type may vary.
</p><p>The following sections examine signatures for these join points
in more detail.</p><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="method-call-join-point-signatures"></a>Method call join point signatures</h3></div></div></div><p>
For a call join point where a call is made to a method
<code class="literal">m(parameter_types)</code> on a target type <code class="literal">T</code> (where
<code class="literal">T</code> is the static type of the target):
</p><pre class="programlisting">
T t = new T();
t.m("hello"); <= call join point occurs when this line is executed
</pre><p>
Then the signature <code class="literal">R(T) T.m(parameter_types)</code> is a signature
of the call join point, where <code class="literal">R(T)</code> is the return
type of <code class="literal">m</code> in <code class="literal">T</code>, and
<code class="literal">parameter_types</code> are the parameter types of
<code class="literal">m</code>. If <code class="literal">T</code> itself does not
declare a definition of <code class="literal">m(parameter_types)</code>, then
<code class="literal">R(T)</code> is the return type in the definition of
<code class="literal">m</code> that <code class="literal">T</code> inherits. Given the
call above, and the definition of <code class="literal">T.m</code>:
</p><pre class="programlisting">
interface Q {
R m(String s);
}
class P implements Q {
R m(String s) {...}
}
class S extends P {
R' m(String s) {...}
}
class T extends S {}
</pre><p>Then <code class="literal">R' T.m(String)</code> is a signature of the
call join point for <code class="literal">t.m("hello")</code>.</p><p>
For each ancestor (super-type) <code class="literal">A</code> of <code class="literal">T</code>,
if <code class="literal">m(parameter_types)</code> is defined for that super-type, then
<code class="literal">R(A) A.m(parameter_types)</code> is a signature of the call join
point, where <code class="literal">R(A)</code> is the return type of <code class="literal">
m(parameter_types)</code> as defined in <code class="literal">A</code>, or as inherited
by <code class="literal">A</code> if <code class="literal">A</code> itself does not
provide a definition of <code class="literal">m(parameter_types)</code>.
</p><p>
Continuing the example from above,we can deduce that
</p><pre class="programlisting">
R' S.m(String)
R P.m(String)
R Q.m(String)
</pre><p>are all additional signatures for the call join point arising
from the call <code class="literal">t.m("hello")</code>. Thus this call
join point has four signatures in total. Every signature has the same
id and parameter types, and a different declaring type.</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="method-execution-join-point-signatures"></a>Method execution join point signatures</h3></div></div></div><p>Join point signatures for execution join points are defined
in a similar manner to signatures for call join points. Given the
hierarchy:
</p><pre class="programlisting">
interface Q {
R m(String s);
}
class P implements Q {
R m(String s) {...}
}
class S extends P {
R' m(String s) {...}
}
class T extends S { }
class U extends T {
R' m(String s) {...}
}
</pre><p>Then the execution join point signatures arising as a result
of the call to <code class="literal">u.m("hello")</code> are: </p><pre class="programlisting">
R' U.m(String)
R' S.m(String)
R P.m(String)
R Q.m(String)
</pre><p>Each signature has the same id and parameter types, and a
different declaring type. There is one signature for each type
that provides its own declaration of the method. Hence in this
example there is no signature <code class="literal">R' T.m(String)</code>
as <code class="literal">T</code> does not provide its own declaration of
the method.</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="field-get-and-set-join-point-signatures"></a>Field get and set join point signatures</h3></div></div></div><p>
For a field get join point where an access is made to a field
<code class="literal">f</code> of type <code class="literal">F</code>
on a object with declared type <code class="literal">T</code>, then
<code class="literal">F T.f</code> is a signature of the get join point.
</p><p>
If <code class="literal">T</code> does not directly declare a member
<code class="literal">f</code>, then for each super type <code class="literal">S</code>
of <code class="literal">T</code>, up to and including the most specific
super type of <code class="literal">T</code> that does declare the member
<code class="literal">f</code>, <code class="literal">F S.f</code> is a signature
of the join point. For example, given the hierarchy:
</p><pre class="programlisting">
class P {
F f;
}
class S extends P {
F f;
}
class T extends S { }
</pre><p>
Then the join point signatures for a field get join point of
the field <code class="literal">f</code> on an object with declared type
<code class="literal">T</code> are:
</p><pre class="programlisting">
F S.f
F T.f
</pre><p>The signatures for a field set join point are derived in an
identical manner.</p></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="join-point-modifiers"></a>Join Point Modifiers</h2></div></div></div><p>Every join point has a single set of modifiers - these include
the standard Java modifiers such as <code class="literal">public, private,
static, abstract</code> etc., any annotations, and the throws
clauses of methods and constructors. These modifiers are the
modifiers of the <span class="emphasis"><em>subject</em></span> of the join point.</p><p>
The following table defines the join point subject for each kind
of join point.
</p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col><col></colgroup><thead><tr><th>Join Point Kind</th><th>Subject</th></tr></thead><tbody><tr><td>Method call</td><td>The method picked out by Java as
the static target of the method call.</td></tr><tr><td>Method execution</td><td>The method that is executing.</td></tr><tr><td>Constructor call</td><td>The constructor being called.</td></tr><tr><td>Constructor execution</td><td>The constructor executing.</td></tr><tr><td>Field get</td><td>The field being accessed.</td></tr><tr><td>Field set</td><td>The field being set.</td></tr><tr><td>Pre-initialization</td><td>The first constructor executing in
this constructor chain.</td></tr><tr><td>Initialization</td><td>The first constructor executing in
this constructor chain.</td></tr><tr><td>Static initialization</td><td>The type being initialized.</td></tr><tr><td>Handler</td><td>The declared type of the
exception being handled.</td></tr><tr><td>Advice execution</td><td>The advice being executed.</td></tr></tbody></table></div><p>For example, given the following types</p><pre class="programlisting">
public class X {
@Foo
protected void doIt() {...}
}
public class Y extends X {
public void doIt() {...}
}
</pre><p>Then the modifiers for a call to <code class="literal">(Y y) y.doIt()</code>
are simply <code class="literal">{public}</code>. The modifiers for a call to
<code class="literal">(X x) x.doIt()</code> are <code class="literal">{@Foo,protected}</code>.
</p></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="join-point-matching-summary"></a>Summary of Join Point Matching</h2></div></div></div><p>
A join point has potentially multiple signatures, but only one set of
modifiers. <span class="emphasis"><em>A kinded primitive pointcut matches a particular join point
if and only if</em></span>:
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">They are of the same kind</li><li class="listitem">The signature pattern (exactly) matches at least one
signature of the join point</li><li class="listitem">The modifiers pattern matches the modifiers of the
subject of the join point</li></ol></div><p>Given the hierarchy</p><pre class="programlisting">
interface Q {
R m(String s);
}
class P implements Q {
@Foo
public R m(String s) {...}
}
class S extends P {
@Bar
public R' m(String s) {...}
}
class T extends S {}
</pre><p>and the program fragment:</p><pre class="programlisting">
P p = new P();
S s = new S();
T t = new T();
...
p.m("hello");
s.m("hello");
t.m("hello");
</pre><p>
The the pointcut <code class="literal">call(@Foo R P.m(String))</code> matches the
call <code class="literal">p.m("hello")</code> since both the signature and the
modifiers match. It does not match the call <code class="literal">s.m("hello")</code>
because even though the signature pattern matches one of the signatures
of the join point, the modifiers pattern does not match the modifiers of
the method m in S which is the static target of the call.
</p><p>The pointcut <code class="literal">call(R' m(String))</code> matches the
calls <code class="literal">t.m("hello")</code> and <code class="literal">s.m("hello")</code>.
It does not match the call <code class="literal">p.m("hello")</code> since the
signature pattern does not match any signature for the call join point
of m in P.</p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="annotations"></a>Chapter 2. Annotations</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="sect1"><a href="#annotations-inJava5">Annotations in Java 5</a></span></dt><dd><dl><dt><span class="sect2"><a href="#using-annotations">Using Annotations</a></span></dt><dt><span class="sect2"><a href="#retention-policies">Retention Policies</a></span></dt><dt><span class="sect2"><a href="#accessing-annotations-at-runtime">Accessing Annotations at Runtime</a></span></dt><dt><span class="sect2"><a href="#annotation-inheritance">Annotation Inheritance</a></span></dt></dl></dd><dt><span class="sect1"><a href="#annotations-aspectmembers">Annotating Aspects</a></span></dt><dt><span class="sect1"><a href="#annotations-pointcuts-and-advice">Join Point Matching based on Annotations</a></span></dt><dd><dl><dt><span class="sect2"><a href="#annotation-patterns">Annotation Patterns</a></span></dt><dt><span class="sect2"><a href="#type-patterns">Type Patterns</a></span></dt><dt><span class="sect2"><a href="#signaturePatterns">Signature Patterns</a></span></dt><dt><span class="sect2"><a href="#example-pointcuts">Example Pointcuts</a></span></dt><dt><span class="sect2"><a href="#runtime-type-matching-and-context-exposure">Runtime type matching and context exposure</a></span></dt><dt><span class="sect2"><a href="#package-and-parameter-annotations">Package and Parameter Annotations</a></span></dt><dt><span class="sect2"><a href="#annotation-inheritance-and-pointcut-matching">Annotation Inheritance and pointcut matching</a></span></dt><dt><span class="sect2"><a href="#matchingOnAnnotationValues">Matching based on annotation values</a></span></dt></dl></dd><dt><span class="sect1"><a href="#annotations-decp">Using Annotations with declare statements</a></span></dt><dd><dl><dt><span class="sect2"><a href="#declare-error-and-declare-warning">Declare error and declare warning</a></span></dt><dt><span class="sect2"><a href="#declare-parents">declare parents</a></span></dt><dt><span class="sect2"><a href="#declare-precedence">declare precedence</a></span></dt></dl></dd><dt><span class="sect1"><a href="#annotations-declare">Declare Annotation</a></span></dt><dt><span class="sect1"><a href="#annotations-itds">Inter-type Declarations</a></span></dt></dl></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="annotations-inJava5"></a>Annotations in Java 5</h2></div></div></div><p>
This section provides the essential information about annotations in
Java 5 needed to understand how annotations are treated in AspectJ 5.
For a full introduction to annotations in Java, please see the
documentation for the Java 5 SDK.
</p><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="using-annotations"></a>Using Annotations</h3></div></div></div><p>
Java 5 introduces <span class="emphasis"><em>annotation types</em></span> which can
be used to express metadata relating to program members in the
form of <span class="emphasis"><em>annotations</em></span>. Annotations in Java 5
can be applied to package and type declarations (classes,
interfaces, enums, and annotations), constructors, methods,
fields, parameters, and variables. Annotations are specified in the
program source by using the <code class="literal">@</code> symbol. For example,
the following piece of code uses the <code class="literal">@Deprecated</code>
annotation to indicate that the <code class="literal">obsoleteMethod()</code>
has been deprecated:
</p><pre class="programlisting">
@Deprecated
public void obsoleteMethod() { ... }
</pre><p>
Annotations may be <span class="emphasis"><em>marker annotations</em></span>,
<span class="emphasis"><em>single-valued annotations</em></span>, or
<span class="emphasis"><em>multi-valued annotations</em></span>.
Annotation types with no members or that provide default values
for all members may be used simply as marker annotations, as in
the deprecation example above. Single-value annotation types have
a single member, and the annotation may be written in one of
two equivalent forms:
</p><pre class="programlisting">
@SuppressWarnings({"unchecked"})
public void someMethod() {...}
</pre><p>
or
</p><pre class="programlisting">
@SuppressWarnings(value={"unchecked"})
public void someMethod() {...}
</pre><p>
Multi-value annotations must use the <code class="literal">member-name=value
</code> syntax to specify annotation values. For example:
</p><pre class="programlisting">
@Authenticated(role="supervisor",clearanceLevel=5)
public void someMethod() {...}
</pre></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="retention-policies"></a>Retention Policies</h3></div></div></div><p>
Annotations can have one of three retention policies:
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Source-file retention</span></dt><dd><p>
Annotations with source-file retention are read by the
compiler during the compilation process, but are not
rendered in the generated <code class="literal">.class</code> files.
</p></dd><dt><span class="term">Class-file retention</span></dt><dd><p>
This is the default retention policy. Annotations
with class-file retention are read by the compiler
and also retained in the generated <code class="literal">
.class</code> files.
</p></dd><dt><span class="term">Runtime retention</span></dt><dd><p>
Annotations with runtime retention are read by the
compiler, retained in the generated <code class="literal">
.class</code> files, and also made available
at runtime.
</p></dd></dl></div><p>Local variable annotations are not retained in class files (or at runtime)
regardless of the retention policy set on the annotation type. See JLS 9.6.1.2.</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="accessing-annotations-at-runtime"></a>Accessing Annotations at Runtime</h3></div></div></div><p>
Java 5 supports a new interface,
<code class="literal">java.lang.reflect.AnnotatedElement</code>, that is
implemented by the reflection classes in Java (<code class="literal">Class</code>,
<code class="literal">Constructor</code>,
<code class="literal">Field</code>, <code class="literal">Method</code>, and
<code class="literal">Package</code>). This interface gives you access
to annotations <span class="emphasis"><em>that have runtime retention</em></span> via
the <code class="literal">getAnnotation</code>, <code class="literal">getAnnotations</code>,
and <code class="literal">isAnnotationPresent</code>. Because annotation types are
just regular Java classes, the annotations returned by these methods
can be queried just like any regular Java object.
</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="annotation-inheritance"></a>Annotation Inheritance</h3></div></div></div><p>
It is important to understand the rules relating to inheritance of
annotations, as these have a bearing on join point matching
based on the presence or absence of annotations.
</p><p>
By default annotations are <span class="emphasis"><em>not</em></span> inherited. Given
the following program
</p><pre class="programlisting">
@MyAnnotation
class Super {
@Oneway public void foo() {}
}
class Sub extends Super {
public void foo() {}
}
</pre><p>
Then <code class="literal">Sub</code> <span class="emphasis"><em>does not</em></span> have
the <code class="literal">MyAnnotation</code> annotation, and
<code class="literal">Sub.foo()</code> is not an <code class="literal">@Oneway</code>
method, despite the fact that it overrides
<code class="literal">Super.foo()</code> which is.
</p><p>
If an annotation type has the meta-annotation <code class="literal">@Inherited</code>
then an annotation of that type on a <span class="emphasis"><em>class</em></span> will cause
the annotation to be inherited by sub-classes. So, in the example
above, if the <code class="literal">MyAnnotation</code> type had the
<code class="literal">@Inherited</code> attribute, then <code class="literal">Sub</code>
would have the <code class="literal">MyAnnotation</code> annotation.
</p><p>
<code class="literal">@Inherited</code> annotations are not inherited when used to
annotate anything other than a type. A type
that implements one or more interfaces never inherits any annotations from
the interfaces it implements.
</p></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="annotations-aspectmembers"></a>Annotating Aspects</h2></div></div></div><p>
AspectJ 5 supports annotations on aspects, and on method, field,
constructor, advice, and inter-type declarations within aspects.
Method and advice parameters may also be annotated.
Annotations are not permitted on pointcut declarations or on
<code class="literal">declare</code> statements.
</p><p>
The following example illustrates the use of annotations in aspects:
</p><pre class="programlisting">
@AspectAnnotation
public abstract aspect ObserverProtocol {
@InterfaceAnnotation
interface Observer {}
@InterfaceAnnotation
interface Subject {}
@ITDFieldAnnotation
private List<Observer> Subject.observers;
@ITDMethodAnnotation
public void Subject.addObserver(Observer o) {
observers.add(o);
}
@ITDMethodAnnotation
public void Subject.removeObserver(Observer o) {
observers.remove(o);
}
@MethodAnnotation
private void notifyObservers(Subject subject) {
for(Observer o : subject.observers)
notifyObserver(o,subject);
}
/**
* Delegate to concrete sub-aspect the actual form of
* notification for a given type of Observer.
*/
@MethodAnnotation
protected abstract void notifyObserver(Observer o, Subject s);
/* no annotations on pointcuts */
protected abstract pointcut observedEvent(Subject subject);
@AdviceAnnotation
after(Subject subject) returning : observedEvent(subject) {
notifyObservers(subject);
}
}
</pre><p>
An annotation on an aspect will be inherited by sub-aspects, iff it has
the <code class="literal">@Inherited</code> meta-annotation.
</p><p>
AspectJ 5 supports a new XLint warning, "the pointcut associated with this
advice does not match any join points". The warning is enabled by default and
will be emitted by the compiler if the pointcut expression associated with an
advice statement can be statically determined to not match any join points. The
warning can be suppressed for an individual advice statement by using the
<code class="literal">@SuppressAjWarnings({"adviceDidNotMatch"})</code> annotation. This works in
the same way as the Java 5 SuppressWarnings annotation (See JLS 9.6.1.5), but has class file
retention.
</p><pre class="programlisting">
import org.aspectj.lang.annotation.SuppressAjWarnings;
public aspect AnAspect {
pointcut anInterfaceOperation() : execution(* AnInterface.*(..));
@SuppressAjWarnings // may not match if there are no implementers of the interface...
before() : anInterfaceOperation() {
// do something...
}
@SuppressAjWarnings("adviceDidNotMatch") // alternate form
after() returning : anInterfaceOperation() {
// do something...
}
}
</pre></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="annotations-pointcuts-and-advice"></a>Join Point Matching based on Annotations</h2></div></div></div><p>
This section discusses changes to type pattern and signature pattern matching in
AspectJ 5 that support matching join points based on the presence or absence of
annotations. We then discuss means of exposing annotation values within the body
of advice.
</p><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="annotation-patterns"></a>Annotation Patterns</h3></div></div></div><p>
For any kind of annotated element (type, method, constructor, package, etc.),
an annotation pattern can be used to match against the set of annotations
on the annotated element.An annotation pattern element has one of two basic
forms:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">@<qualified-name>, for example, @Foo, or
@org.xyz.Foo.</li><li class="listitem">@(<type-pattern>), for example, @(org.xyz..*), or
@(Foo || Boo)</li></ul></div><p>These simple elements may be negated using <code class="literal">!</code>, and
combined by simple concatentation. The pattern <code class="literal">@Foo @Boo</code>
matches an annotated element that has both an annotation of type <code class="literal">Foo</code>
and an annotation of type <code class="literal">Boo</code>.</p><p>Some examples of annotation patterns follow:</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">@Immutable</span></dt><dd><p>
Matches any annotated element which has an annotation of
type <code class="literal">Immutable</code>.
</p></dd><dt><span class="term">!@Persistent</span></dt><dd><p>
Matches any annotated element which does not have an annotation of
type <code class="literal">Persistent</code>.
</p></dd><dt><span class="term">@Foo @Goo</span></dt><dd><p>
Matches any annotated element which has both an annotation of type <code class="literal">Foo</code> and
an annotation of type <code class="literal">Goo</code>.
</p></dd><dt><span class="term">@(Foo || Goo)</span></dt><dd><p>
Matches any annotated element which has either an annotation of a type matching
the type pattern <code class="literal">(Foo || Goo)</code>.
In other words, an annotated element with either an
annotation of type <code class="literal">Foo</code> or
an annotation of type <code class="literal">Goo</code> (or both). (The parenthesis are required in this example).
</p></dd><dt><span class="term">@(org.xyz..*)</span></dt><dd><p>
Matches any annotated element which has either an annotation of a type matching
the type pattern <code class="literal">(org.xyz..*)</code>.
In other words, an annotated element with an annotation that is declared in the
org.xyz package or a sub-package. (The parenthesis are required in this example).
</p></dd></dl></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="type-patterns"></a>Type Patterns</h3></div></div></div><p>AspectJ 1.5 extends type patterns to allow an optional <code class="literal">AnnotationPattern</code>
prefix.</p><pre class="programlisting">
TypePattern := SimpleTypePattern |
'!' TypePattern |
'(' AnnotationPattern? TypePattern ')'
TypePattern '&&' TypePattern |
TypePattern '||' TypePattern
SimpleTypePattern := DottedNamePattern '+'? '[]'*
DottedNamePattern := FullyQualifiedName RestOfNamePattern? |
'*' NotStarNamePattern?
RestOfNamePattern := '..' DottedNamePattern |
'*' NotStarNamePattern?
NotStarNamePattern := FullyQualifiedName RestOfNamePattern? |
'..' DottedNamePattern
FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)*
</pre><p>Note that in most cases when annotations are used as part of a type pattern,
the parenthesis are required (as in <code class="literal">(@Foo Hello+)</code>). In
some cases (such as a type pattern used within a <code class="literal">within</code> or
<code class="literal">handler</code>
pointcut expression), the parenthesis are optional:</p><pre class="programlisting">
OptionalParensTypePattern := AnnotationPattern? TypePattern
</pre><p>
The following examples illustrate the use of annotations in type
patterns:
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">(@Immutable *)</span></dt><dd><p>
Matches any type with an <code class="literal">@Immutable</code> annotation.
</p></dd><dt><span class="term">(!@Immutable *)</span></dt><dd><p>
Matches any type which does not have an <code class="literal">@Immutable</code> annotation.
</p></dd><dt><span class="term"> (@Immutable (org.xyz.* || org.abc.*))</span></dt><dd><p>
Matches any type in the <code class="literal">org.xyz</code> or <code class="literal">org.abc</code>
packages with the <code class="literal">@Immutable</code> annotation.
</p></dd><dt><span class="term">((@Immutable Foo+) || Goo)</span></dt><dd><p>
Matches a type <code class="literal">Foo</code> or any of its subtypes, which have the <code class="literal">@Immutable</code>
annotation, or a type <code class="literal">Goo</code>.
</p></dd><dt><span class="term">((@(Immutable || NonPersistent) org.xyz..*)</span></dt><dd><p>
Matches any type in a package beginning with the prefix <code class="literal">org.xyz</code>,
which has either the <code class="literal">@Immutable</code> annotation or the
<code class="literal">@NonPersistent</code> annotation.
</p></dd><dt><span class="term">(@Immutable @NonPersistent org.xyz..*)</span></dt><dd><p>
Matches any type in a package beginning with the prefix <code class="literal">org.xyz</code>,
which has both an <code class="literal">@Immutable</code> annotation and an
<code class="literal">@NonPersistent</code> annotation.
</p></dd><dt><span class="term"> (@(@Inherited *) org.xyz..*)</span></dt><dd><p>
Matches any type in a package beginning with the prefix <code class="literal">org.xyz</code>,
which has an inheritable annotation. The annotation pattern
<code class="literal">@(@Inherited *)</code> matches any annotation of a type matching the
type pattern <code class="literal">@Inherited *</code>, which in turn matches any type with the
<code class="literal">@Inherited</code> annotation.
</p></dd></dl></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="signaturePatterns"></a>Signature Patterns</h3></div></div></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="fieldPatterns"></a>Field Patterns</h4></div></div></div><p>A <code class="literal">FieldPattern</code> can optionally specify an annotation-matching
pattern as the first element:</p><pre class="programlisting">
FieldPattern :=
AnnotationPattern? FieldModifiersPattern?
TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern
FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*
FieldModifier := 'public' | 'private' | 'protected' | 'static' |
'transient' | 'final'
DotOrDotDot := '.' | '..'
SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?
</pre><p>
If present, the <code class="literal">AnnotationPattern</code> restricts matches to fields with
annotations that match the pattern. For example:
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">@SensitiveData * *</span></dt><dd><p>
Matches a field of any type and any name, that has an annotation of
type <code class="literal">@SensitiveData</code>
</p></dd><dt><span class="term">@SensitiveData List org.xyz..*.*</span></dt><dd><p>
Matches a member field of a type in a package with prefix <code class="literal">org.xzy</code>,
where the field is of type <code class="literal">List</code>, and has an annotation of type
<code class="literal">@SensitiveData</code>
</p></dd><dt><span class="term">(@SensitiveData *) org.xyz..*.*</span></dt><dd><p>
Matches a member field of a type in a package with prefix <code class="literal">org.xzy</code>,
where the field is of a type which has a <code class="literal">@SensitiveData</code> annotation.
</p></dd><dt><span class="term">@Foo (@Goo *) (@Hoo *).*</span></dt><dd><p>
Matches a field with an annotation <code class="literal">@Foo</code>, of a type with an
annotation <code class="literal">@Goo</code>, declared in a type with annotation
<code class="literal">@Hoo</code>.
</p></dd><dt><span class="term">@Persisted @Classified * *</span></dt><dd><p>
Matches a field with an annotation <code class="literal">@Persisted</code> and
an annotation <code class="literal">@Classified</code>.
</p></dd></dl></div></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="methodPatterns"></a>Method and Constructor Patterns</h4></div></div></div><p>A <code class="literal">MethodPattern</code> can optionally specify an annotation-matching
pattern as the first element.</p><pre class="programlisting">
MethodPattern :=
AnnotationPattern? MethodModifiersPattern? TypePattern
(TypePattern DotOrDotDot)? SimpleNamePattern
'(' FormalsPattern ')'ThrowsPattern?
MethodModifiersPattern := '!'? MethodModifier MethodModifiersPattern*
MethodModifier := 'public' | 'private' | 'protected' | 'static' |
'synchronized' | 'final'
FormalsPattern := '..' (',' FormalsPatternAfterDotDot)* |
OptionalParensTypePattern (',' FormalsPattern)* |
TypePattern '...'
FormalsPatternAfterDotDot :=
OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* |
TypePattern '...'
ThrowsPattern := 'throws' TypePatternList
TypePatternList := TypePattern (',' TypePattern)*
</pre><p>A <code class="literal">ConstructorPattern</code> has the form</p><pre class="programlisting">
ConstructorPattern :=
AnnotationPattern? ConstructorModifiersPattern?
(TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
ThrowsPattern?
ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*
ConstructorModifier := 'public' | 'private' | 'protected'
</pre><p>
The optional <code class="literal">AnnotationPattern</code> at the beginning of a
method or constructor pattern restricts matches to methods/constructors with
annotations that match the pattern. For example:
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">@Oneway * *(..)</span></dt><dd><p>
Matches a method with any return type and any name, that has an annotation of
type <code class="literal">@Oneway</code>.
</p></dd><dt><span class="term">@Transaction * (@Persistent org.xyz..*).*(..)</span></dt><dd><p>
Matches a method with the <code class="literal">@Transaction</code> annotation,
declared in a type with the <code class="literal">@Persistent</code> annotation, and
in a package beginning with the <code class="literal">org.xyz</code> prefix.
</p></dd><dt><span class="term">* *.*(@Immutable *,..)</span></dt><dd><p>
Matches any method taking at least one parameter, where the parameter
type has an annotation <code class="literal">@Immutable</code>.
</p></dd></dl></div></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="example-pointcuts"></a>Example Pointcuts</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">within(@Secure *)</span></dt><dd><p>
Matches any join point where the code executing is declared in a
type with an <code class="literal">@Secure</code>
annotation. The format of the <code class="literal">within</code> pointcut designator
in AspectJ 5 is <code class="literal">'within' '(' OptionalParensTypePattern ')'</code>.
</p></dd><dt><span class="term">staticinitialization(@Persistent *)</span></dt><dd><p>
Matches the staticinitialization join point of any type with the
<code class="literal">@Persistent</code> annotation. The format of the
<code class="literal">staticinitialization</code> pointcut designator
in AspectJ 5 is <code class="literal">'staticinitialization' '(' OptionalParensTypePattern ')'</code>.
</p></dd><dt><span class="term">call(@Oneway * *(..))</span></dt><dd><p>
Matches a call to a method with a <code class="literal">@Oneway</code> annotation.
</p></dd><dt><span class="term">execution(public (@Immutable *) org.xyz..*.*(..))</span></dt><dd><p>
The execution of any public method in a package with prefix
<code class="literal">org.xyz</code>, where the method returns an
immutable result.
</p></dd><dt><span class="term">set(@Cachable * *)</span></dt><dd><p>
Matches the set of any cachable field.
</p></dd><dt><span class="term">handler(!@Catastrophic *)</span></dt><dd><p>
Matches the handler join point for the handling of any exception that is
not <code class="literal">Catastrophic</code>. The format of the <code class="literal">handler</code>
pointcut designator in AspectJ 5 is <code class="literal">'handler' '(' OptionalParensTypePattern ')'</code>.
</p></dd></dl></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="runtime-type-matching-and-context-exposure"></a>Runtime type matching and context exposure</h3></div></div></div><p>AspectJ 5 supports a set of "@" pointcut designators which
can be used both to match based on the presence of an annotation at
runtime, and to expose the annotation value as context in a pointcut or
advice definition. These designators are <code class="literal">@args, @this, @target,
@within, @withincode</code>, and <code class="literal">@annotation</code>
</p><p>It is a compilation error to attempt to match on an annotation type
that does not have runtime retention using <code class="literal">@this, @target</code>
or <code class="literal">@args</code>. It is a compilation error to attempt to use
any of these designators to expose an annotation value that does not
have runtime retention.</p><p>
The <code class="literal">this()</code>, <code class="literal">target()</code>, and
<code class="literal">args()</code> pointcut designators allow matching based
on the runtime type of an object, as opposed to the statically
declared type. In AspectJ 5, these designators are supplemented
with three new designators : <code class="literal">@this()</code> (read, "this
annotation"), <code class="literal">@target()</code>, and <code class="literal">@args()</code>.
</p><p>
Like their counterparts, these pointcut designators can be used
both for join point matching, and to expose context. The format of
these new designators is:
</p><pre class="programlisting">
AtThis := '@this' '(' AnnotationOrIdentifer ')'
AtTarget := '@target' '(' AnnotationOrIdentifier ')'
AnnotationOrIdentifier := FullyQualifiedName | Identifier
AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'
AnnotationsOrIdentifiersPattern :=
'..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
'*' (',' AnnotationsOrIdentifiersPattern)*
AnnotationsOrIdentifiersPatternAfterDotDot :=
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
'*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*
</pre><p>
The forms of <code class="literal">@this()</code> and <code class="literal">@target()</code> that
take a single annotation name are analogous to their counterparts that take
a single type name. They match at join points where the object bound to
<code class="literal">this</code> (or <code class="literal">target</code>, respectively) has an
annotation of the specified type. For example:
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">@this(Foo)</span></dt><dd><p>
Matches any join point where the object currently bound to 'this'
has an annotation of type <code class="literal">Foo</code>.
</p></dd><dt><span class="term">call(* *(..)) && @target(Classified)</span></dt><dd><p>
Matches a call to any object where the target of the call has
a <code class="literal">@Classified</code> annotation.
</p></dd></dl></div><p>
Annotations can be exposed as context in the body of advice by
using the forms of <code class="literal">@this(), @target()</code> and
<code class="literal">@args()</code> that use bound variables in the place
of annotation names. For example:
</p><pre class="programlisting">
pointcut callToClassifiedObject(Classified classificationInfo) :
call(* *(..)) && @target(classificationInfo);
pointcut txRequiredMethod(Tx transactionAnnotation) :
execution(* *(..)) && @this(transactionAnnotation)
&& if(transactionAnnotation.policy() == TxPolicy.REQUIRED);
</pre><p>
The <code class="literal">@args</code> pointcut designator behaves as its <code class="literal">args</code>
counterpart, matching join points based on number and position of arguments, and
supporting the <code class="literal">*</code> wildcard and at most one <code class="literal">..</code>
wildcard. An annotation at a given position in an <code class="literal">@args</code> expression
indicates that the runtime type of the argument in that position at a join point must
have an annotation of the indicated type. For example:
</p><pre class="programlisting">
/**
* matches any join point with at least one argument, and where the
* type of the first argument has the @Classified annotation
*/
pointcut classifiedArgument() : @args(Classified,..);
/**
* matches any join point with three arguments, where the third
* argument has an annotation of type @Untrusted.
*/
pointcut untrustedData(Untrusted untrustedDataSource) :
@args(*,*,untrustedDataSource);
</pre><p>In addition to accessing annotation information at runtime through context binding,
access to <code class="literal">AnnotatedElement</code> information is also available
reflectively with the body of advice through the <code class="literal">thisJoinPoint</code>,
<code class="literal">thisJoinPointStaticPart</code>, and
<code class="literal">thisEnclosingJoinPointStaticPart</code> variables. To access
annotations on the arguments, or object bound to this or target at a join
point you can use the following code fragments:</p><pre class="programlisting">
Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations();
Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations();
Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations();
</pre><p>
The <code class="literal">@within</code> and <code class="literal">@withincode</code> pointcut designators
match any join point where the executing code is defined within a type (<code class="literal">@within</code>),
or a method/constructor (<code class="literal">@withincode</code>) that has an annotation of the specified
type. The form of these designators is:
</p><pre class="programlisting">
AtWithin := '@within' '(' AnnotationOrIdentifier ')'
AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'
</pre><p>Some examples of using these designators follow:</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">@within(Foo)</span></dt><dd><p>
Matches any join point where the executing code is defined
within a type which has an annotation of type <code class="literal">Foo</code>.
</p></dd><dt><span class="term">pointcut insideCriticalMethod(Critical c) :
@withincode(c);</span></dt><dd><p>
Matches any join point where the executing code is defined
in a method or constructor which has an annotation of type <code class="literal">@Critical</code>,
and exposes the value of the annotation in the parameter
<code class="literal">c</code>.
</p></dd></dl></div><p>The <code class="literal">@annotation</code> pointcut designator matches any
join point where the <span class="emphasis"><em>subject</em></span> of the join point has
an annotation of the given type. Like the other @pcds, it can also be
used for context exposure.</p><pre class="programlisting">
AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'
</pre><p>The subject of a join point is defined in the table in chapter one of
this guide.</p><p>
Access to annotation information on members at a matched join point is also available
through the <code class="literal">getSignature</code> method of the <code class="literal">JoinPoint</code>
and <code class="literal">JoinPoint.StaticPart</code> interfaces. The <code class="literal">Signature</code>
interfaces are extended with additional operations that provide access to the
<code class="literal">java.lang.reflect</code> <code class="literal">Method, Field</code> and
<code class="literal">Constructor</code> objects on which annnotations can be queried. The following fragment
illustrates an example use of this interface to access annotation information.
</p><pre class="programlisting">
Signature sig = thisJoinPointStaticPart.getSignature();
AnnotatedElement declaringTypeAnnotationInfo = sig.getDeclaringType();
if (sig instanceof MethodSignature) {
// this must be a call or execution join point
Method method = ((MethodSignature)sig).getMethod();
}
</pre><p>
<span class="emphasis"><em>Note again that it would be nicer to add the method getAnnotationInfo
directly to MemberSignature, but this would once more couple the runtime library
to Java 5.</em></span>
</p><p>
The <code class="literal">@this,@target</code> and <code class="literal">@args</code>
pointcut designators can only be used to match against annotations
that have runtime retention. The <code class="literal">@within, @withincode</code>
and <code class="literal">@annotation</code> pointcut designators can only be used
to match against annotations that have at least class-file retention, and
if used in the binding form the annotation must have runtime retention.
</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="package-and-parameter-annotations"></a>Package and Parameter Annotations</h3></div></div></div><p>
<span class="emphasis"><em>Matching on package annotations is not supported in AspectJ. Support for
this capability may be considered in a future release.</em></span>
</p><p>
Parameter annotation matching is being added in AspectJ1.6.
Initially only matching is supported but binding will be
implemented at some point. Whether the annotation specified in a pointcut should be
considered to be an annotation on the parameter type or an annotation on the parameter
itself is determined through the use of parentheses around the parameter type.
Consider the following:
</p><pre class="programlisting">
@SomeAnnotation
class AnnotatedType {}
class C {
public void foo(AnnotatedType a) {}
public void goo(@SomeAnnotation String s) {}
}
</pre><p>
The method foo has a parameter of an annotated type, and can be matched by this pointcut:
</p><pre class="programlisting">
pointcut p(): execution(* *(@SomeAnnotation *));
</pre><p>
When there is a single annotation specified like this, it is considered to be part of the type
pattern in the match against the parameter: 'a parameter of any type that has the annotation @SomeAnnotation'.
</p><p>
To match the parameter annotation case, the method goo, this is the pointcut:
</p><pre class="programlisting">
pointcut p(): execution(* *(@SomeAnnotation (*)));
</pre><p>
The use of parentheses around the wildcard is effectively indicating that the annotation should be considered
separately to the type pattern for the parameter type: 'a parameter of any type that has a parameter annotation of
@SomeAnnotation'.
</p><p>
To match when there is a parameter annotation and an annotation on the type as well:
</p><pre class="programlisting">
pointcut p(): execution(* *(@SomeAnnotation (@SomeOtherAnnotation *)));
</pre><p>
The parentheses are grouping @SomeOtherAnnotation with the * to form the type pattern for the parameter, then
the type @SomeAnnotation will be treated as a parameter annotation pattern.
</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="annotation-inheritance-and-pointcut-matching"></a>Annotation Inheritance and pointcut matching</h3></div></div></div><p>
According to the Java 5 specification, non-type annotations are not
inherited, and annotations on types are only inherited if they have the
<code class="literal">@Inherited</code> meta-annotation.
Given the following program:
</p><pre class="programlisting">
class C1 {
@SomeAnnotation
public void aMethod() {...}
}
class C2 extends C1 {
public void aMethod() {...}
}
class Main {
public static void main(String[] args) {
C1 c1 = new C1();
C2 c2 = new C2();
c1.aMethod();
c2.aMethod();
}
}
aspect X {
pointcut annotatedC2MethodCall() :
call(@SomeAnnotation * C2.aMethod());
pointcut annotatedMethodCall() :
call(@SomeAnnotation * aMethod());
}
</pre><p>
The pointcut <code class="literal">annotatedC2MethodCall</code> will not match anything
since the definition of <code class="literal">aMethod</code> in <code class="literal">C2</code>
does not have the annotation.
</p><p>
The pointcut <code class="literal">annotatedMethodCall</code> matches
<code class="literal">c1.aMethod()</code> but not <code class="literal">c2.aMethod()</code>. The call
to <code class="literal">c2.aMethod</code> is not matched because join point matching for
modifiers (the visibility modifiers, annotations, and throws clause) is based on
the subject of the join point (the method actually being called).
</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="matchingOnAnnotationValues"></a>Matching based on annotation values</h3></div></div></div><p>
The <code class="literal">if</code> pointcut designator can be used to write pointcuts
that match based on the values annotation members. For example:
</p><pre class="programlisting">
pointcut txRequiredMethod(Tx transactionAnnotation) :
execution(* *(..)) && @this(transactionAnnotation)
&& if(transactionAnnotation.policy() == TxPolicy.REQUIRED);
</pre></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="annotations-decp"></a>Using Annotations with declare statements</h2></div></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="declare-error-and-declare-warning"></a>Declare error and declare warning</h3></div></div></div><p>
Since pointcut expressions in AspectJ 5 support join point matching based
on annotations, this facility can be exploited when writing
<code class="literal">declare warning</code> and <code class="literal">declare error</code>
statements. For example:
</p><pre class="programlisting">
declare warning : withincode(@PerformanceCritical * *(..)) &&
call(@ExpensiveOperation * *(..))
: "Expensive operation called from within performance critical section";
</pre><pre class="programlisting">
declare error : call(* org.xyz.model.*.*(..)) &&
!@within(Trusted)
: "Untrusted code should not call the model classes directly";
</pre></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="declare-parents"></a>declare parents</h3></div></div></div><p>
The general form of a <code class="literal">declare parents</code> statement is:
</p><pre class="programlisting">
declare parents : TypePattern extends Type;
declare parents : TypePattern implements TypeList;
</pre><p>
Since AspectJ 5 supports annotations as part of a type pattern
specification, it is now possible to match types based on the presence
of annotations <span class="emphasis"><em>with either class-file or runtime retention</em></span>.
For example:
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">declare parents : (@Secured *) implements SecuredObject;</span></dt><dd><p>
All types with the <code class="literal">@Secured</code> annotation
implement the <code class="literal">SecuredObject</code> inteface.
</p></dd><dt><span class="term">declare parents : (@Secured BankAccount+) implements SecuredObject;</span></dt><dd><p>
The subset of types drawn from the <code class="literal">BankAccount</code> type and any subtype of
<code class="literal">BankAccount</code>, where the
<code class="literal">@Secured</code> annotation is present, implement the
<code class="literal">SecuredObject</code> interface.
</p></dd></dl></div><p>An annotation type may not be used as the target of a declare parents
statement. If an annotation type is named explicitly as the target of a
declare parents statement, a compilation error will result. If an annotation
type is matched by a non-explicit type pattern used in a declare parents
statement it will be ignored (and an XLint warning issued).</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="declare-precedence"></a>declare precedence</h3></div></div></div><p>
The general form of a declare precedence statement is:
</p><pre class="programlisting">
declare precedence : TypePatList;
</pre><p>
AspectJ 5 allows the type patterns in the list to include annotation information
as part of the pattern specification. For example:
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">declare precedence : (@Security *),*;</span></dt><dd><p>
All aspects with the <code class="literal">@Security</code> annotation
take precedence over any other aspects in the system. (Or, more
informally, all security-related aspects take precedence).
</p></dd></dl></div></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="annotations-declare"></a>Declare Annotation</h2></div></div></div><p>AspectJ 5 supports a new kind of declare statement, <code class="literal">declare annotation</code>.
This takes different forms according to the recipient of the annotation:
<code class="literal">declare @type</code> for types, <code class="literal">declare @method</code> for methods,
<code class="literal">declare @constructor</code> for constructors, and <code class="literal">declare @field</code>
for fields. <code class="literal">declare @package</code> may be supported in a future release.
</p><p>The general form is:</p><pre class="programlisting">
declare @<kind> : ElementPattern : Annotation ;
</pre><p>Where annotation is a regular annotation expression as defined in the Java 5 language. If the annotation has
the <code class="literal">@Target</code> meta-annotation, then the elements matched by <code class="literal">ElementPattern</code>
must be of the kind specified by the <code class="literal">@Target</code> annotation.</p><p><code class="literal">ElementPattern</code> is defined as follows:</p><pre class="programlisting">
ElementPattern := TypePattern |
MethodPattern |
ConstructorPattern |
FieldPattern
</pre><p>The following examples illustrate the use of <code class="literal">declare annotation</code>.</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">declare @type : org.xyz.model..* : @BusinessDomain ;</span></dt><dd><p>
All types defined in a package with the prefix <code class="literal">org.xyz.model</code>
have the <code class="literal">@BusinessDomain</code> annotation.
</p></dd><dt><span class="term">declare @method : public * BankAccount+.*(..) : @Secured(role="supervisor")</span></dt><dd><p>
All public methods in <code class="literal">BankAccount</code> and its subtypes have the
annotation <code class="literal">@Secured(role="supervisor")</code>.
</p></dd><dt><span class="term">declare @constructor : BankAccount+.new(..) : @Secured(role="supervisor")</span></dt><dd><p>
All constructors in <code class="literal">BankAccount</code> and its subtypes have the
annotation <code class="literal">@Secured(role="supervisor")</code>.
</p></dd><dt><span class="term">declare @field : * DAO+.* : @Persisted;</span></dt><dd><p>
All fields defined in <code class="literal">DAO</code> or its subtypes have the
<code class="literal">@Persisted</code> annotation.
</p></dd></dl></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="annotations-itds"></a>Inter-type Declarations</h2></div></div></div><p>An annotation type may not be the target of an inter-type declaration.</p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="generics"></a>Chapter 3. Generics</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="sect1"><a href="#generics-inJava5">Generics in Java 5</a></span></dt><dd><dl><dt><span class="sect2"><a href="#declaring-generic-types">Declaring Generic Types</a></span></dt><dt><span class="sect2"><a href="#using-generic-and-parameterized-types">Using Generic and Parameterized Types</a></span></dt><dt><span class="sect2"><a href="#subtypes-supertypes-and-assignability">Subtypes, Supertypes, and Assignability</a></span></dt><dt><span class="sect2"><a href="#generic-methods-and-constructors">Generic Methods and Constructors</a></span></dt><dt><span class="sect2"><a href="#erasure">Erasure</a></span></dt></dl></dd><dt><span class="sect1"><a href="#generics-inAspectJ5">Generics in AspectJ 5</a></span></dt><dd><dl><dt><span class="sect2"><a href="#matching-generic-and-parameterized-types-in-pointcut-expressions">Matching generic and parameterized types in pointcut expressions</a></span></dt><dt><span class="sect2"><a href="#inter-type-declarations">Inter-type Declarations</a></span></dt><dt><span class="sect2"><a href="#declare-parents">Declare Parents</a></span></dt><dt><span class="sect2"><a href="#declare-soft">Declare Soft</a></span></dt><dt><span class="sect2"><a href="#generic-aspects">Generic Aspects</a></span></dt></dl></dd></dl></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="generics-inJava5"></a>Generics in Java 5</h2></div></div></div><p>
This section provides the essential information about generics in
Java 5 needed to understand how generics are treated in AspectJ 5.
For a full introduction to generics in Java, please see the
documentation for the Java 5 SDK.
</p><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="declaring-generic-types"></a>Declaring Generic Types</h3></div></div></div><p>
A generic type is declared with one or more type parameters following the type name.
By convention formal type parameters are named using a single letter, though this is not required.
A simple generic list type
(that can contain elements of any type <code class="literal">E</code>) could be declared:
</p><pre class="programlisting">
interface List<E> {
Iterator<E> iterator();
void add(E anItem);
E remove(E anItem);
}
</pre><p>
It is important to understand that unlike template mechanisms there will only be one type, and one class file, corresponding to
the <code class="literal">List</code> interface, regardless of how many different instantiations of the <code class="literal">List</code> interface a program
has (each potentially providing a different value for the type parameter <code class="literal">E</code>). A consequence of this
is that you cannot refer to the type parameters of a type declaration in a static method or initializer, or in the declaration or
initializer of a static variable.
</p><p>
A <span class="emphasis"><em>parameterized type</em></span>
is an invocation of a generic type with concrete values supplied for
all of its type parameters (for example, <code class="literal">List<String></code> or <code class="literal">List<Food></code>).
</p><p>A generic type may be declared with multiple type parameters. In addition to simple type parameter names, type
parameter declarations can also constrain the set of types allowed by using the <code class="literal">extends</code>
keyword. Some examples follow:</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">class Foo<T> {...}</span></dt><dd><p>A class <code class="literal">Foo</code> with one type parameter, <code class="literal">T</code>.
</p></dd><dt><span class="term">class Foo<T,S> {...}</span></dt><dd><p>A class <code class="literal">Foo</code> with two type parameters, <code class="literal">T</code> and <code class="literal">S</code>.
</p></dd><dt><span class="term">class Foo<T extends Number> {...}</span></dt><dd><p>A class <code class="literal">Foo</code> with one type parameter <code class="literal">T</code>, where <code class="literal">T</code> must be
instantiated as the type <code class="literal">Number</code> or a subtype of <code class="literal">Number</code>.
</p></dd><dt><span class="term">class Foo<T, S extends T> {...}</span></dt><dd><p>A class <code class="literal">Foo</code> with two type parameters, <code class="literal">T</code> and <code class="literal">S</code>. <code class="literal">Foo</code>
must be instantiated with a type <code class="literal">S</code> that is a subtype of the type specified for parameter <code class="literal">T</code>.
</p></dd><dt><span class="term">class Foo<T extends Number & Comparable> {...}</span></dt><dd><p>A class <code class="literal">Foo</code> with one type parameter, <code class="literal">T</code>. <code class="literal">Foo</code>
must be instantiated with a type that is a subtype of <code class="literal">Number</code> and that implements <code class="literal">Comparable</code>.
</p></dd></dl></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="using-generic-and-parameterized-types"></a>Using Generic and Parameterized Types</h3></div></div></div><p>You declare a variable (or a method/constructor argument) of a parameterized type by specifying a concrete type specfication for each type parameter in
the generic type. The following example declares a list of strings and a list of numbers:</p><pre class="programlisting">
List<String> strings;
List<Number> numbers;
</pre><p>It is also possible to declare a variable of a generic type without specifying any values for the type
parameters (a <span class="emphasis"><em>raw</em></span> type). For example, <code class="literal">List strings</code>.
In this case, unchecked warnings may be issued by the compiler
when the referenced object is passed as a parameter to a method expecting a parameterized type such as a
<code class="literal">List<String></code>. New code written in the Java 5 language would not be expected to use
raw types.</p><p>Parameterized types are instantiated by specifying type parameter values in the constructor call expression as in
the following examples:</p><pre class="programlisting">
List<String> strings = new MyListImpl<String>();
List<Number> numbers = new MyListImpl<Number>();
</pre><p>
When declaring parameterized types, the <code class="literal">?</code> wildcard may be used, which stands for "some type".
The <code class="literal">extends</code> and <code class="literal">super</code> keywords may be used in conjunction with the wildcard
to provide upper and lower bounds on the types that may satisfy the type constraints. For example:
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">List<?></span></dt><dd><p>A list containing elements of some type, the type of the elements in the list is unknown.
</p></dd><dt><span class="term">List<? extends Number></span></dt><dd><p>A list containing elements of some type that extends Number, the exact type of the elements in the list is unknown.
</p></dd><dt><span class="term">List<? super Double></span></dt><dd><p>A list containing elements of some type that is a super-type of Double, the exact type of the elements in the list is unknown.
</p></dd></dl></div><p>
A generic type may be extended as any other type. Given a generic type <code class="literal">Foo<T></code> then
a subtype <code class="literal">Goo</code> may be declared in one of the following ways:
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">class Goo extends Foo</span></dt><dd><p>Here <code class="literal">Foo</code> is used as a raw type, and the appropriate warning messages will be
issued by the compiler on attempting to invoke methods in <code class="literal">Foo</code>.
</p></dd><dt><span class="term">class Goo<E> extends Foo</span></dt><dd><p><code class="literal">Goo</code> is a generic type, but the super-type <code class="literal">Foo</code> is used as a raw
type and the appropriate warning messages will be
issued by the compiler on attempting to invoke methods defined by <code class="literal">Foo</code>.
</p></dd><dt><span class="term">class Goo<E> extends Foo<E></span></dt><dd><p>This is the most usual form. <code class="literal">Goo</code> is a generic type with one parameter that extends
the generic type <code class="literal">Foo</code> with that same parameter. So <code class="literal">Goo<String<</code> is
a subclass of <code class="literal">Foo<String></code>.
</p></dd><dt><span class="term">class Goo<E,F> extends Foo<E></span></dt><dd><p><code class="literal">Goo</code> is a generic type with two parameters that extends
the generic type <code class="literal">Foo</code> with the first type parameter of <code class="literal">Goo</code> being used
to parameterize <code class="literal">Foo</code>. So <code class="literal">Goo<String,Integer<</code> is
a subclass of <code class="literal">Foo<String></code>.
</p></dd><dt><span class="term">class Goo extends Foo<String></span></dt><dd><p><code class="literal">Goo</code> is a type that extends
the parameterized type <code class="literal">Foo<String></code>.
</p></dd></dl></div><p>A generic type may implement one or more generic interfaces, following the type binding
rules given above. A type may also implement one or more parameterized interfaces (for example,
<code class="literal">class X implements List<String></code>, however a type may not at the same time
be a subtype of two interface types which are different parameterizations of the same interface.</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="subtypes-supertypes-and-assignability"></a>Subtypes, Supertypes, and Assignability</h3></div></div></div><p>
The supertype of a generic type <code class="literal">C</code> is the type given in the extends clause of
<code class="literal">C</code>, or <code class="literal">Object</code> if no extends clause is present. Given the type declaration
</p><pre class="programlisting">
public interface List<E> extends Collection<E> {... }
</pre><p>
then the supertype of <code class="literal">List<E></code> is <code class="literal">Collection<E></code>.
</p><p>
The supertype of a parameterized type <code class="literal">P</code> is the type given in the extends clause of
<code class="literal">P</code>, or <code class="literal">Object</code> if no extends clause is present. Any type parameters in
the supertype are substituted in accordance with the parameterization of <code class="literal">P</code>. An example
will make this much clearer: Given the type <code class="literal">List<Double></code> and the definition of
the <code class="literal">List</code> given above, the direct supertype is
<code class="literal">Collection<Double></code>. <code class="literal">List<Double></code> is <span class="emphasis"><em>not</em></span>
considered to be a subtype of <code class="literal">List<Number></code>.
</p><p>
An instance of a parameterized type <code class="literal">P<T1,T2,...Tn></code>may be assigned to a variable of
the same type or a supertype
without casting. In addition it may be assigned to a variable <code class="literal">R<S1,S2,...Sm></code> where
<code class="literal">R</code> is a supertype of <code class="literal">P</code> (the supertype relationship is reflexive),
<code class="literal">m <= n</code>, and for all type parameters <code class="literal">S1..m</code>, <code class="literal">Tm</code> equals
<code class="literal">Sm</code> <span class="emphasis"><em>or</em></span> <code class="literal">Sm</code> is a wildcard type specification and
<code class="literal">Tm</code> falls within the bounds of the wildcard. For example, <code class="literal">List<String></code>
can be assigned to a variable of type <code class="literal">Collection<?></code>, and <code class="literal">List<Double></code>
can be assigned to a variable of type <code class="literal">List<? extends Number></code>.
</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="generic-methods-and-constructors"></a>Generic Methods and Constructors</h3></div></div></div><p>
A static method may be declared with one or more type parameters as in the following declaration:
</p><pre class="programlisting">
static <T> T first(List<T> ts) { ... }
</pre><p>
Such a definition can appear in any type, the type parameter <code class="literal">T</code> does not need to
be declared as a type parameter of the enclosing type.
</p><p>
Non-static methods may also be declared with one or more type parameters in a similar fashion:
</p><pre class="programlisting">
<T extends Number> T max(T t1, T t2) { ... }
</pre><p>The same technique can be used to declare a generic constructor.</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="erasure"></a>Erasure</h3></div></div></div><p>Generics in Java are implemented using a technique called <span class="emphasis"><em>erasure</em></span>. All
type parameter information is erased from the run-time type system. Asking an object of a parameterized
type for its class will return the class object for the raw type (eg. <code class="literal">List</code> for an object
declared to be of type <code class="literal">List<String></code>. A consequence of this is that you cannot at
runtime ask if an object is an <code class="literal">instanceof</code> a parameterized type.</p></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="generics-inAspectJ5"></a>Generics in AspectJ 5</h2></div></div></div><p>
AspectJ 5 provides full support for all of the Java 5 language features, including generics. Any legal Java 5 program is a
legal AspectJ 5 progam. In addition, AspectJ 5 provides support for generic and parameterized types in pointcuts, inter-type
declarations, and declare statements. Parameterized types may freely be used within aspect members, and support is
also provided for generic <span class="emphasis"><em>abstract</em></span> aspects.
</p><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="matching-generic-and-parameterized-types-in-pointcut-expressions"></a>Matching generic and parameterized types in pointcut expressions</h3></div></div></div><p>
The simplest way to work with generic and parameterized types in pointcut expressions and type patterns
is simply to use the raw type name. For example, the type pattern <code class="literal">List</code> will match
the generic type <code class="literal">List<E></code> and any parameterization of that type
(<code class="literal">List<String>, List<?>, List<? extends Number></code> and so on. This
ensures that pointcuts written in existing code that is not generics-aware will continue to work as
expected in AspectJ 5. It is also the recommended way to match against generic and parameterized types
in AspectJ 5 unless you explicitly wish to narrow matches to certain parameterizations of a generic type.
</p><p>Generic methods and constructors, and members defined in generic types, may use type variables
as part of their signature. For example:</p><pre class="programlisting">
public class Utils {
/** static generic method */
static <T> T first(List<T> ts) { ... }
/** instance generic method */
<T extends Number> T max(T t1, T t2) { ... }
}
public class G<T> {
// field with parameterized type
T myData;
// method with parameterized return type
public List<T> getAllDataItems() {...}
}
</pre><p>
AspectJ 5 does not allow the use of type variables in pointcut expressions and type patterns. Instead, members that
use type parameters as part of their signature are matched by their <span class="emphasis"><em>erasure</em></span>. Java 5 defines the
rules for determing the erasure of a type as follows.
</p><p>Let <code class="literal">|T|</code> represent the erasure of some type <code class="literal">T</code>. Then:</p><table border="0" summary="Simple list" class="simplelist"><tr><td>The erasure of a parameterized type <code class="literal">T<T1,...,Tn></code> is <code class="literal">|T|</code>.
For example, the erasure of <code class="literal">List<String></code> is <code class="literal">List</code>.</td></tr><tr><td>The erasure of a nested type <code class="literal">T.C</code> is <code class="literal">|T|.C</code>. For example,
the erasure of the nested type <code class="literal">Foo<T>.Bar</code> is <code class="literal">Foo.Bar</code>.</td></tr><tr><td>The erasure of an array type <code class="literal">T[]</code> is <code class="literal">|T|[]</code>. For example,
the erasure of <code class="literal">List<String>[]</code> is <code class="literal">List[]</code>.</td></tr><tr><td>The erasure of a type variable is its leftmost bound. For example, the erasure of a
type variable <code class="literal">P</code> is <code class="literal">Object</code>, and the erasure of a type
variable <code class="literal">N extends Number</code> is <code class="literal">Number</code>.</td></tr><tr><td>The erasure of every other type is the type itself</td></tr></table><p>Applying these rules to the earlier examples, we find that the methods defined in <code class="literal">Utils</code>
can be matched by a signature pattern matching <code class="literal">static Object Utils.first(List)</code> and
<code class="literal">Number Utils.max(Number, Number)</code> respectively. The members of the generic type
<code class="literal">G</code> can be matched by a signature pattern matching <code class="literal">Object G.myData</code> and
<code class="literal">public List G.getAllDataItems()</code> respectively.</p><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp64368608"></a>Restricting matching using parameterized types</h4></div></div></div><p>Pointcut matching can be further restricted to match only given parameterizations of parameter types (methods and constructors), return
types (methods) and field types (fields). This is achieved by specifying a parameterized type pattern at the appropriate point
in the signature pattern. For example, given the class <code class="literal">Foo</code>:</p><pre class="programlisting">
public class Foo {
List<String> myStrings;
List<Float> myFloats;
public List<String> getStrings() { return myStrings; }
public List<Float> getFloats() { return myFloats; }
public void addStrings(List<String> evenMoreStrings) {
myStrings.addAll(evenMoreStrings);
}
}
</pre><p>Then a <code class="literal">get</code> join point for the field <code class="literal">myStrings</code> can be matched by the
pointcut <code class="literal">get(List Foo.myStrings)</code> and by the pointcut <code class="literal">get(List<String> Foo.myStrings)</code>,
but <span class="emphasis"><em>not</em></span> by the pointcut <code class="literal">get(List<Number> *)</code>.</p><p>A <code class="literal">get</code> join point for the field <code class="literal">myFloats</code> can be matched by the
pointcut <code class="literal">get(List Foo.myFloats)</code>, the pointcut <code class="literal">get(List<Float> *)</code>,
and the pointcut <code class="literal">get(List<Number+> *)</code>. This last example shows how AspectJ type
patterns can be used to match type parameters types just like any other type. The pointcut
<code class="literal">get(List<Double> *)</code> does <span class="emphasis"><em>not</em></span> match.</p><p>The execution of the methods <code class="literal">getStrings</code> and <code class="literal">getFloats</code> can be
matched by the pointcut expression <code class="literal">execution(List get*(..))</code>, and the pointcut
expression <code class="literal">execution(List<*> get*(..))</code>, but only <code class="literal">getStrings</code>
is matched by <code class="literal">execution(List<String> get*(..))</code> and only <code class="literal">getFloats</code>
is matched by <code class="literal">execution(List<Number+> get*(..))</code></p><p>A call to the method <code class="literal">addStrings</code> can be matched by the pointcut expression
<code class="literal">call(* addStrings(List))</code> and by the expression <code class="literal">call(* addStrings(List<String>))</code>,
but <span class="emphasis"><em>not</em></span> by the expression <code class="literal">call(* addStrings(List<Number>))</code>.
</p><p>Remember that any type variable reference in a generic member is
<span class="emphasis"><em>always</em></span> matched by its erasure. Thus given the following
example:</p><pre class="programlisting">
class G<T> {
List<T> foo(List<String> ls) { return null; }
}
</pre><p>The execution of <code class="literal">foo</code> can be matched by
<code class="literal">execution(List foo(List))</code>,
<code class="literal">execution(List foo(List<String>>))</code>, and
<code class="literal">execution(* foo(List<String<))</code>but
<span class="emphasis"><em>not</em></span> by <code class="literal">execution(List<Object> foo(List<String>>)</code>
since the erasure of <code class="literal">List<T></code> is <code class="literal">List</code>
and not <code class="literal">List<Object></code>.
</p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp64397456"></a>Generic wildcards and signature matching</h4></div></div></div><p>
When it comes to signature matching, a type parameterized using a generic wildcard is a distinct type.
For example, <code class="literal">List<?></code> is a very different type to <code class="literal">List<String></code>,
even though a variable of type <code class="literal">List<String></code> can be assigned to a variable of
type <code class="literal">List<?></code>. Given the methods:
</p><pre class="programlisting">
class C {
public void foo(List<? extends Number> listOfSomeNumberType) {}
public void bar(List<?> listOfSomeType) {}
public void goo(List<Double> listOfDoubles) {}
}
</pre><div class="variablelist"><dl class="variablelist"><dt><span class="term">execution(* C.*(List))</span></dt><dd><p>Matches an execution join point for any of the three methods.
</p></dd><dt><span class="term">execution(* C.*(List<? extends Number>))</span></dt><dd><p>matches only the
execution of <code class="literal">foo</code>, and <span class="emphasis"><em>not</em></span> the execution
of <code class="literal">goo</code> since <code class="literal">List<? extends Number></code> and
<code class="literal">List<Double></code> are distinct types.
</p></dd><dt><span class="term">execution(* C.*(List<?>))</span></dt><dd><p>matches only the execution of <code class="literal">bar</code>.
</p></dd><dt><span class="term">execution(* C.*(List<? extends Object+>))</span></dt><dd><p>matches both the execution of <code class="literal">foo</code> and the execution of <code class="literal">bar</code>
since the upper bound of <code class="literal">List<?></code> is implicitly <code class="literal">Object</code>.
</p></dd></dl></div></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp64415072"></a>Treatment of bridge methods</h4></div></div></div><p>Under certain circumstances a Java 5 compiler is required to create <span class="emphasis"><em>bridge
methods</em></span> that support the compilation of programs using raw types. Consider the types</p><pre class="programlisting">
class Generic<T> {
public T foo(T someObject) {
return someObject;
}
}
class SubGeneric<N extends Number> extends Generic<N> {
public N foo(N someNumber) {
return someNumber;
}
}
</pre><p>The class <code class="literal">SubGeneric</code> extends <code class="literal">Generic</code>
and overrides the method <code class="literal">foo</code>. Since the upper bound of the type variable
<code class="literal">N</code> in <code class="literal">SubGeneric</code> is different to the upper bound of
the type variable <code class="literal">T</code> in <code class="literal">Generic</code>, the method <code class="literal">foo</code>
in <code class="literal">SubGeneric</code> has a different erasure to the method <code class="literal">foo</code>
in <code class="literal">Generic</code>. This is an example of a case where a Java 5 compiler will create
a <span class="emphasis"><em>bridge method</em></span> in <code class="literal">SubGeneric</code>. Although you never see it,
the bridge method will look something like this:</p><pre class="programlisting">
public Object foo(Object arg) {
Number n = (Number) arg; // "bridge" to the signature defined in this type
return foo(n);
}
</pre><p>Bridge methods are synthetic artefacts generated as a result of a particular compilation strategy and
have no execution join points in AspectJ 5. So the pointcut <code class="literal">execution(Object SubGeneric.foo(Object))</code>
does not match anything. (The pointcut <code class="literal">execution(Object Generic.foo(Object))</code> matches the
execution of <code class="literal">foo</code> in both <code class="literal">Generic</code> and <code class="literal">SubGeneric</code> since
both are implementations of <code class="literal">Generic.foo</code>).
</p><p>It <span class="emphasis"><em>is</em></span> possible to <span class="emphasis"><em>call</em></span> a bridge method as the following short
code snippet demonstrates. Such a call <span class="emphasis"><em>does</em></span> result in a call join point for the call to
the method.
</p><pre class="programlisting">
SubGeneric rawType = new SubGeneric();
rawType.foo("hi"); // call to bridge method (will result in a runtime failure in this case)
Object n = new Integer(5);
rawType.foo(n); // call to bridge method that would succeed at runtime
</pre></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp64434448"></a>Runtime type matching with this(), target() and args()</h4></div></div></div><p>The <code class="literal">this()</code>, <code class="literal">target()</code>, and
<code class="literal">args()</code> pointcut expressions all match based on the runtime
type of their arguments. Because Java 5 implements generics using erasure, it is not
possible to ask at runtime whether an object is an instance of a given parameterization of a type
(only whether or not it is an instance of the erasure of that parameterized type). Therefore
AspectJ 5 does not support the use of parameterized types with the <code class="literal">this()</code> and
<code class="literal">target()</code> pointcuts. Parameterized types may however be used in conjunction with
<code class="literal">args()</code>. Consider the following class
</p><pre class="programlisting">
public class C {
public void foo(List<String> listOfStrings) {}
public void bar(List<Double> listOfDoubles) {}
public void goo(List<? extends Number> listOfSomeNumberType) {}
}
</pre><div class="variablelist"><dl class="variablelist"><dt><span class="term">args(List)</span></dt><dd><p>will match an execution or call join point for any of
these methods
</p></dd><dt><span class="term">args(List<String>)</span></dt><dd><p>will match an execution
or call join point for <code class="literal">foo</code>.
</p></dd><dt><span class="term">args(List<Double>)</span></dt><dd><p>matches an execution or call join point for <code class="literal">bar</code>, and <span class="emphasis"><em>may</em></span> match
at an execution or call join point for <code class="literal">goo</code> since it is legitimate to pass an
object of type <code class="literal">List<Double></code> to a method expecting a <code class="literal">List<? extends Number></code>.
</p><p>
In this situation a runtime test would normally be applied to ascertain whether or not the argument
was indeed an instance of the required type. However, in the case of parameterized types such a test is not
possible and therefore AspectJ 5 considers this a match, but issues an <span class="emphasis"><em>unchecked</em></span> warning.
For example, compiling the aspect <code class="literal">A</code> below with the class <code class="literal">C</code> produces the
compilation warning: "unchecked match of List<Double> with List<? extends Number> when argument is
an instance of List at join point method-execution(void C.goo(List<? extends Number>)) [Xlint:uncheckedArgument]";
</p></dd></dl></div><pre class="programlisting">
public aspect A {
before(List<Double> listOfDoubles) : execution(* C.*(..)) && args(listOfDoubles) {
for (Double d : listOfDoubles) {
// do something
}
}
}
</pre><p>Like all Lint messages, the <code class="literal">uncheckedArgument</code> warning can be
configured in severity from the default warning level to error or even ignore if preferred.
In addition, AspectJ 5 offers the annotation <code class="literal">@SuppressAjWarnings</code> which is
the AspectJ equivalent of Java's <code class="literal">@SuppressWarnings</code> annotation. If the
advice is annotated with <code class="literal">@SuppressWarnings</code> then <span class="emphasis"><em>all</em></span>
lint warnings issued during matching of pointcut associated with the advice will be
suppressed. To suppress just an <code class="literal">uncheckedArgument</code> warning, use the
annotation <code class="literal">@SuppressWarnings("uncheckedArgument")</code> as in the following
examples:
</p><pre class="programlisting">
import org.aspectj.lang.annotation.SuppressAjWarnings
public aspect A {
@SuppressAjWarnings // will not see *any* lint warnings for this advice
before(List<Double> listOfDoubles) : execution(* C.*(..)) && args(listOfDoubles) {
for (Double d : listOfDoubles) {
// do something
}
}
@SuppressAjWarnings("uncheckedArgument") // will not see *any* lint warnings for this advice
before(List<Double> listOfDoubles) : execution(* C.*(..)) && args(listOfDoubles) {
for (Double d : listOfDoubles) {
// do something
}
}
}
</pre><p>
The safest way to deal with <code class="literal">uncheckedArgument</code> warnings however is to restrict the pointcut
to match only at those join points where the argument is guaranteed to match. This is achieved by combining
<code class="literal">args</code> with a <code class="literal">call</code> or <code class="literal">execution</code> signature matching
pointcut. In the following example the advice will match the execution of <code class="literal">bar</code> but not
of <code class="literal">goo</code> since the signature of <code class="literal">goo</code> is not matched by the execution pointcut
expression.
</p><pre class="programlisting">
public aspect A {
before(List<Double> listOfDoubles) : execution(* C.*(List<Double>)) && args(listOfDoubles) {
for (Double d : listOfDoubles) {
// do something
}
}
}
</pre><p>Generic wildcards can be used in args type patterns, and matching follows regular Java 5 assignability rules. For
example, <code class="literal">args(List<?>)</code> will match a list argument of any type, and
<code class="literal">args(List<? extends Number>)</code> will match an argument of type
<code class="literal">List<Number>, List<Double>, List<Float></code> and so on. Where a match cannot be
fully statically determined, the compiler will once more issue an <code class="literal">uncheckedArgument</code> warning.
</p><p>Consider the following program:</p><pre class="programlisting">
public class C {
public static void main(String[] args) {
C c = new C();
List<String> ls = new ArrayList<String>();
List<Double> ld = new ArrayList<Double>();
c.foo("hi");
c.foo(ls);
c.foo(ld);
}
public void foo(Object anObject) {}
}
aspect A {
before(List<? extends Number> aListOfSomeNumberType)
: call(* foo(..)) && args(aListOfSomeNumberType) {
// process list...
}
}
</pre><p>From the signature of <code class="literal">foo</code> all we know is that the runtime argument will be an instance of
<code class="literal">Object</code>.Compiling this program gives the unchecked argument warning:
"unchecked match of List<? extends Number> with List when argument is
an instance of List at join point method-execution(void C.foo(Object)) [Xlint:uncheckedArgument]".
The advice will not execute at the call join point for <code class="literal">c.foo("hi")</code> since <code class="literal">String</code>
is not an instance of <code class="literal">List</code>. The advice <span class="emphasis"><em>will</em></span> execute at the call join points
for <code class="literal">c.foo(ls)</code> and <code class="literal">c.foo(ld)</code> since in both cases the argument is an instance of
<code class="literal">List</code>.
</p><p>Combine a wildcard argument type with a signature pattern to avoid unchecked argument matches. In the example
below we use the signature pattern <code class="literal">List<Number+></code> to match a call to any method taking
a <code class="literal">List<Number>, List<Double>, List<Float></code> and so on. In addition the
signature pattern <code class="literal">List<? extends Number+></code> can be used to match a call to a method
declared to take a <code class="literal">List<? extends Number></code>, <code class="literal">List<? extends Double></code>
and so on. Taken together, these restrict matching to only
those join points at which the argument is guaranteed to be an instance of <code class="literal">List<? extends Number></code>.</p><pre class="programlisting">
aspect A {
before(List<? extends Number> aListOfSomeNumberType)
: (call(* foo(List<Number+>)) || call(* foo(List<? extends Number+>)))
&& args(aListOfSomeNumberType) {
// process list...
}
}
</pre></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp64484256"></a>Binding return values in after returning advice</h4></div></div></div><p>
After returning advice can be used to bind the return value from a matched join point. AspectJ 5 supports the use of
a parameterized type in the returning clause, with matching following the same rules as described for args. For
example, the following aspect matches the execution of any method returning a <code class="literal">List</code>, and makes
the returned list available to the body of the advice.
</p><pre class="programlisting">
public aspect A {
pointcut executionOfAnyMethodReturningAList() : execution(List *(..));
after() returning(List<?> listOfSomeType) : executionOfAnyMethodReturningAList() {
for (Object element : listOfSomeType) {
// process element...
}
}
}
</pre><p>The pointcut uses the raw type pattern <code class="literal">List</code>, and hence it
matches methods returning any kind of list (<code class="literal">List<String>, List<Double></code>,
and so on). We've chosen to bind the returned list as the parameterized type
<code class="literal">List<?></code> in the advice since Java's type checking will now ensure
that we only perform safe operations on the list.</p><p>Given the class</p><pre class="programlisting">
public class C {
public List<String> foo(List<String> listOfStrings) {...}
public List<Double> bar(List<Double> listOfDoubles) {...}
public List<? extends Number> goo(List<? extends Number> listOfSomeNumberType) {...}
}
</pre><p>The advice in the aspect below will run after the execution of <code class="literal">bar</code>
and bind the return value. It will also run after the execution of <code class="literal">goo</code> and
bind the return value, but gives an <code class="literal">uncheckedArgument</code> warning during
compilation. It does <span class="emphasis"><em>not</em></span> run after the execution of <code class="literal">foo</code>.
</p><pre class="programlisting">
public aspect Returning {
after() returning(List<Double> listOfDoubles) : execution(* C.*(..)) {
for(Double d : listOfDoubles) {
// process double...
}
}
}
</pre><p>As with <code class="literal">args</code> you can guarantee that after returning advice only
executes on lists <span class="emphasis"><em>statically determinable</em></span> to be of the right
type by specifying a return type pattern in the associated pointcut. The
<code class="literal">@SuppressAjWarnings</code> annotation can also be used if desired.</p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp64498272"></a>Declaring pointcuts inside generic types</h4></div></div></div><p>Pointcuts can be declared in both classes and aspects. A pointcut declared in a generic
type may use the type variables of the type in which it is declared. All references to
a pointcut declared in a generic type from outside of that type must be via a parameterized type reference,
and not a raw type reference.</p><p>Consider the generic type <code class="literal">Generic</code> with a pointcut <code class="literal">foo</code>:
</p><pre class="programlisting">
public class Generic<T> {
/**
* matches the execution of any implementation of a method defined for T
*/
public pointcut foo() : execution(* T.*(..));
}
</pre><p>Such a pointcut must be refered to using a parameterized reference as shown
below.</p><pre class="programlisting">
public aspect A {
// runs before the execution of any implementation of a method defined for MyClass
before() : Generic<MyClass>.foo() {
// ...
}
// runs before the execution of any implementation of a method defined for YourClass
before() : Generic<YourClass>.foo() {
// ...
}
// results in a compilation error - raw type reference
before() : Generic.foo() { }
}
</pre></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="inter-type-declarations"></a>Inter-type Declarations</h3></div></div></div><p>
AspectJ 5 supports the inter-type declaration of generic methods, and of members on
generic types. For generic methods, the syntax is exactly as for a regular method
declaration, with the addition of the target type specification:
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><T extends Number> T Utils.max(T first, T second) {...}</span></dt><dd><p>Declares a generic instance method <code class="literal">max</code> on the class <code class="literal">Util</code>.
The <code class="literal">max</code> method takes two arguments, <code class="literal">first</code> and <code class="literal">second</code> which must
both be of the same type (and that type must be Number or a subtype of Number) and returns an instance
of that type.
</p></dd><dt><span class="term">static <E> E Utils.first(List<E> elements) {...}</span></dt><dd><p>Declares a static generic method <code class="literal">first</code> on the class <code class="literal">Util</code>.
The <code class="literal">first</code> method takes a list of elements of some type, and returns an instance
of that type.
</p></dd><dt><span class="term"><T> Sorter.new(List<T> elements,Comparator<? super T> comparator) {...}</span></dt><dd><p>Declares a constructor on the class <code class="literal">Sorter</code>.
The constructor takes a list of elements of some type, and a comparator that can compare instances
of the element type.
</p></dd></dl></div><p>
A generic type may be the target of an inter-type declaration, used either in its raw form or with
type parameters specified. If type parameters are specified, then the number of type parameters given
must match the number of type parameters in
the generic type declaration. Type parameter <span class="emphasis"><em>names</em></span> do not have to match.
For example, given the generic type <code class="literal">Foo<T,S extends Number></code> then:
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">String Foo.getName() {...}</span></dt><dd><p>Declares a <code class="literal">getName</code> method on behalf of the type <code class="literal">Foo</code>. It is
not possible to refer to the type parameters of Foo in such a declaration.
</p></dd><dt><span class="term">public R Foo<Q, R>.getMagnitude() {...}</span></dt><dd><p>Declares a method <code class="literal">getMagnitude</code> on the generic class <code class="literal">Foo</code>.
The method returns an instance of the type substituted for the second type parameter in an invocation
of <code class="literal">Foo</code> If <code class="literal">Foo</code> is declared as
<code class="literal">Foo<T,N extends Number> {...}</code> then this inter-type declaration is
equivalent to the declaration of a method <code class="literal">public N getMagnitude()</code>
within the body of <code class="literal">Foo</code>.
</p></dd><dt><span class="term">R Foo<Q, R extends Number>.getMagnitude() {...}</span></dt><dd><p>Results in a compilation error since a bounds specification is not allowed in this
form of an inter-type declaration (the bounds are determined from the declaration of the
target type).
</p></dd></dl></div><p>A parameterized type may not be the target of an inter-type declaration. This is because
there is only one type (the generic type) regardless of how many different invocations (parameterizations) of
that generic type are made in a program. Therefore it does not make sense to try and declare a member
on behalf of (say) <code class="literal">Bar<String></code>, you can only declare members on the generic
type <code class="literal">Bar<T></code>.
</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="declare-parents"></a>Declare Parents</h3></div></div></div><p>Both generic and parameterized types can be used as the parent type in a <code class="literal">declare parents</code>
statement (as long as the resulting type hierarchy would be well-formed in accordance with Java's sub-typing
rules). Generic types may also be used as the target type of a <code class="literal">declare parents</code> statement.</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">declare parents: Foo implements List<String></span></dt><dd><p>The <code class="literal">Foo</code> type implements the <code class="literal">List<String></code> interface. If
<code class="literal">Foo</code> already implements some other parameterization of the <code class="literal">List</code>
interface (for example, <code class="literal">List<Integer></code> then a compilation error will result since a
type cannot implement multiple parameterizations of the same generic interface type.
</p></dd></dl></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="declare-soft"></a>Declare Soft</h3></div></div></div><p>It is an error to use a generic or parameterized type as the softened exception type in a declare soft statement. Java 5 does
not permit a generic class to be a direct or indirect subtype of <code class="literal">Throwable</code> (JLS 8.1.2).</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="generic-aspects"></a>Generic Aspects</h3></div></div></div><p>
AspectJ 5 allows an <span class="emphasis"><em>abstract</em></span> aspect to be declared as a generic type. Any concrete
aspect extending a generic abstract aspect must extend a parameterized version of the abstract aspect.
Wildcards are not permitted in this parameterization.
</p><p>Given the aspect declaration:</p><pre class="programlisting">
public abstract aspect ParentChildRelationship<P,C> {
...
}
</pre><p>then</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">public aspect FilesInFolders extends ParentChildRelationship<Folder,File> {...</span></dt><dd><p>declares a concrete sub-aspect, <code class="literal">FilesInFolders</code> which extends the
parameterized abstract aspect <code class="literal">ParentChildRelationship<Folder,File></code>.
</p></dd><dt><span class="term">public aspect FilesInFolders extends ParentChildRelationship {...</span></dt><dd><p>results in a compilation error since the <code class="literal">ParentChildRelationship</code> aspect must
be fully parameterized.
</p></dd><dt><span class="term">public aspect ThingsInFolders<T> extends ParentChildRelationship<Folder,T></span></dt><dd><p>results in a compilation error since concrete aspects may not have type parameters.
</p></dd><dt><span class="term">public abstract aspect ThingsInFolders<T> extends ParentChildRelationship<Folder,T></span></dt><dd><p>declares a sub-aspect of <code class="literal">ParentChildRelationship</code> in which <code class="literal">Folder</code>
plays the role of parent (is bound to the type variable <code class="literal">P</code>).
</p></dd></dl></div><p>The type parameter variables from a generic aspect declaration may be used in place of a type within any
member of the aspect, <span class="emphasis"><em>except for within inter-type declarations</em></span>.
For example, we can declare a <code class="literal">ParentChildRelationship</code> aspect to
manage the bi-directional relationship between parent and child nodes as follows:
</p><pre class="programlisting">
/**
* a generic aspect, we've used descriptive role names for the type variables
* (Parent and Child) but you could use anything of course
*/
public abstract aspect ParentChildRelationship<Parent,Child> {
/** generic interface implemented by parents */
interface ParentHasChildren<C extends ChildHasParent>{
List<C> getChildren();
void addChild(C child);
void removeChild(C child);
}
/** generic interface implemented by children */
interface ChildHasParent<P extends ParentHasChildren>{
P getParent();
void setParent(P parent);
}
/** ensure the parent type implements ParentHasChildren<child type> */
declare parents: Parent implements ParentHasChildren<Child>;
/** ensure the child type implements ChildHasParent<parent type> */
declare parents: Child implements ChildHasParent<Parent>;
// Inter-type declarations made on the *generic* interface types to provide
// default implementations.
/** list of children maintained by parent */
private List<C> ParentHasChildren<C>.children = new ArrayList<C>();
/** reference to parent maintained by child */
private P ChildHasParent<P>.parent;
/** Default implementation of getChildren for the generic type ParentHasChildren */
public List<C> ParentHasChildren<C>.getChildren() {
return Collections.unmodifiableList(children);
}
/** Default implementation of getParent for the generic type ChildHasParent */
public P ChildHasParent<P>.getParent() {
return parent;
}
/**
* Default implementation of addChild, ensures that parent of child is
* also updated.
*/
public void ParentHasChildren<C>.addChild(C child) {
if (child.parent != null) {
child.parent.removeChild(child);
}
children.add(child);
child.parent = this;
}
/**
* Default implementation of removeChild, ensures that parent of
* child is also updated.
*/
public void ParentHasChildren<C>.removeChild(C child) {
if (children.remove(child)) {
child.parent = null;
}
}
/**
* Default implementation of setParent for the generic type ChildHasParent.
* Ensures that this child is added to the children of the parent too.
*/
public void ChildHasParent<P>.setParent(P parent) {
parent.addChild(this);
}
/**
* Matches at an addChild join point for the parent type P and child type C
*/
public pointcut addingChild(Parent p, Child c) :
execution(* ParentHasChildren.addChild(ChildHasParent)) && this(p) && args(c);
/**
* Matches at a removeChild join point for the parent type P and child type C
*/
public pointcut removingChild(Parent p, Child c) :
execution(* ParentHasChildren.removeChild(ChildHasParent)) && this(p) && args(c);
}
</pre><p>
The example aspect captures the protocol for managing a bi-directional parent-child relationship between
any two types playing the role of parent and child. In a compiler implementation managing an abstract syntax
tree (AST) in which AST nodes may contain other AST nodes we could declare the concrete aspect:
</p><pre class="programlisting">
public aspect ASTNodeContainment extends ParentChildRelationship<ASTNode,ASTNode> {
before(ASTNode parent, ASTNode child) : addingChild(parent, child) {
...
}
}
</pre><p>
As a result of this declaration, <code class="literal">ASTNode</code> gains members:
</p><table border="0" summary="Simple list" class="simplelist"><tr><td><code class="literal">List<ASTNode> children</code></td></tr><tr><td><code class="literal">ASTNode parent</code></td></tr><tr><td><code class="literal">List<ASTNode>getChildren()</code></td></tr><tr><td><code class="literal">ASTNode getParent()</code></td></tr><tr><td><code class="literal">void addChild(ASTNode child)</code></td></tr><tr><td><code class="literal">void removeChild(ASTNode child)</code></td></tr><tr><td><code class="literal">void setParent(ASTNode parent)</code></td></tr></table><p>
In a system managing orders, we could declare the concrete aspect:
</p><pre class="programlisting">
public aspect OrderItemsInOrders extends ParentChildRelationship<Order,OrderItem> {
}
</pre><p>
As a result of this declaration, <code class="literal">Order</code> gains members:
</p><table border="0" summary="Simple list" class="simplelist"><tr><td><code class="literal">List<OrderItem> children</code></td></tr><tr><td><code class="literal">List<OrderItem> getChildren()</code></td></tr><tr><td><code class="literal">void addChild(OrderItem child)</code></td></tr><tr><td><code class="literal">void removeChild(OrderItem child)</code></td></tr></table><p>and <code class="literal">OrderItem</code> gains members:</p><table border="0" summary="Simple list" class="simplelist"><tr><td><code class="literal">Order parent</code></td></tr><tr><td><code class="literal">Order getParent()</code></td></tr><tr><td><code class="literal">void setParent(Order parent)</code></td></tr></table><p>A second example of an abstract aspect, this time for handling exceptions in a uniform
manner, is shown below:</p><pre class="programlisting">
abstract aspect ExceptionHandling<T extends Throwable> {
/**
* method to be implemented by sub-aspects to handle thrown exceptions
*/
protected abstract void onException(T anException);
/**
* to be defined by sub-aspects to specify the scope of exception handling
*/
protected abstract pointcut inExceptionHandlingScope();
/**
* soften T within the scope of the aspect
*/
declare soft: T : inExceptionHandlingScope();
/**
* bind an exception thrown in scope and pass it to the handler
*/
after() throwing (T anException) : inExceptionHandlingScope() {
onException(anException);
}
}
</pre><p>Notice how the type variable <code class="literal">T extends Throwable</code> allows the
components of the aspect to be designed to work together in a type-safe manner. The
following concrete sub-aspect shows how the abstract aspect might be extended to
handle <code class="literal">IOExceptions</code>.</p><pre class="programlisting">
public aspect IOExceptionHandling extends ExceptionHandling<IOException>{
protected pointcut inExceptionHandlingScope() :
call(* doIO*(..)) && within(org.xyz..*);
/**
* called whenever an IOException is thrown in scope.
*/
protected void onException(IOException ex) {
System.err.println("handled exception: " + ex.getMessage());
throw new MyDomainException(ex);
}
}
</pre></div></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="autoboxing"></a>Chapter 4. Autoboxing and Unboxing</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="sect1"><a href="#boxing-inJava5">Autoboxing and Unboxing in Java 5</a></span></dt><dt><span class="sect1"><a href="#autoboxing-in-aspectj5">Autoboxing and Join Point matching in AspectJ 5</a></span></dt><dt><span class="sect1"><a href="#autoboxing-and-method-dispatch">Inter-type method declarations and method dispatch</a></span></dt></dl></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boxing-inJava5"></a>Autoboxing and Unboxing in Java 5</h2></div></div></div><p>
Java 5 (and hence AspectJ 1.5) supports automatic conversion of
primitive types (int, float, double etc.) to their object equivalents
(Integer, Float, Double,...) in assignments and method and constructor
invocations. This conversion is know as autoboxing.
</p><p>Java 5 also supports automatic unboxing, where wrapper types
are automatically converted into their primitive equivalents if
needed for assignments or method or constructor invocations.</p><p>For example:</p><pre class="programlisting">
int i = 0;
i = new Integer(5); // auto-unboxing
Integer i2 = 5; // autoboxing
</pre></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="autoboxing-in-aspectj5"></a>Autoboxing and Join Point matching in AspectJ 5</h2></div></div></div><p>Most of the pointcut designators match based on signatures, and
hence are unaffected by autoboxing. For example, a call to a method</p><pre class="programlisting">
public void foo(Integer i);
</pre><p>is <span class="emphasis"><em>not</em></span> matched by a pointcut
<code class="literal">call(void foo(int))</code> since the signature declares
a single <code class="literal">Integer</code> parameter, not an <code class="literal">int</code>.
</p><p>The <code class="literal">args</code> pointcut designator is affected by
autoboxing since it matches based on the runtime type of the arguments.
AspectJ 5 applies autoboxing and unboxing in determining argument matching.
In other words, <code class="literal">args(Integer)</code> will match any join
point at which there is a single argument of type <code class="literal">Integer</code>
or of type <code class="literal">int</code>.</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">args(Integer) and args(int) are equivalent</li><li class="listitem">args(Float) and args(float) are equivalent</li><li class="listitem">args(Double) and args(double) are equivalent</li><li class="listitem">args(Short) and args(short) are equivalent</li><li class="listitem">args(Byte) and args(byte) are equivalent</li><li class="listitem">args(Long) and args(long) are equivalent</li><li class="listitem">args(Boolean) and args(boolean) are equivalent</li></ul></div><p>
Autoboxing and unboxing are also applied when binding pointcut or
advice parameters, for example:
</p><pre class="programlisting">
pointcut foo(int i) : args(i);
before(Integer i) : foo(i) {
...
}
</pre></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="autoboxing-and-method-dispatch"></a>Inter-type method declarations and method dispatch</h2></div></div></div><p>Autoboxing, unboxing, and also varargs all affect the method
dispatch algorithm used in Java 5. In AspectJ 5, the target method
of a call is selected according to the following algorithm:</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">Attempt to locate a matching method or inter-type declared
method without considering
autoboxing, unboxing, or vararg invocations.</li><li class="listitem">If no match is found, try again considering autoboxing
and unboxing.</li><li class="listitem">Finally try again considering both autoboxing, unboxing,
and varargs.</li></ol></div><p>One consequence is that a directly matching inter-type declared
method will take precedence over a method declared locally in the
target class but that only matches via autoboxing.</p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="covariance"></a>Chapter 5. Covariance</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="sect1"><a href="#covariance-inJava5">Covariance in Java 5</a></span></dt><dt><span class="sect1"><a href="#covariance-and-join-point-matching">Covariant methods and Join Point matching</a></span></dt></dl></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="covariance-inJava5"></a>Covariance in Java 5</h2></div></div></div><p>
Java 5 (and hence AspectJ 5) allows you to narrow the return type
in an overriding method. For example:
</p><pre class="programlisting">
class A {
public A whoAreYou() {...}
}
class B extends A {
// override A.whoAreYou *and* narrow the return type.
public B whoAreYou() {...}
}
</pre></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="covariance-and-join-point-matching"></a>Covariant methods and Join Point matching</h2></div></div></div><p>The join point matching rules for <code class="literal">call</code>
and <code class="literal">execution</code> pointcut designators are extended
to match against covariant methods.</p><p>
Given the classes <code class="literal">A</code> and <code class="literal">B</code>
as defined in the previous section, and the program fragment
</p><pre class="programlisting">
A a = new A();
B b = new B();
a.whoAreYou();
b.whoAreYou();
</pre><p>The signatures for the call join point <code class="literal">a.whoAreYou()</code> are
simply:</p><pre class="programlisting">
A A.whoAreYou()
</pre><p>The signatures for the call join point <code class="literal">b.whoAreYou()</code> are:
</p><pre class="programlisting">
A A.whoAreYou()
B B.whoAreYou()
</pre><p>Following the join point matching rules given in <a class="xref" href="#jpsigs" title="Chapter 1. Join Point Signatures">Join Point Signatures</a>,</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">call(* whoAreYou())</span></dt><dd><p>Matches both calls, (since each call join point has at least
one matching signature).
</p></dd><dt><span class="term">call(* A.whoAreYou())</span></dt><dd><p>Matches both calls, (since each call join point has at least
one matching signature).
</p></dd><dt><span class="term">call(A whoAreYou())</span></dt><dd><p>Matches both calls, (since each call join point has at least
one matching signature).
</p></dd><dt><span class="term">call(A B.whoAreYou())</span></dt><dd><p>Does not match anything - neither of the call join points
has a signature matched by this pattern. A lint warning is
given for the call <code class="literal">a.whoAreYou()</code> ("does not match
because declaring type is A, if match required use target(B)").
</p></dd><dt><span class="term">call(A+ B.whoAreYou())</span></dt><dd><p>Matches the call to <code class="literal">b.whoAreYou()</code> since
the signature pattern matches the signature <code class="literal">B B.whoAreYou()</code>.
A lint warning is given for the call <code class="literal">a.whoAreYou()</code> ("does not match
because declaring type is A, if match required use target(B)").
</p></dd><dt><span class="term">call(B A.whoAreYou())</span></dt><dd><p>Does not match anything since neither join point has a
signature matched by this pattern.
</p></dd><dt><span class="term">call(B whoAreYou())</span></dt><dd><p>Matches the call to <code class="literal">b.whoAreYou()</code> only.
</p></dd><dt><span class="term">call(B B.whoAreYou())</span></dt><dd><p>Matches the call to <code class="literal">b.whoAreYou()</code> only.
</p></dd></dl></div><p>The rule for signature matching at call and execution join points
is unchanged from AspectJ 1.2: a call or execution pointcut matches if
the signature pattern matches at least one of the signatures of the
join point, and if the modifiers of the method or constructor are matched
by any modifier pattern or annotation pattern that may be present.</p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="varargs"></a>Chapter 6. Varargs</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="sect1"><a href="#varargs-inJava5">Variable-length Argument Lists in Java 5</a></span></dt><dd><dl><dt><span class="sect2"><a href="#calling-methods-and-constructors-with-variable-length-arguments">Calling Methods and Constructors with variable-length arguments</a></span></dt></dl></dd><dt><span class="sect1"><a href="#varargs-in-pcds">Using Variable-length arguments in advice and pointcut expressions</a></span></dt><dd><dl><dt><span class="sect2"><a href="#matching-signatures-based-on-variable-length-argument-types">Matching signatures based on variable length argument types</a></span></dt><dt><span class="sect2"><a href="#exposing-variable-length-arguments-as-context-in-pointcuts-and-advice">Exposing variable-length arguments as context in pointcuts and advice</a></span></dt></dl></dd></dl></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="varargs-inJava5"></a>Variable-length Argument Lists in Java 5</h2></div></div></div><p>
Java 5 (and hence AspectJ 5) allows you to specify methods that take a
variable number of arguments of a specified type. This is achieved using
an ellipsis (...) in the method signature as shown:
</p><pre class="programlisting">
public void foo(int i, String... strings) {
}
</pre><p>
A method or constructor may take at most one variable length argument, and
this must always be the last declared argument in the signature.
</p><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="calling-methods-and-constructors-with-variable-length-arguments"></a>Calling Methods and Constructors with variable-length arguments</h3></div></div></div><p>
A <span class="emphasis"><em>varargs</em></span> method may be called with zero or more arguments
in the variable argument position. For example, given the definition of
<code class="literal">foo</code> above, the following calls are all legal:
</p><pre class="programlisting">
foo(5);
foo(5,"One String");
foo(7,"One String","Two Strings");
foo(3,"One String","Two Strings","Three Strings");
</pre><p>A <span class="emphasis"><em>varargs</em></span> parameter is treated as an array within the
defining member. So in the body of <code class="literal">foo</code> we could write for example:
</p><pre class="programlisting">
public void foo(int i, String... strings) {
String[] someStrings = strings;
// rest of method body
}
</pre><p>One consequence of this treatment of a varargs parameter as an array
is that you can also call a varargs method with an array:</p><pre class="programlisting">
foo(7,new String[] {"One String","Two Strings"});
</pre></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="varargs-in-pcds"></a>Using Variable-length arguments in advice and pointcut expressions</h2></div></div></div><p>AspectJ 5 allows variable-length arguments to be used for methods declared within
aspects, and for inter-type declared methods and constructors, in accordance with the rules
outlined in the previous section.</p><p>
AspectJ 5 also allows variable length arguments to be matched by pointcut expressions and
bound as formals in advice.
</p><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="matching-signatures-based-on-variable-length-argument-types"></a>Matching signatures based on variable length argument types</h3></div></div></div><p>
Recall from the definition of signature patterns given in the chapter on
annotations (<a class="xref" href="#signaturePatterns" title="Signature Patterns">Signature Patterns</a>), that <code class="literal">MethodPattern</code>
and <code class="literal">ConstructorPattern</code> are extended to allow a <code class="literal">varargs</code>
pattern in the last argument position of a method or constructor signature.
</p><pre class="programlisting">
FormalsPattern := '..' (',' FormalsPatternAfterDotDot)? |
OptionalParensTypePattern (',' FormalsPattern)* |
TypePattern '...'
FormalsPatternAfterDotDot :=
OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* |
TypePattern '...'
</pre><p>
Method and constructor patterns are used in the <code class="literal">call</code>,
<code class="literal">execution</code>, <code class="literal">initialization</code>,
<code class="literal">preinitialization</code>, and <code class="literal">withincode</code>
pointcut designators. Some examples of usage follow:
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">call(* org.xyz.*.*(int, String...))</span></dt><dd><p>
Matches a call join point for a call to a method defined in the
<code class="literal">org.xyz</code> package, taking an <code class="literal">int</code>
and a <code class="literal">String vararg</code>.
</p></dd><dt><span class="term">execution(* org.xyz.*.*(Integer...))</span></dt><dd><p>
Matches an execution join point for the execution of a method defined in the
<code class="literal">org.xyz</code> package, taking an <code class="literal">Integer vararg</code>.
</p></dd><dt><span class="term">initialization(org.xyz.*.new((Foo || Goo)...))</span></dt><dd><p>
Matches the initialization join point for the construction of an
object in the <code class="literal">org.xyz</code> package via a constructor
taking either a variable number of <code class="literal">Foo</code> parameters or
a variable number of <code class="literal">Goo</code> parameters. (This example
illustrating the use of a type pattern with ...).
</p></dd></dl></div><p>A variable argument parameter and an array parameter are treated as distinct
signature elements, so given the method definitions:
</p><pre class="programlisting">
void foo(String...);
void bar(String[]);
</pre><p>
The pointcut <code class="literal">execution(* *.*(String...))</code> matches the execution join point
for <code class="literal">foo</code>, but not <code class="literal">bar</code>. The pointcut
<code class="literal">execution(* *.*(String[]))</code> matches the execution join point
for <code class="literal">bar</code> but not <code class="literal">foo</code>.
</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="exposing-variable-length-arguments-as-context-in-pointcuts-and-advice"></a>Exposing variable-length arguments as context in pointcuts and advice</h3></div></div></div><p>
When a varargs parameter is used within the body of a method, it has
an array type, as discussed in the introduction to this section. We follow the
same convention when binding a varargs parameter via the <code class="literal">args</code>
pointcut designator. Given a method
</p><pre class="programlisting">
public void foo(int i, String... strings) {
}
</pre><p>
The call or execution join points for <code class="literal">foo</code> will be matched
by the pointcut <code class="literal">args(int,String[])</code>. It is not permitted
to use the varargs syntax within an args pointcut designator - so you
<span class="emphasis"><em>cannot</em></span> write <code class="literal">args(int,String...)</code>.
</p><p>
Binding of a varargs parameter in an advice statement is straightforward:
</p><pre class="programlisting">
before(int i, String[] ss) : call(* foo(int,String...)) && args(i,ss) {
// varargs String... argument is accessible in advice body through ss
// ...
}
</pre><p>Since you cannot use the varargs syntax in the <code class="literal">args</code>
pointcut designator, you also cannot use the varargs syntax to declare
advice parameters.</p><p>Note: the proposal in this section does not allow you to
distinguish between a join point with a signature (int, String...)
and a join point with a signature (int, String[]) based
<span class="emphasis"><em>solely</em></span> on the use of the <code class="literal">args</code>
pointcut designator. If this distinction is required, <code class="literal">args</code>
can always be coupled with <code class="literal">call</code> or
<code class="literal">execution</code>.</p></div></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="enumeratedtypes"></a>Chapter 7. Enumerated Types</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="sect1"><a href="#enums-in-java5">Enumerated Types in Java 5</a></span></dt><dt><span class="sect1"><a href="#enums-in-aspectj5">Enumerated Types in AspectJ 5</a></span></dt></dl></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="enums-in-java5"></a>Enumerated Types in Java 5</h2></div></div></div><p>Java 5 (and hence AspectJ 5) provides explicit support for
enumerated types. In the simplest case, you can declare an enumerated
type as follows:</p><pre class="programlisting">
public enum ProgrammingLanguages {
COBOL,C,JAVA,ASPECTJ
}
</pre><p>Enumerated types are just classes, and they can contain method
and field declarations, and may implement interfaces. Enums may only
have private constructors, and may not be extended.</p><p>Enumerated types in Java 5 all implicitly extend the type
<code class="literal">java.lang.Enum</code>. It is illegal to explicitly
declare a subtype of this class.</p></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="enums-in-aspectj5"></a>Enumerated Types in AspectJ 5</h2></div></div></div><p>
AspectJ 5 supports the declaration of enumerated types just as Java 5
does. Because of the special restrictions Java 5 places around enumerated
types, AspectJ makes the following additional restrictions:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">You cannot use declare parents to change the super type of
an enum.</li><li class="listitem">You cannot use declare parents to declare java.lang.Enum as
the parent of any type.</li><li class="listitem">You cannot make inter-type constructor declarations on an
enum.</li><li class="listitem">You cannot extend the set of values in an enum via any
ITD-like construct.</li><li class="listitem">You cannot make inter-type method or field declarations on
an enum.</li><li class="listitem">You cannot use declare parents to make an enum type implement
an interface.</li></ul></div><p>In theory, the last of these two items <span class="emphasis"><em>could</em></span>
be supported. However, AspectJ 5 follows the simple rule that <span class="emphasis"><em>
an enum type cannot be the target of an inter-type declaration or declare
parents statement</em></span>. This position may be relaxed in a future
version of AspectJ.</p><p>If an enum is named explicitly as the target of a
declare parents statement, a compilation error will result. If an enumerated
type is matched by a non-explicit type pattern used in a declare parents
statement it will be ignored (and an XLint warning issued).</p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="pertypewithin"></a>Chapter 8. The pertypewithin Aspect Instantiation Model</h1></div></div></div><p>
AspectJ 5 defines a new per-clause type for aspect instantiation:
<code class="literal">pertypewithin</code>. Unlike the other per-clauses,
<code class="literal">pertypewithin</code> takes a type pattern:
</p><pre class="programlisting">
PerTypeWithin := 'pertypewithin' '(' OptionalParensTypePattern ')'
</pre><p>
When an aspect is declared using the <code class="literal">pertypewithin</code>
instantiation model, one new aspect instance will be created for each
type matched by the associated type pattern.
</p><p>
Pertypewithin aspects have <code class="literal">aspectOf</code> and
<code class="literal">hasAspect</code> methods with the following signatures:
</p><pre class="programlisting">
/**
* return true if this aspect has an instance associated with
* the given type.
*/
public static boolean hasAspect(Class clazz)
/**
* return the instance associated with the given type.
* Throws NoAspectBoundException if there is no such
* aspect.
*/
public static P aspectOf(Class clazz)
</pre><p>
Where <code class="literal">P</code> is the type of the <code class="literal">pertypewithin</code>
aspect.
</p><p>
In addition, <code class="literal">pertypewithin</code> aspects have a
<code class="literal">getWithinTypeName</code> method that can be called
to return the package qualified name of the type for which the
aspect instance has been created.
</p><pre class="programlisting">
/**
* return the package qualified name (eg. com.foo.MyClass) of the type
* for which the aspect instance has been instantiated.
*/
public String getWithinTypeName()
</pre><p>
In common with the other per-clause instantiation models, the execution
of any advice declared within a <code class="literal">pertypewithin</code> aspect
is conditional upon an implicit pointcut condition. In this case, that
any join point be <code class="literal">within</code> the type that the executing
aspect is an <code class="literal">aspectOf</code>. For example, given the aspect
definition
</p><pre class="programlisting">
import java.util.*;
public aspect InstanceTracking pertypewithin(org.xyz..*) {
// use WeakHashMap for auto-garbage collection of keys
private Map<Object,Boolean> instances = new WeakHashMap<Object,Boolean>();
after(Object o) returning() : execution(new(..)) && this(o) {
instances.put(o,true);
}
public Set<?> getInstances() {
return instances.keySet();
}
}
</pre><p>
Then one aspect instance will be created for each type within
<code class="literal">org.xyz..*</code>. For each aspect instance, the
after returning advice will match only the execution of constructors
within the matched per-type-within type. The net result is that
the aspect tracks all known instances of each type within
<code class="literal">org.xyz..*</code>. To get access to the instances, a
programmer can simply write
<code class="literal">InstanceTracking.aspectOf(org.xyz.SomeType.class).getInstances()</code>.
</p><p>
The <code class="literal">pertypewithin</code> aspect instantiation model should
be used when the implementation of a crosscutting concern requires that
some state be maintained for each type in a set of types. To maintain
state for a single type, it is easier to use a static inter-type declared
field. Examples of usage include instance tracking, profiling, and the
implementation of a common tracing idiom that uses one Logger per
traced class.
</p></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="ataspectj"></a>Chapter 9. An Annotation Based Development Style</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="sect1"><a href="#ataspectj-intro">Introduction</a></span></dt><dt><span class="sect1"><a href="#ataspectj-aspects">Aspect Declarations</a></span></dt><dd><dl><dt><span class="sect2"><a href="#limitations">Limitations</a></span></dt></dl></dd><dt><span class="sect1"><a href="#ataspectj-pcadvice">Pointcuts and Advice</a></span></dt><dd><dl><dt><span class="sect2"><a href="#pointcuts">Pointcuts</a></span></dt><dt><span class="sect2"><a href="#advice">Advice</a></span></dt></dl></dd><dt><span class="sect1"><a href="#ataspectj-itds">Inter-type Declarations</a></span></dt><dd><dl><dt><span class="sect2"><a href="#atDeclareParents">@DeclareParents</a></span></dt><dt><span class="sect2"><a href="#atDeclareMixin">@DeclareMixin</a></span></dt></dl></dd><dt><span class="sect1"><a href="#ataspectj-declare">Declare statements</a></span></dt><dt><span class="sect1"><a href="#ataspectj-aspectof">aspectOf() and hasAspect() methods</a></span></dt></dl></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="ataspectj-intro"></a>Introduction</h2></div></div></div><p>In addition to the familiar AspectJ code-based style of aspect
declaration, AspectJ 5 also supports an annotation-based style of
aspect declaration. We informally call the set of annotations that
support this development style the "@AspectJ" annotations.</p><p>
AspectJ 5 allows aspects and their members to be specified using
either the code style or the annotation style. Whichever style you
use, the AspectJ weaver ensures that your program has exactly the
same semantics. It is, to quote a famous advertising campaign,
"a choice, not a compromise". The two styles can be mixed within
a single application, and even within a single source file, though
we doubt this latter mix will be recommended in practice.
</p><p>
The use of the @AspectJ annotations means that there are large
classes of AspectJ applications that can be compiled by a regular
Java 5 compiler, and subsequently woven by the AspectJ weaver (for
example, as an additional build stage, or as late as class load-time).
In this chapter we introduce the @AspectJ annotations and show how
they can be used to declare aspects and aspect members.
</p></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="ataspectj-aspects"></a>Aspect Declarations</h2></div></div></div><p>
Aspect declarations are supported by the
<code class="literal">org.aspectj.lang.annotation.Aspect</code>
annotation.
The declaration:
</p><pre class="programlisting">
@Aspect
public class Foo {}
</pre><p>Is equivalent to:</p><pre class="programlisting">
public aspect Foo {}
</pre><p>To specify an aspect an aspect instantiation model (the default is
singleton), provide the perclause as the
<code class="literal">@Aspect</code>
value.
For example:
</p><pre class="programlisting">
@Aspect("perthis(execution(* abc..*(..)))")
public class Foo {}
</pre><p>is equivalent to...</p><pre class="programlisting">
public aspect Foo perthis(execution(* abc..*(..))) {}
</pre><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="limitations"></a>Limitations</h3></div></div></div><p>Privileged aspects are not supported by the annotation style.</p></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="ataspectj-pcadvice"></a>Pointcuts and Advice</h2></div></div></div><p>
Pointcut and advice declarations can be made using the
<code class="literal">Pointcut, Before, After, AfterReturning, AfterThrowing,</code>
and
<code class="literal">Around</code>
annotations.
</p><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="pointcuts"></a>Pointcuts</h3></div></div></div><p>
Pointcuts are specified using the
<code class="literal">org.aspectj.lang.annotation.Pointcut</code>
annotation
on a method declaration. The method should have a
<code class="literal">void</code>
return type. The parameters of the method correspond to the parameters
of the pointcut. The modifiers of the method correspond to the modifiers
of the pointcut.
</p><p>
As a general rule, the
<code class="literal">@Pointcut</code>
annotated method must have an empty method body
and must not have any
<code class="literal">throws</code>
clause. If formal are bound (using
<code class="literal">args(), target(), this(), @args(), @target(), @this(), @annotation())</code>
in the
pointcut, then they must appear in the method signature.
</p><p>
The
<code class="literal">if()</code>
pointcut is treated specially and is discussed in a later section.
</p><p>Here is a simple example of a pointcut declaration in both code and @AspectJ styles:</p><pre class="programlisting">
@Pointcut("call(* *.*(..))")
void anyCall() {}
</pre><p>is equivalent to...</p><pre class="programlisting">
pointcut anyCall() : call(* *.*(..));
</pre><p>When binding arguments, simply declare the arguments as normal in the annotated method:</p><pre class="programlisting">
@Pointcut("call(* *.*(int)) && args(i) && target(callee)")
void anyCall(int i, Foo callee) {}
</pre><p>is equivalent to...</p><pre class="programlisting">
pointcut anyCall(int i, Foo callee) : call(* *.*(int)) && args(i) && target(callee);
</pre><p>An example with modifiers (Remember that Java 5 annotations are not
inherited, so the <code class="literal">@Pointcut</code> annotation must be
present on the extending aspect's pointcut declaration too):</p><pre class="programlisting">
@Pointcut("")
protected abstract void anyCall();
</pre><p>is equivalent to...</p><pre class="programlisting">
protected abstract pointcut anyCall();
</pre><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp65301328"></a>Type references inside @AspectJ annotations</h4></div></div></div><p>
Using the code style, types referenced in pointcut expressions are
resolved with respect to the imported types in the compilation unit.
When using the annotation style, types referenced in pointcut
expressions are resolved in the absence of any imports and so have
to be fully qualified if they are not by default visible to the
declaring type (outside of the declaring package and
<code class="literal">java.lang</code>
). This
does not apply to type patterns with wildcards, which are always resolved
in a global scope.
</p><p>
Consider the following compilation unit:
</p><pre class="programlisting">
package org.aspectprogrammer.examples;
import java.util.List;
public aspect Foo {
pointcut listOperation() : call(* List.*(..));
pointcut anyUtilityCall() : call(* java.util..*(..));
}
</pre><p>
Using the annotation style this would be written as:
</p><pre class="programlisting">
package org.aspectprogrammer.examples;
import java.util.List; // redundant but harmless
@Aspect
public class Foo {
@Pointcut("call(* java.util.List.*(..))") // must qualify
void listOperation() {}
@Pointcut("call(* java.util..*(..))")
void anyUtilityCall() {}
}
</pre></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp65306320"></a>if() pointcut expressions</h4></div></div></div><p>In code style, it is possible to use the
<code class="literal">if(...)</code>
poincut to define
a conditional pointcut expression which will be evaluated at runtime for each candidate join point.
The
<code class="literal">if(...)</code>
body can be any valid Java boolean expression, and can use any exposed formal, as well as the join
point forms
<code class="literal">thisJoinPoint, thisJoinPointStaticPart and thisJoinPointEnclosingStaticPart</code>
.
</p><p>
When using the annotation style, it is not possible to write a full Java expression
within
the annotation value so the syntax differs slightly, whilst providing the very same
semantics and runtime behaviour. An
<code class="literal">if()</code>
pointcut expression can be
declared in an
<code class="literal">@Pointcut</code>
, but must have either an empty body (<code class="literal">if()</code>, or be one
of the expression forms
<code class="literal">if(true)</code>
or
<code class="literal">if(false)</code>
. The annotated
method must be public, static, and return a boolean. The body of the method contains the
condition to be evaluated. For example:
</p><pre class="programlisting">
@Pointcut("call(* *.*(int)) && args(i) && if()")
public static boolean someCallWithIfTest(int i) {
return i > 0;
}
</pre><p>is equivalent to...</p><pre class="programlisting">
pointcut someCallWithIfTest(int i) : call(* *.*(int)) && args(i) && if(i > 0);
</pre><p>and the following is also a valid form:</p><pre class="programlisting">
static int COUNT = 0;
@Pointcut("call(* *.*(int)) && args(i) && if()")
public static boolean someCallWithIfTest(int i, JoinPoint jp, JoinPoint.EnclosingStaticPart esjp) {
// any legal Java expression...
return i > 0
&& jp.getSignature().getName.startsWith("doo")
&& esjp.getSignature().getName().startsWith("test")
&& COUNT++ < 10;
}
@Before("someCallWithIfTest(anInt, jp, enc)")
public void beforeAdviceWithRuntimeTest(int anInt, JoinPoint jp, JoinPoint.EnclosingStaticPart enc) {
//...
}
// Note that the following is NOT valid
/*
@Before("call(* *.*(int)) && args(i) && if()")
public void advice(int i) {
// so you were writing an advice or an if body ?
}
*/
</pre><p>
It is thus possible with the annotation style to use the
<code class="literal">if()</code>
pointcut
only within an
<code class="literal">@Pointcut</code>
expression. The
<code class="literal">if()</code>
must not contain any
body. The annotated
<code class="literal">@Pointcut</code>
method must then be of the form
<code class="literal">public static boolean</code>
and can use formal bindings as usual.
Extra
<span class="emphasis"><em>implicit</em></span>
arguments of type JoinPoint, JoinPoint.StaticPart and JoinPoint.EnclosingStaticPart can also be used
(this is not permitted for regular annotated pointcuts not using the
<code class="literal">if()</code>
form).
</p><p>
The special forms
<code class="literal">if(true)</code>
and
<code class="literal">if(false)</code>
can be used in a more
general way and don't imply that the pointcut method must have a body.
You can thus write
<code class="literal">@Before("somePoincut() && if(false)")</code>
.
</p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="advice"></a>Advice</h3></div></div></div><p>In this section we first discuss the use of annotations for
simple advice declarations. Then we show how
<code class="literal">thisJoinPoint</code>
and its siblings are handled in the body of advice and discuss the
treatment of
<code class="literal">proceed</code>
in around advice.
</p><p>Using the annotation style, an advice declaration is written as
a regular Java method with one of the
<code class="literal">Before, After, AfterReturning,
AfterThrowing,</code>
or
<code class="literal">Around</code>
annotations. Except in
the case of around advice, the method should return void. The method should
be declared public.
</p><p>A method that has an advice annotation is treated exactly as an
advice declaration by AspectJ's weaver. This includes the join points that
arise when the advice is executed (an adviceexecution join point, not a
method execution join point).</p><p>The following example shows a simple before advice declaration in
both styles:</p><pre class="programlisting">
@Before("call(* org.aspectprogrammer..*(..)) && this(Foo)")
public void callFromFoo() {
System.out.println("Call from Foo");
}
</pre><p>is equivalent to...</p><pre class="programlisting">
before() : call(* org.aspectprogrammer..*(..)) && this(Foo) {
System.out.println("Call from Foo");
}
</pre><p>If the advice body needs to know which particular
<code class="literal">Foo</code>
instance
is making the call, just add a parameter to the advice declaration.
</p><pre class="programlisting">
before(Foo foo) : call(* org.aspectprogrammer..*(..)) && this(foo) {
System.out.println("Call from Foo: " + foo);
}
</pre><p>can be written as:</p><pre class="programlisting">
@Before("call(* org.aspectprogrammer..*(..)) && this(foo)")
public void callFromFoo(Foo foo) {
System.out.println("Call from Foo: " + foo);
}
</pre><p>If the advice body needs access to
<code class="literal">thisJoinPoint</code>
,
<code class="literal">thisJoinPointStaticPart</code>
,
<code class="literal">thisEnclosingJoinPointStaticPart</code>
then these need to
be declared as additional method parameters when using the annotation
style.
</p><pre class="programlisting">
@Before("call(* org.aspectprogrammer..*(..)) && this(foo)")
public void callFromFoo(JoinPoint thisJoinPoint, Foo foo) {
System.out.println("Call from Foo: " + foo + " at "
+ thisJoinPoint);
}
</pre><p>is equivalent to...</p><pre class="programlisting">
before(Foo foo) : call(* org.aspectprogrammer..*(..)) && this(foo) {
System.out.println("Call from Foo: " + foo + " at "
+ thisJoinPoint);
}
</pre><p>Advice that needs all three variables would be declared:</p><pre class="programlisting">
@Before("call(* org.aspectprogrammer..*(..)) && this(Foo)")
public void callFromFoo(JoinPoint thisJoinPoint,
JoinPoint.StaticPart thisJoinPointStaticPart,
JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart) {
// ...
}
</pre><p>
<code class="literal">JoinPoint.EnclosingStaticPart</code>
is a new (empty) sub-interface
of
<code class="literal">JoinPoint.StaticPart</code>
which allows the AspectJ weaver to
distinguish based on type which of
<code class="literal">thisJoinPointStaticPart</code>
and
<code class="literal">thisEnclosingJoinPointStaticPart</code>
should be passed in a given
parameter position.
</p><p>
<code class="literal">After</code>
advice declarations take exactly the same form
as
<code class="literal">Before</code>
, as do the forms of
<code class="literal">AfterReturning</code>
and
<code class="literal">AfterThrowing</code>
that do not expose the return type or
thrown exception respectively.
</p><p>
To expose a return value with after returning advice simply declare the returning
parameter as a parameter in the method body and bind it with the "returning"
attribute:
</p><pre class="programlisting">
@AfterReturning("criticalOperation()")
public void phew() {
System.out.println("phew");
}
@AfterReturning(pointcut="call(Foo+.new(..))",returning="f")
public void itsAFoo(Foo f) {
System.out.println("It's a Foo: " + f);
}
</pre><p>is equivalent to...</p><pre class="programlisting">
after() returning : criticalOperation() {
System.out.println("phew");
}
after() returning(Foo f) : call(Foo+.new(..)) {
System.out.println("It's a Foo: " + f);
}
</pre><p>(Note the use of the "pointcut=" prefix in front of the pointcut
expression in the returning case).</p><p>After throwing advice works in a similar fashion, using the
<code class="literal">throwing</code>
attribute when needing to expose a
thrown exception.
</p><p>For around advice, we have to tackle the problem of
<code class="literal">proceed</code>
.
One of the design goals for the annotation style is that a large class of
AspectJ applications should be compilable with a standard Java 5 compiler.
A straight call to
<code class="literal">proceed</code>
inside a method body:
</p><pre class="programlisting">
@Around("call(* org.aspectprogrammer..*(..))")
public Object doNothing() {
return proceed(); // CE on this line
}
</pre><p>will result in a "No such method" compilation error. For this
reason AspectJ 5 defines a new sub-interface of
<code class="literal">JoinPoint</code>
,
<code class="literal">ProceedingJoinPoint</code>
.
</p><pre class="programlisting">
public interface ProceedingJoinPoint extends JoinPoint {
public Object proceed(Object[] args);
}
</pre><p>The around advice given above can now be written as:</p><pre class="programlisting">
@Around("call(* org.aspectprogrammer..*(..))")
public Object doNothing(ProceedingJoinPoint thisJoinPoint) {
return thisJoinPoint.proceed();
}
</pre><p>Here's an example that uses parameters for the proceed call:</p><pre class="programlisting">
@Aspect
public class ProceedAspect {
@Pointcut("call(* setAge(..)) && args(i)")
void setAge(int i) {}
@Around("setAge(i)")
public Object twiceAsOld(ProceedingJoinPoint thisJoinPoint, int i) {
return thisJoinPoint.proceed(new Object[]{i*2}); //using Java 5 autoboxing
}
}
</pre><p>is equivalent to:</p><pre class="programlisting">
public aspect ProceedAspect {
pointcut setAge(int i): call(* setAge(..)) && args(i);
Object around(int i): setAge(i) {
return proceed(i*2);
}
}
</pre><p>Note that the ProceedingJoinPoint does not need to be passed to the proceed(..) arguments.
</p><p>In code style, the proceed method has the same signature as the advice, any reordering of
actual arguments to the joinpoint that is done in the advice signature must be respected. Annotation
style is different. The proceed(..) call takes, in this order:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">If 'this()' was used in the pointcut <span class="emphasis"><em>for binding</em></span>, it must be passed first in proceed(..).
</li><li class="listitem">If 'target()' was used in the pointcut <span class="emphasis"><em>for binding</em></span>, it must be passed next in proceed(..) - it will be the
first argument to proceed(..) if this() was not used for binding.
</li><li class="listitem">Finally come <span class="emphasis"><em>all</em></span> the arguments expected at the join point, in the order they
are supplied at the join point. Effectively the advice signature is ignored - it doesn't
matter if a subset of arguments were bound or the ordering was changed in the advice
signature, the proceed(..) calls takes all of them in the right order for the join point.
</li></ul></div><p>
</p><p>Since proceed(..) in this case takes an Object array, AspectJ cannot do as much compile time
checking as it can for code style. If the rules above aren't obeyed then it will unfortunately
manifest as a runtime error.
</p></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="ataspectj-itds"></a>Inter-type Declarations</h2></div></div></div><p>
Inter-type declarations are challenging to support using an annotation style. For code style aspects
compiled with the ajc compiler, the entire type system can be made aware of inter-type declarations (new
supertypes, new methods, new fields) and the completeness and correctness of it can be guaranteed.
Achieving this with an annotation style is hard because the source code may simply be compiled with javac
where the type system cannot be influenced and what is compiled must be 'pure java'.
</p><p>
AspectJ 1.5.0 introduced @DeclareParents, an attempt to offer something like that which is achievable with
code style declare parents and the other intertype declarations (fields, methods, constructors). However,
it has proved too challenging to get close to the expressiveness and capabilities of code style in this area
and effectively @DeclareParents is offering just a mixin strategy. The definition of mixin I am using here is that when
some interface I is mixed into some target type T then this means that all the methods from I are created in T and their
implementations are simple forwarding methods that call a delegate which that provides an implementation of I.
</p><p>
The next section covers @DeclareParents but AspectJ 1.6.4 introduces @DeclareMixin - an improved approach to defining
a mixin and the choice of a different name for the annotation will hopefully alleviate some of the confusion about
why @DeclareParents just doesn't offer the same semantics as the code style variant. Offering @DeclareMixin also gives
code style developers a new tool for a simple mixin whereas previously they would have avoided @DeclareParents
thinking what it could only do was already achievable with code style syntax.
</p><p>
The defaultImpl attribute of @DeclareParents may become deprecated if @DeclareMixin proves popular, leaving
@DeclareParents purely as a way to introduce a marker interface.
</p><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="atDeclareParents"></a>@DeclareParents</h3></div></div></div><p>
Consider the following aspect:
</p><pre class="programlisting">
public aspect MoodIndicator {
public interface Moody {};
private Mood Moody.mood = Mood.HAPPY;
public Mood Moody.getMood() {
return mood;
}
declare parents : org.xyz..* implements Moody;
before(Moody m) : execution(* *.*(..)) && this(m) {
System.out.println("I'm feeling " + m.getMood());
}
}
</pre><p>
This declares an interface
<code class="literal">Moody</code>
, and then makes two
inter-type declarations on the interface - a field that is private to the
aspect, and a method that returns the mood. Within the body of the inter-type
declared method
<code class="literal">getMoody</code>
, the type of
<code class="literal">this</code>
is
<code class="literal">Moody</code>
(the target type of the inter-type declaration).
</p><p>Using the annotation style this aspect can be written:
</p><pre class="programlisting">
@Aspect
public class MoodIndicator {
// this interface can be outside of the aspect
public interface Moody {
Mood getMood();
};
// this implementation can be outside of the aspect
public static class MoodyImpl implements Moody {
private Mood mood = Mood.HAPPY;
public Mood getMood() {
return mood;
}
}
// the field type must be the introduced interface. It can't be a class.
@DeclareParents(value="org.xzy..*",defaultImpl=MoodyImpl.class)
private Moody implementedInterface;
@Before("execution(* *.*(..)) && this(m)")
void feelingMoody(Moody m) {
System.out.println("I'm feeling " + m.getMood());
}
}
</pre><p>
This is very similar to the mixin mechanism supported by AspectWerkz. The
effect of the
<code class="literal">@DeclareParents</code>
annotation is equivalent to
a declare parents statement that all types matching the type pattern implement
the given interface (in this case Moody).
Each method declared in the interface is treated as an inter-type declaration.
Note how this scheme operates within the constraints
of Java type checking and ensures that
<code class="literal">this</code>
has access
to the exact same set of members as in the code style example.
</p><p>
Note that it is illegal to use the @DeclareParents annotation on an aspect' field of a non-interface type.
The interface type is the inter-type declaration contract that dictates
which methods are declared on the target type.
</p><pre class="programlisting">
// this type will be affected by the inter-type declaration as the type pattern matches
package org.xyz;
public class MoodTest {
public void test() {
// see here the cast to the introduced interface (required)
Mood mood = ((Moody)this).getMood();
...
}
}
</pre><p>The <code class="literal">@DeclareParents</code> annotation can also be used without specifying
a <code class="literal">defaultImpl</code> value (for example,
<code class="literal">@DeclareParents("org.xyz..*")</code>). This is equivalent to a
<code class="literal">declare parents ... implements</code> clause, and does <span class="emphasis"><em>not</em></span>
make any inter-type declarations for default implementation of the interface methods.
</p><p>
Consider the following aspect:
</p><pre class="programlisting">
public aspect SerializableMarker {
declare parents : org.xyz..* implements Serializable;
}
</pre><p>Using the annotation style this aspect can be written:
</p><pre class="programlisting">
@Aspect
public class SerializableMarker {
@DeclareParents("org.xyz..*")
Serializable implementedInterface;
}
</pre><p>
If the interface defines one or more operations, and these are not implemented by
the target type, an error will be issued during weaving.
</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="atDeclareMixin"></a>@DeclareMixin</h3></div></div></div><p>
Consider the following aspect:
</p><pre class="programlisting">
public aspect MoodIndicator {
public interface Moody {};
private Mood Moody.mood = Mood.HAPPY;
public Mood Moody.getMood() {
return mood;
}
declare parents : org.xyz..* implements Moody;
before(Moody m) : execution(* *.*(..)) && this(m) {
System.out.println("I'm feeling " + m.getMood());
}
}
</pre><p>
This declares an interface <code class="literal">Moody</code>, and then makes two inter-type declarations on the interface
- a field that is private to the aspect, and a method that returns the mood. Within the body of the inter-type
declared method <code class="literal">getMoody</code>, the type of <code class="literal">this</code> is <code class="literal">Moody</code>
(the target type of the inter-type declaration).
</p><p>Using the annotation style this aspect can be written:
</p><pre class="programlisting">
@Aspect
public class MoodIndicator {
// this interface can be outside of the aspect
public interface Moody {
Mood getMood();
};
// this implementation can be outside of the aspect
public static class MoodyImpl implements Moody {
private Mood mood = Mood.HAPPY;
public Mood getMood() {
return mood;
}
}
// The DeclareMixin annotation is attached to a factory method that can return instances of the delegate
// which offers an implementation of the mixin interface. The interface that is mixed in is the
// return type of the method.
@DeclareMixin("org.xyz..*")
public static Moody createMoodyImplementation() {
return new MoodyImpl();
}
@Before("execution(* *.*(..)) && this(m)")
void feelingMoody(Moody m) {
System.out.println("I'm feeling " + m.getMood());
}
}
</pre><p>
Basically, the <code class="literal">@DeclareMixin</code> annotation is attached to a factory method. The
factory method specifies the interface to mixin as its return type, and calling the method should
create an instance of a delegate that implements the interface. This is the interface which will
be delegated to from any target matching the specified type pattern.
</p><p>
Exploiting this syntax requires the user to obey the rules of pure Java. So references to any
targeted type as if it were affected by the Mixin must be made through a cast, like this:
</p><pre class="programlisting">
// this type will be affected by the inter-type declaration as the type pattern matches
package org.xyz;
public class MoodTest {
public void test() {
// see here the cast to the introduced interface (required)
Mood mood = ((Moody)this).getMood();
...
}
}
</pre><p>
Sometimes the delegate instance may want to perform differently depending upon the type/instance for
which it is behaving as a delegate. To support this it is possible for the factory method to specify a
parameter. If it does, then when the factory method is called the parameter will be the object instance for
which a delegate should be created:
</p><pre class="programlisting">
@Aspect
public class Foo {
@DeclareMixin("org.xyz..*")
public static SomeInterface createDelegate(Object instance) {
return new SomeImplementation(instance);
}
}
</pre><p>
It is also possible to make the factory method non-static - and in this case it can then exploit
the local state in the surrounding aspect instance, but this is only supported for singleton aspects:
</p><pre class="programlisting">
@Aspect
public class Foo {
public int maxLimit=35;
@DeclareMixin("org.xyz..*")
public SomeInterface createDelegate(Object instance) {
return new SomeImplementation(instance,maxLimit);
}
}
</pre><p>
Although the interface type is usually determined purely from the return type of the factory method, it can
be specified in the annotation if necessary. In this example the return type of the method extends multiple
other interfaces and only a couple of them (I and J) should be mixed into any matching targets:
</p><pre class="programlisting">
// interfaces is an array of interface classes that should be mixed in
@DeclareMixin(value="org.xyz..*",interfaces={I.class,J.class})
public static InterfaceExtendingLotsOfInterfaces createMoodyImplementation() {
return new MoodyImpl();
}
</pre><p>
There are clearly similarities between <code class="literal">@DeclareMixin</code> and <code class="literal">@DeclareParents</code> but
<code class="literal">@DeclareMixin</code> is not pretending to offer more than a simple mixin strategy. The flexibility in
being able to provide the factory method instead of requiring a no-arg constructor for the implementation also
enables delegate instances to make decisions based upon the type for which they are the delegate.
</p><p>
Any annotations defined on the interface methods are also put upon the delegate forwarding methods created in the
matched target type.
</p></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="ataspectj-declare"></a>Declare statements</h2></div></div></div><p>The previous section on inter-type declarations covered the case
of declare parents ... implements. The 1.5.0 release of AspectJ 5 does
not support annotation style declarations for declare parents ... extends
and declare soft (programs with these declarations would not in general
be compilable by a regular Java 5 compiler, reducing the priority of
their implementation). These may be supported in a future release.</p><p>
Declare annotation is also not supported in the 1.5.0 release of AspectJ 5.
</p><p>Declare precedence <span class="emphasis"><em>is</em></span>
supported. For declare precedence, use the
<code class="literal">@DeclarePrecedence</code>
annotation as in the following example:
</p><pre class="programlisting">
public aspect SystemArchitecture {
declare precedence : Security*, TransactionSupport, Persistence;
// ...
}
can be written as:
@Aspect
@DeclarePrecedence("Security*,org.xyz.TransactionSupport,org.xyz.Persistence")
public class SystemArchitecture {
// ...
}
</pre><p>We also support annotation style declarations for declare warning and
declare error - any corresponding warnings and errors will be emitted at
weave time, not when the aspects containing the declarations are compiled.
(This is the same behaviour as when using declare warning or error with the
code style). Declare warning and error declarations are made by annotating
a string constant whose value is the message to be issued.</p><p>Note that the String must be a literal and not the result of the invocation
of a static method for example.</p><pre class="programlisting">
declare warning : call(* javax.sql..*(..)) && !within(org.xyz.daos..*)
: "Only DAOs should be calling JDBC.";
declare error : execution(* IFoo+.*(..)) && !within(org.foo..*)
: "Only foo types can implement IFoo";
can be written as...
@DeclareWarning("call(* javax.sql..*(..)) && !within(org.xyz.daos..*)")
static final String aMessage = "Only DAOs should be calling JDBC.";
@DeclareError("execution(* IFoo+.*(..)) && !within(org.foo..*)")
static final String badIFooImplementors = "Only foo types can implement IFoo";
// the following is not valid since the message is not a String literal
@DeclareError("execution(* IFoo+.*(..)) && !within(org.foo..*)")
static final String badIFooImplementorsCorrupted = getMessage();
static String getMessage() {
return "Only foo types can implement IFoo " + System.currentTimeMillis();
}
</pre></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="ataspectj-aspectof"></a>aspectOf() and hasAspect() methods</h2></div></div></div><p>A central part of AspectJ's programming model is that aspects
written using the code style and compiled using ajc support
<code class="literal">aspectOf</code>
and
<code class="literal">hasAspect</code>
static
methods. When developing an aspect using the annotation style and compiling
using a regular Java 5 compiler, these methods will not be visible to the
compiler and will result in a compilation error if another part of the
program tries to call them.
</p><p>To provide equivalent support for AspectJ applications compiled with
a standard Java 5 compiler, AspectJ 5 defines the
<code class="literal">Aspects</code>
utility class:
</p><pre class="programlisting">
public class Aspects {
/* variation used for singleton, percflow, percflowbelow */
static<T> public static T aspectOf(T aspectType) {...}
/* variation used for perthis, pertarget */
static<T> public static T aspectOf(T aspectType, Object forObject) {...}
/* variation used for pertypewithin */
static<T> public static T aspectOf(T aspectType, Class forType) {...}
/* variation used for singleton, percflow, percflowbelow */
public static boolean hasAspect(Object anAspect) {...}
/* variation used for perthis, pertarget */
public static boolean hasAspect(Object anAspect, Object forObject) {...}
/* variation used for pertypewithin */
public static boolean hasAspect(Object anAspect, Class forType) {...}
}
</pre></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="reflection"></a>Chapter 10. New Reflection Interfaces</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="sect1"><a href="#reflection_api">Using AjTypeSystem</a></span></dt></dl></div><p>
AspectJ 5 provides a full set of reflection APIs analogous to the
<code class="literal">java.lang.reflect</code> package, but fully aware of the
AspectJ type system. See the javadoc for the runtime and tools APIs
for the full details. The reflection APIs are only supported when
running under Java 5 and for code compiled by the AspectJ 5 compiler
at target level 1.5.
</p><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="reflection_api"></a>Using AjTypeSystem</h2></div></div></div><p>
The starting point for using the reflection apis is
<code class="literal">org.aspectj.lang.reflect.AjTypeSystem</code> which
provides the method <code class="literal">getAjType(Class)</code> which will
return the <code class="literal">AjType</code> corresponding to a given
Java class. The <code class="literal">AjType</code> interface corresponds to
<code class="literal">java.lang.Class</code> and gives you access to all of the
method, field, constructor, and also pointcut, advice, declare
statement and inter-type declaration members in the type.
</p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="miscellaneous"></a>Chapter 11. Other Changes in AspectJ 5</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="sect1"><a href="#pointcuts">Pointcuts</a></span></dt><dt><span class="sect1"><a href="#declare-soft">Declare Soft</a></span></dt></dl></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="pointcuts"></a>Pointcuts</h2></div></div></div><p>
AspectJ 5 is more liberal than AspectJ 1.2.1 in accepting pointcut expressions
that bind context variables in more than one location. For example, AspectJ
1.2.1 does not allow:
</p><pre class="programlisting">
pointcut foo(Foo foo) : (execution(* *(..)) && this(foo) ) ||
(set(* *) && target(foo));
</pre><p>
whereas this expression is permitted in AspectJ 5. Each context variable must
be bound exactly once in each branch of a disjunction, and the disjunctive branches
must be mutually exclusive. In the above example for instance, no join point
can be both an execution join point and a set join point so the two branches
are mutually exclusive.
</p></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="declare-soft"></a>Declare Soft</h2></div></div></div><p>
The semantics of the <code class="literal">declare soft</code> statement have been
refined in AspectJ 5 to only soften exceptions that are not already runtime
exceptions. If the exception type specified in a declare soft statement is <code class="literal">RuntimeException</code>
or a subtype of <code class="literal">RuntimeException</code> then a new XLint warning will be issued:</p><pre class="programlisting">
declare soft : SomeRuntimeException : execution(* *(..));
>> "SomeRuntimeException will not be softened as it is already a RuntimeException" [XLint:runtimeExceptionNotSoftened]
</pre><p>
This XLint message can be controlled by setting the <code class="literal">runtimeExceptionNotSoftened</code> XLint parameter.
</p><p>
If the exception type specified in a declare soft statement is a super type of <code class="literal">RuntimeException</code>
(such as <code class="literal">Exception</code> for example) then any <span class="emphasis"><em>checked</em></span> exception thrown at a matched join point,
where the exception is an instance of the softened exception, will be softened to an
<code class="literal">org.aspectj.lang.SoftException</code>.
</p><pre class="programlisting">
public aspect SoftenExample {
declare soft : Exception : execution(* Foo.*(..));
}
class Foo {
public static void main(String[] args) {
Foo foo = new Foo();
foo.foo();
foo.bar();
}
void foo() throws Exception {
throw new Exception(); // this will be converted to a SoftException
}
void bar() throws Exception {
throw new RuntimeException(); // this will remain a RuntimeException
}
}
</pre></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="ltw"></a>Chapter 12. Load-Time Weaving</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="sect1"><a href="#ltw-introduction">Introduction</a></span></dt></dl></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="ltw-introduction"></a>Introduction</h2></div></div></div><p>See Developer's Guide for information on
load-time weaving support in AspectJ 5.</p></div></div></div></body></html>
|