Introduction <ul><li>Building enterprise applications is hard </li></ul><ul><ul><li>state management </li></ul></ul><ul><u...
“Enterprise” <ul><li>An enterprise system is one which … </li></ul><ul><ul><li>… shares some or all resources used </li></...
Topics <ul><li>Architecture </li></ul><ul><ul><li>“ Big Picture” topics </li></ul></ul><ul><li>Communication </li></ul><ul...
Architecture <ul><li>Enterprise architecture: a vision for the design and implementation of your enterprise components </l...
Item 1 <ul><li>Prefer components as the key element of development, deployment and reuse </li></ul><ul><ul><li>Objects wer...
Item 2 <ul><li>Prefer loose coupling across component boundaries </li></ul><ul><ul><li>Coupling is the degree of interconn...
Item 3 <ul><li>Differentiate layers from tiers </li></ul><ul><ul><li>&quot; N -tier systems are better than 2-tier systems...
Item 4 <ul><li>Keep data and processors close together </li></ul><ul><ul><li>Reason: Obtaining data is often not a free ac...
Item 5 <ul><li>Remember that identity breeds contention </li></ul><ul><ul><li>Remember the equals() vs. == discussion? </l...
Item 6 <ul><li>Use “hook points” to inject optimization, customization, or new functionality </li></ul><ul><ul><li>Hookpoi...
Item 7 <ul><li>Be robust in the face of failure </li></ul><ul><ul><li>&quot;Stuff happens&quot;: Code must deal gracefully...
Item 8 <ul><li>Define performance and scalability goals </li></ul><ul><ul><li>Every project has performance and scalabilit...
Item 9 <ul><li>Restrict EJB to transactional processing </li></ul><ul><ul><li>Contrary to popular belief, it  is  legal to...
Item 10 <ul><li>Never optimize without profiling first </li></ul><ul><ul><li>Remember the 80/20 rule </li></ul></ul><ul><u...
Item 11 <ul><li>Recognize the cost of vendor-neutrality </li></ul><ul><ul><li>Much of Java’s marketing based on “vendor ne...
Item 12 <ul><li>Build in monitoring support </li></ul><ul><ul><li>How do we know the application is still running? </li></...
Item 13 <ul><li>Build in administration support </li></ul><ul><ul><li>Enterprise apps often need administration </li></ul>...
Item 14 <ul><li>Make deployment as simple as possible </li></ul><ul><ul><li>Shipping is a feature, too! </li></ul></ul><ul...
Conclusion <ul><li>Not everything is cut-and-dried answers </li></ul><ul><ul><li>Many of these items contradict one anothe...
Credentials <ul><li>Who is this guy? </li></ul><ul><ul><li>Independent consultant and mentor </li></ul></ul><ul><ul><li>Sp...
Upcoming SlideShare
Loading in …5
×

EffectiveJava1.ppt (760.5 KB) - Interoperability Happens

347 views
297 views

Published on

Published in: Technology, Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
347
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
12
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

EffectiveJava1.ppt (760.5 KB) - Interoperability Happens

  1. 2. Introduction <ul><li>Building enterprise applications is hard </li></ul><ul><ul><li>state management </li></ul></ul><ul><ul><li>communications </li></ul></ul><ul><ul><li>lookup </li></ul></ul><ul><ul><li>resource management </li></ul></ul><ul><ul><li>security </li></ul></ul><ul><ul><li>and all this before we even get to the real problem domain! </li></ul></ul>
  2. 3. “Enterprise” <ul><li>An enterprise system is one which … </li></ul><ul><ul><li>… shares some or all resources used </li></ul></ul><ul><ul><li>… is intended for internal (or mostly internal) use </li></ul></ul><ul><ul><li>… must work within existing architecture </li></ul></ul><ul><ul><li>… will be deployed and maintained by internal IT staff </li></ul></ul><ul><ul><li>… requires greater robustness </li></ul></ul><ul><ul><li>… must fail gracefully (if it does fail) </li></ul></ul><ul><ul><li>… must gracefully handle evolution over time </li></ul></ul>
  3. 4. Topics <ul><li>Architecture </li></ul><ul><ul><li>“ Big Picture” topics </li></ul></ul><ul><li>Communication </li></ul><ul><ul><li>Schlepping data from program A to program B </li></ul></ul><ul><li>Processing </li></ul><ul><ul><li>The “real work” of the system </li></ul></ul><ul><li>State Management </li></ul><ul><ul><li>Maintaining data across requests and reboots </li></ul></ul><ul><li>Presentation </li></ul><ul><ul><li>What the user sees, and when </li></ul></ul><ul><li>Security </li></ul><ul><ul><li>What the user doesn’t see, and shouldn’t </li></ul></ul><ul><li>System </li></ul><ul><ul><li>The platform beneath the platform </li></ul></ul>
  4. 5. Architecture <ul><li>Enterprise architecture: a vision for the design and implementation of your enterprise components </li></ul><ul><ul><li>Guides and influences design </li></ul></ul><ul><ul><li>Dictates component interoperability approaches </li></ul></ul><ul><li>Architecture lays down groundwork for success </li></ul><ul><ul><li>Hard to achieve success if architecture blows </li></ul></ul><ul><ul><li>Architecture defines how J2EE components interact: </li></ul></ul><ul><ul><ul><li>Topology </li></ul></ul></ul><ul><ul><ul><li>Coarse component design </li></ul></ul></ul><ul><ul><ul><li>Interaction policies </li></ul></ul></ul><ul><ul><ul><li>… and so on </li></ul></ul></ul><ul><ul><li>Architecture, unlike code, is hard to refactor effectively </li></ul></ul><ul><ul><li>So think critically about how your J2EE system is architected </li></ul></ul>
  5. 6. Item 1 <ul><li>Prefer components as the key element of development, deployment and reuse </li></ul><ul><ul><li>Objects were supposed to enable “tinkertoy programming” </li></ul></ul><ul><ul><li>Objects failed—effective reuse never really happened to a large scale (beyond a single framework) </li></ul></ul><ul><ul><ul><li>Reuse-via-inheritance doesn’t work (Fragile Base Class) </li></ul></ul></ul><ul><ul><ul><li>Classes sometimes tightly couple (Iterators) </li></ul></ul></ul><ul><ul><li>Components: binary unit of independent development, deployment and production, defined by contract </li></ul></ul><ul><ul><ul><li>Enables composition , which provides better reuse </li></ul></ul></ul><ul><ul><ul><li>Examples: Servlet tag libraries, Servlet web apps, etc. </li></ul></ul></ul><ul><ul><li>Several Java practices already lead you towards components </li></ul></ul><ul><ul><ul><li>Effective Java : Items 1, 14, 15, 16, 34 </li></ul></ul></ul>
  6. 7. Item 2 <ul><li>Prefer loose coupling across component boundaries </li></ul><ul><ul><li>Coupling is the degree of interconnectedness of any two “things” in the system </li></ul></ul><ul><ul><ul><li>if changing one means changing the other: tight coupling </li></ul></ul></ul><ul><ul><ul><li>not to be confused with “late bound” or “loosely typed” code </li></ul></ul></ul><ul><ul><li>Loose coupling protects against change/evolution </li></ul></ul><ul><ul><ul><li>for example, RPC/interface-based designs reduce coupling, but they don’t eliminate it entirely </li></ul></ul></ul><ul><ul><ul><li>refactoring isn’t an answer here: refactoring assumes you own both ends </li></ul></ul></ul><ul><ul><ul><li>seek approaches that will keep assumptions to a minimum </li></ul></ul></ul><ul><ul><li>Tight coupling is not bad, so long as the tightly-coupled parts aren’t expected to evolve independently </li></ul></ul><ul><ul><ul><li>such as within a component (e.g., collection class + Iterator) </li></ul></ul></ul><ul><ul><ul><li>across components, however, it can be death to the system </li></ul></ul></ul>
  7. 8. Item 3 <ul><li>Differentiate layers from tiers </li></ul><ul><ul><li>&quot; N -tier systems are better than 2-tier systems&quot;; why? </li></ul></ul><ul><ul><ul><li>Network access hurts performance </li></ul></ul></ul><ul><ul><ul><ul><li>yet n -tier systems double the number of network traversals </li></ul></ul></ul></ul><ul><ul><ul><li>So why do this? </li></ul></ul></ul><ul><ul><ul><ul><li>Connection pooling </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Centralization of logic </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Easier deployment </li></ul></ul></ul></ul><ul><ul><ul><li>Question: can I get the best of both worlds? </li></ul></ul></ul><ul><ul><li>Tiers are physical nodes in the network; layers are logical separations of related functionality </li></ul></ul><ul><ul><ul><li>Don't assume business logic ( layer ) must be on middle tier </li></ul></ul></ul><ul><ul><ul><li>Not all business logic can rest in the middle (ex: input validation) </li></ul></ul></ul><ul><ul><ul><li>Browser-servlet-database arrangement is 3 tiers, by the way </li></ul></ul></ul>
  8. 9. Item 4 <ul><li>Keep data and processors close together </li></ul><ul><ul><li>Reason: Obtaining data is often not a free action </li></ul></ul><ul><ul><ul><li>Network access significantly slower (see Item 17) </li></ul></ul></ul><ul><ul><li>Keep data close to processors </li></ul></ul><ul><ul><ul><li>Avoid flagrantly fetching or storing data remotely </li></ul></ul></ul><ul><ul><ul><li>Cache data to avoid having to re-fetch it </li></ul></ul></ul><ul><ul><ul><li>Store data locally (in-proc or local file) to avoid network access </li></ul></ul></ul><ul><ul><ul><li>Be wary of cache-concurrency problems </li></ul></ul></ul><ul><ul><ul><li>Be wary of cache-identity concerns </li></ul></ul></ul><ul><ul><li>Keep processors close to data </li></ul></ul><ul><ul><ul><li>If we can't bring the data to the code, bring the code to the data </li></ul></ul></ul><ul><ul><ul><li>Use stored procs to execute code in the same process as data </li></ul></ul></ul><ul><ul><ul><li>Run Java code in JVM inside RDBMS (Oracle, DB/2, etc.) </li></ul></ul></ul><ul><ul><ul><li>Avoids the cache-identity and cache-concurrency problems </li></ul></ul></ul>
  9. 10. Item 5 <ul><li>Remember that identity breeds contention </li></ul><ul><ul><li>Remember the equals() vs. == discussion? </li></ul></ul><ul><ul><ul><li>that was a demonstration of object identity vs. equivalence </li></ul></ul></ul><ul><ul><ul><li>in single-VM systems, identity is implicit ( this ) </li></ul></ul></ul><ul><ul><ul><li>this creates potential complications in enterprise systems, as the identity requirement creates bottlenecks </li></ul></ul></ul><ul><ul><ul><li>identity shows up in other scenarios, e.g., databases </li></ul></ul></ul><ul><ul><ul><li>identity also becomes crucial in distributed objects </li></ul></ul></ul><ul><ul><li>In order to protect data against corruption, we need to restrict access by multiple users to a given thing </li></ul></ul><ul><ul><ul><li>thing == object, row, whatever </li></ul></ul></ul><ul><ul><ul><li>identity requires synchronization </li></ul></ul></ul><ul><ul><ul><li>synchronization breeds contention </li></ul></ul></ul><ul><ul><ul><li>contention is the enemy of scalability </li></ul></ul></ul><ul><ul><li>Avoid identity at all costs—often equivalence is sufficient </li></ul></ul>
  10. 11. Item 6 <ul><li>Use “hook points” to inject optimization, customization, or new functionality </li></ul><ul><ul><li>Hookpoints are places in the system designed to bypass/augment normal processing </li></ul></ul><ul><ul><ul><li>Performance optimizations </li></ul></ul></ul><ul><ul><ul><li>Security enhancement </li></ul></ul></ul><ul><ul><ul><li>Out-of-band information (extensions) </li></ul></ul></ul><ul><ul><li>Most J2EE specs offer standardized hook points (except EJB) </li></ul></ul><ul><ul><ul><li>J2SE Dynamic Proxies </li></ul></ul></ul><ul><ul><ul><li>Servlet filters </li></ul></ul></ul><ul><ul><ul><li>CORBA Interceptors </li></ul></ul></ul><ul><ul><ul><li>JMS Filters </li></ul></ul></ul><ul><ul><li>Interception adds services to opaque components </li></ul></ul><ul><ul><ul><li>&quot;hijacks&quot; the caller’s thread prior to component invocation </li></ul></ul></ul><ul><ul><ul><li>provides service on way in and/or back out </li></ul></ul></ul><ul><ul><ul><li>allows call to continue (or not) as appropriate </li></ul></ul></ul><ul><ul><li>Requires you build strong encapsulation boundary (components!) </li></ul></ul><ul><ul><ul><li>clients only interact with interfaces </li></ul></ul></ul><ul><ul><ul><li>clients use factory to obtain instances of interfaced objects </li></ul></ul></ul>
  11. 12. Item 7 <ul><li>Be robust in the face of failure </li></ul><ul><ul><li>&quot;Stuff happens&quot;: Code must deal gracefully with exceptions </li></ul></ul><ul><ul><ul><li>Don't just &quot;catch-and-log&quot; </li></ul></ul></ul><ul><ul><ul><li>Deal with exceptions as they were intended: </li></ul></ul></ul><ul><ul><ul><ul><li>SQLExceptions: database failure </li></ul></ul></ul></ul><ul><ul><ul><ul><li>RemoteExceptions: network failure </li></ul></ul></ul></ul><ul><ul><ul><ul><li>EJBExceptions: container failure (never catch!) </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Application exceptions: user did something wrong (always catch!) </li></ul></ul></ul></ul><ul><ul><ul><li>JSP, servlets, JMS, all need to handle exceptions gracefully </li></ul></ul></ul><ul><ul><li>Plan on dealing with failure: </li></ul></ul><ul><ul><ul><li>How will you patch production code? </li></ul></ul></ul><ul><ul><ul><li>How will you recover from database or network failure? </li></ul></ul></ul><ul><ul><ul><li>How will you deal with OutOfMemoryErrors? </li></ul></ul></ul><ul><ul><ul><li>How will you deal with users bookmarking web pages? </li></ul></ul></ul><ul><ul><li>Thinking about failure up front yields better robustness </li></ul></ul><ul><ul><ul><li>In other words, have a unified &quot;problem strategy&quot; </li></ul></ul></ul><ul><ul><li>Not all failures can be solved in code; solve what you can </li></ul></ul>
  12. 13. Item 8 <ul><li>Define performance and scalability goals </li></ul><ul><ul><li>Every project has performance and scalability goals </li></ul></ul><ul><ul><ul><li>usually defined in terms like “Make it run fast” </li></ul></ul></ul><ul><ul><ul><li>… which is not exactly a quantifiable goal! </li></ul></ul></ul><ul><ul><li>Definitions </li></ul></ul><ul><ul><ul><li>Performance: time for single client to complete </li></ul></ul></ul><ul><ul><ul><li>Scalability: add more user capacity by adding hardware </li></ul></ul></ul><ul><ul><li>Most “performance” problems are scalability problems, due to excessive contention for locked resources </li></ul></ul><ul><ul><ul><li>look for ways to improve scalability (to desired levels) </li></ul></ul></ul><ul><ul><ul><li>… reducing performance if necessary! </li></ul></ul></ul><ul><ul><ul><li>recognize that user perception is more important than reality </li></ul></ul></ul>
  13. 14. Item 9 <ul><li>Restrict EJB to transactional processing </li></ul><ul><ul><li>Contrary to popular belief, it is legal to do J2EE without EJB </li></ul></ul><ul><ul><ul><li>In fact, it's desirable in places (&quot;Fast Lane Pattern&quot;) </li></ul></ul></ul><ul><ul><li>Problem: EJB was oversold </li></ul></ul><ul><ul><ul><li>Part of EJB was to make distributed systems simpler </li></ul></ul></ul><ul><ul><ul><li>4 .java files + deployment descriptor + EJBQL != “simpler”! </li></ul></ul></ul><ul><ul><ul><li>Requires tremendous intellectual investment to use </li></ul></ul></ul><ul><ul><li>Main benefit of EJB: transactional processing </li></ul></ul><ul><ul><ul><li>In particular, distributed transactions are easy with EJB </li></ul></ul></ul><ul><ul><ul><li>Auto-enlistment of resource managers </li></ul></ul></ul><ul><ul><ul><li>Auto-commit or –rollback, based on component voting </li></ul></ul></ul><ul><ul><li>Don’t rely on EJB to provide scalability or performance </li></ul></ul><ul><ul><ul><li>EJB can’t solve those problems: that’s what YOU do </li></ul></ul></ul>
  14. 15. Item 10 <ul><li>Never optimize without profiling first </li></ul><ul><ul><li>Remember the 80/20 rule </li></ul></ul><ul><ul><li>You don’t know what the 20% of the code is </li></ul></ul><ul><ul><ul><li>you may think you know... </li></ul></ul></ul><ul><ul><ul><li>... but the fact is most developers’ intuition sucks </li></ul></ul></ul><ul><ul><ul><li>Add in the fact that the JIT can silently add optimizations </li></ul></ul></ul><ul><ul><li>Use the profiler to find the bottlenecks, not source code </li></ul></ul><ul><ul><li>Once you find bottlenecks, use hook points (Item 4) to fix </li></ul></ul><ul><ul><li>Remember that profiling carries its own cost, too </li></ul></ul><ul><ul><ul><li>Heisenburg's Uncertainty Principle plays into all of this </li></ul></ul></ul><ul><ul><ul><li>so take a broad sample of profiled data before optimizing </li></ul></ul></ul>
  15. 16. Item 11 <ul><li>Recognize the cost of vendor-neutrality </li></ul><ul><ul><li>Much of Java’s marketing based on “vendor neutrality” </li></ul></ul><ul><ul><li>Critical question: Do you care? Do you need it? </li></ul></ul><ul><ul><li>Vendors offer numerous positive enhancements </li></ul></ul><ul><ul><ul><li>Using them forces code changes when platforms change </li></ul></ul></ul><ul><ul><ul><li>Using them improves performance, scalability, etc. </li></ul></ul></ul><ul><ul><li>Writing “vendor-neutral” code means sticking to spec: </li></ul></ul><ul><ul><ul><li>No file I/O access from inside EJBs </li></ul></ul></ul><ul><ul><ul><li>No exclusivity assumption for entity beans </li></ul></ul></ul><ul><ul><ul><li>No vendor value-added extensions of any kind </li></ul></ul></ul><ul><ul><li>Make your choice deliberately: portability, or performance </li></ul></ul><ul><ul><ul><li>In many cases, this will be a hybrid answer </li></ul></ul></ul><ul><ul><ul><li>There is no right-or-wrong answer here! </li></ul></ul></ul>
  16. 17. Item 12 <ul><li>Build in monitoring support </li></ul><ul><ul><li>How do we know the application is still running? </li></ul></ul><ul><ul><ul><li>Need some way of knowing when the application is failing </li></ul></ul></ul><ul><ul><ul><li>Unless you want your clients to be your signal, of course… </li></ul></ul></ul><ul><ul><li>Quick diagnostic tool necessary to know if system is working </li></ul></ul><ul><ul><ul><li>&quot;the Happy Page&quot;: a single round-trip test of the system </li></ul></ul></ul><ul><ul><ul><li>ping the database server, query the database instance, get the version # </li></ul></ul></ul><ul><ul><ul><li>ping the middleware server, call a component, get the version #, etc </li></ul></ul></ul><ul><ul><li>Diagnostic logging gives window on what's happening </li></ul></ul><ul><ul><ul><li>Log to someplace fast for diagnostics, log to files for archival purposes </li></ul></ul></ul><ul><ul><ul><li>Make sure to log at different levels: logging isn't free </li></ul></ul></ul><ul><ul><ul><li>Make sure to make log levels component-centric and hot-configurable </li></ul></ul></ul><ul><ul><li>Performance counters track how the system is performing </li></ul></ul><ul><ul><ul><li>Java Management Extensions (JMX) were designed for this </li></ul></ul></ul><ul><ul><ul><li>O/S-specific tools can also provide some good insights </li></ul></ul></ul><ul><ul><li>Diagnostics make everybody happy: managers & coders both </li></ul></ul>
  17. 18. Item 13 <ul><li>Build in administration support </li></ul><ul><ul><li>Enterprise apps often need administration </li></ul></ul><ul><ul><ul><li>Configuration, control, problem resolution, etc. </li></ul></ul></ul><ul><ul><ul><li>Could use tools specific to each technology (SQL console, etc) </li></ul></ul></ul><ul><ul><ul><li>But this creates complex configuration that admins must learn </li></ul></ul></ul><ul><ul><li>Create an administrative console for config & control </li></ul></ul><ul><ul><li>Configuration </li></ul></ul><ul><ul><ul><li>Existing solutions: Properties, database, LDAP, all have issues </li></ul></ul></ul><ul><ul><ul><li>Deployment descriptors try to solve some of this, but… </li></ul></ul></ul><ul><ul><ul><li>Preferences (java.util.prefs) try provide unifying solution </li></ul></ul></ul><ul><ul><ul><li>Requires a user interface for admin use, which you build </li></ul></ul></ul><ul><ul><ul><li>You'll need a UI for control operations anyway, so unify them </li></ul></ul></ul><ul><ul><li>Control </li></ul></ul><ul><ul><ul><li>Fixing &quot;lost in the system&quot; errors </li></ul></ul></ul><ul><ul><ul><li>User management (adding, removing, etc) </li></ul></ul></ul>
  18. 19. Item 14 <ul><li>Make deployment as simple as possible </li></ul><ul><ul><li>Shipping is a feature, too! </li></ul></ul><ul><ul><li>Many developers are not allowed access to production servers </li></ul></ul><ul><ul><ul><li>This means sysadmins are doing deployments </li></ul></ul></ul><ul><ul><ul><li>Sysadmins typically aren't Java developers, and don't know J2EE </li></ul></ul></ul><ul><ul><ul><li>Deployment is usually vendor-specific </li></ul></ul></ul><ul><ul><li>Think about all that's needed to deploy your application </li></ul></ul><ul><ul><ul><li>.jar/.war files </li></ul></ul></ul><ul><ul><ul><li>JRE installation </li></ul></ul></ul><ul><ul><ul><li>Database schema changes/updates </li></ul></ul></ul><ul><ul><ul><li>Database data (lookup tables, etc) </li></ul></ul></ul><ul><ul><ul><li>Network configurations </li></ul></ul></ul><ul><ul><li>Ant can go a long way towards helping here: a single script can do both builds and deployment </li></ul></ul><ul><ul><ul><li>or give admins their own deployment-only script </li></ul></ul></ul>
  19. 20. Conclusion <ul><li>Not everything is cut-and-dried answers </li></ul><ul><ul><li>Many of these items contradict one another in places </li></ul></ul><ul><ul><ul><li>Certain items will apply in certain situations </li></ul></ul></ul><ul><ul><ul><li>Everything is context-dependent </li></ul></ul></ul><ul><ul><ul><li>That’s what makes it fun!  </li></ul></ul></ul><ul><ul><li>In all things, be a little cynical </li></ul></ul><ul><ul><ul><li>If your experience seems to contradict the book, experiment! </li></ul></ul></ul><ul><ul><ul><li>Just because it’s written in a book doesn’t make it right </li></ul></ul></ul><ul><ul><li>Keep an eye on future developments </li></ul></ul><ul><ul><ul><li>Much of what’s here applies to Spring, Hibernate, .NET, … </li></ul></ul></ul><ul><ul><ul><li>J2EE continues to evolve as well </li></ul></ul></ul>
  20. 21. Credentials <ul><li>Who is this guy? </li></ul><ul><ul><li>Independent consultant and mentor </li></ul></ul><ul><ul><li>Speaker </li></ul></ul><ul><ul><ul><li>TechEd, No Fluff Just Stuff, VSLive!, JavaOne, and others </li></ul></ul></ul><ul><ul><li>Java Community Process EG member (JSR 175, 250, …) </li></ul></ul><ul><ul><li>Author </li></ul></ul><ul><ul><ul><li>Effective Enterprise Java (Addison-Wesley, 2004) </li></ul></ul></ul><ul><ul><ul><li>Server-Based Java Programming (Manning, 2000) </li></ul></ul></ul><ul><ul><ul><li>C# in a Nutshell (with Drayton, Albahari; OReilly, 2001) </li></ul></ul></ul><ul><ul><ul><li>SSCLI Essentials (with Stutz, Shilling; OReilly, 2003) </li></ul></ul></ul><ul><ul><ul><li>Papers at www.neward.net/ted/Papers </li></ul></ul></ul><ul><ul><ul><li>Weblog at www.neward.net /ted/weblog </li></ul></ul></ul>

×