Title: Dynamic Programming In the Java Platform
1Dynamic Programming In the Java Platform
2Overview
- Static Dynamic Binding
- Reflection
- Proxy
- Scripting
- Misc
- Q A
3Static Dynamic Binding
4Definitions
- Binding (or linking) is the process by which
symbols are resolved to physical addresses in the
machine. - Static (or early) binding tries to resolve a
symbol to an address during compilation. - Dynamic (or late) binding tries to resolve a
symbol to an address while the program is running.
5Static Binding - Advantages
- The cost of resolving the symbol to an address is
done once at compile-time - Because essentially everything about the program
is known at compile-time, the compiler is able to
do some very sophisticated optimizations - Tools (eg, IDEs) can know everything about the
code, making it easier for tool builders to
provide very nice features like code completion
and static analysis (FindBugs, PMD, etc.)
6Static Binding - Disadvantages
- The cost of compiling can be huge, since
everything even code thats never actually used
has to be linked - The incremental drag on developer productivity is
virtually impossible to overstate - The compiler doesnt have any information about
the actual runtime environment in which the
program is running - It may make bad assumptions
- It cant make assumptions that may be perfect for
how the program is being used - Its much harder to add new capabilities to an
installed program, so everything needs to be
redeployed
7Dynamic Binding - Advantages
- The cost of compiling is much lower, allowing for
much faster development - Because the runtime linker knows more about the
current state of the program, it can reorder the
memory and resources more easily - The runtime linker can resolve symbols to
addresses that may not be known about (or even
exist) at compile-time (eg, remote resources),
making it ideal for networked systems and other
heterogeneous environments - Allows for the sharing of common resources rather
than duplicating it in each executable (eg,
system DLLs)
8Dynamic Binding - Disadvantages
- The cost of resolving the symbol to an address is
done every time the program is run - Its more difficult to know ahead of time that
the resource actually exists, or that youll get
the resource youre expecting - Common examples JavaScript that doesnt complain
about an undeclared variable until its in
production DLL Hell
9Myths Reflection is slow
- Reflection and its kin has a performance cost
rapidly approaching zero when used properly - As evidenced by some of the following example
products/libraries that use reflection
extensively, even if the cost is a hundred times
the cost of a static call, it is still marginal
compared to the operations it is supporting (and
makes everyones life much easier)
10Myths But you loose type safety
- While static type checking can check for the
existence of a method on an objects type, thats
about all it can do - Sometimes that can be a significant disadvantage
- For any non-trivial/naïve understanding of
correctness for the code, static type checking
provides virtually nothing. Correctness can only
be verified by unit tests, which provides the
same function as a side-effect - Design By Contract can be a bit of an exception
to this, but that is arguably a unit test in the
production code - See Bruce Eckels Strong Typing vs. Strong
Testing - http//mindview.net/WebLog/log-0025
11Myths You cant refactor
- While common-sense would seem to say that you
need static typing/binding for tools to do things
like refactoring, thats clearly not true.
Refactoring as a formal development practice
comes from the Smalltalk world, where the IDEs
provided extensive refactoring support before
Java even existed.
12Which Is Better?
- Like so many things, the answer is It depends
- In static environments or when the best possible
performance is essential (e.g. device drivers),
static binding is the only way to go - The more dynamic/complex the system is, or when
the developers time is more important than the
computers, then dynamic wins - Most modern systems are hybrids, statically
linking for performance, but pushing that step
off to as late as possible
13Examples - JUnit
- Reflection is used to prevent the need to create
- public static TestSuite suite()
- TestSuite suite new TestSuite()
- suite.addTest(new Test()
- public int countTestCases()
- return 1
-
- public void run(TestResult testResult)
- SimpleAppTests tests new
SimpleAppTests("aTestMethod") - tests.setUp()
- try
- testResult.startTest(this)
- try
- tests.aTestMethod()
-
- catch (AssertionFailedError e)
- testResult.addFailure(this, e)
-
14Examples JSP
- Old JSPs give the feeling of dynamic, while
still being quite static. (eg, When the page is
refreshed, the page is converted to static Java
and compiled.) - TagLibs (like JSTL) must be precompiled
- New JSPs have taken a more dynamic approach,
which is why EL (Expression Language) has been
rolled into the spec. - EL requires the use of reflection to do JavaBean
lookups and dereferencing
15Examples Hibernate
- In your code you deal with domain models
statically (ie, you code against a particular
class definition) - Behind the scenes, there is a lot of reflection
happening to intercept method calls, extract and
populate values from the models, convert things
to the needed SQL, etc.
16Examples Spring
- The poster-child for the power of dynamic
programming in a static environment - The BeanFactory uses Reflection to create the
objects, populate the values, etc. - AOP is provided entirely via proxies (in Spring
1.x), which is an extreme use of Reflection. - AOP is how Spring provides most of its magic,
like JNDI lookups, security, hot-swappable
services, etc.
17Reflection
18What Is Reflection?
- Reflection is the ability of a program to examine
itself and its environment at runtime and modify
its behavior accordingly. - Meta-data provides the capability for a program
to introspect itself and other objects in the
system, allowing dynamic invoking or changing of
that code.
19JavaBeans Definition
- While the formal specification for what is a
JavaBean is a little complex (a classic case of
over-engineering), in practice a JavaBean is a
class that - Has a public no-argument constructor
- Has public getter and setter methods
- getter methods return a non-void value and have
no arguments - setter methods return void and have a single
argument
20JavaBeans Example class
- package myco
- public class Person
- private String personFirstName
- public Person()
-
- public void setFirstName(String newName)
- this.personFirstName newName
-
- public String getFirstName()
- return this.personFirstName
-
21JavaBeans Example usage
- ltbean id"dude" class"myco.Person"gt
- ltproperty name"firstName" value"Jim"/gt
- lt/beangt
- Becomes, at runtime, roughly the same as
- myco.Person dude new myco.Person()
- dude.setFirstName("Jim")
22But What It Is Actually Doing Is
- myco.Person dude new myco.Person()
- dude.setFirstName("Jim")
- Is implemented via reflection as (roughly)
- Class personClass Class.forName("myco.Person")
- Method setNameMethod theClass.getMethod("setName
", new Object String.class) - Object dude personClass.newInstance()
- setNameMethod.invoke(dude, "Jim")
23BeanInfo and Introspector
- BeanInfo is part of the standard API for
JavaBeans, providing a cached description of the
methods, properties, etc of a bean - Its typically retrieved for a Class by using
Introspector.getBeanInfo(MyClass.class) - If a class provides an explicit BeanInfo
implementation (for fine-grained control) then
that is used - If one is not explicitly provided, it is
dynamically created by inspecting the class
24Proxy
25JDK 1.3 Proxy
- Implements one or more arbitrary interfaces
- CGLib and similar libraries add the ability to
proxy classes, within the limits dictated by the
language - Can be used as a façade (wrapping and extending
functionality, such as adding security) or a true
proxy (passing everything off to logic that
dynamically determines what to do with the call)
26Example Call Logging traditional
- public class RemotePersonServiceStub
- private static final Logger LOG
Logger.getLogger(RemotePersonServiceStub.class) - // ... set things up ...
- public PersonDto getPerson(long id)
- final long start System.currentTimeMillis()
- LOG.info("Calling PersonDto getPerson(long)
with "id"") - try
- // ... make remote call ...
-
- finally
- final long stop System.currentTimeMillis()
- final double diff (double)(stop - start)
- LOG.info("Method call for getPerson took "
(diff / 1000.0) " sec") -
-
- public PersonDto getPersonByFirstNameAndLastName
(String firstName, String lastName) - final long start System.currentTimeMillis()
- LOG.info("Calling PersonDto
getPersonByFirstNameAndLastName(String,String)
with " firstName","lastName"") - try
27Example Call Logging traditional
- public class RemotePersonServiceStub
- private static final Logger LOG
Logger.getLogger(RemotePersonServiceStub.class) - // ... set things up ...
- public PersonDto getPerson(long id)
- final long start System.currentTimeMillis()
- LOG.info("Calling PersonDto getPerson(long)
with "id"") - try
- // ... make remote call ...
-
- finally
- final long stop System.currentTimeMillis()
- final double diff (double)(stop - start)
- LOG.info("Method call for getPerson took "
(diff / 1000.0) " sec") -
-
- public PersonDto getPersonByFirstNameAndLastName
(String firstName, String lastName) - final long start System.currentTimeMillis()
- LOG.info("Calling PersonDto
getPersonByFirstNameAndLastName(String,String)
with " firstName","lastName"") - try
28Example Call Logging Dynamic Proxy
- public class CallTimeLogger implements
MethodInterceptor - public Object invoke(MethodInvocation
invocation) throws Throwable - final Logger logger Logger.getLogger(invocat
ion.getMethod().getDeclaringClass()) - final long start System.currentTimeMillis()
- try
- final Method method invocation.getMethod()
- final Object arguments
invocation.getArguments() - if (arguments null)
- logger.info("Calling " method)
- else
- final StringBuilder builder new
StringBuilder("Calling "). -
append(method).append(" with ") - argStr(method, arguments, builder)
- logger.info(builder.toString())
-
- return invocation.proceed()
-
29Scripting
30Why Scripting?
- Some things are just more naturally scripts
- Ant tasks, quick one-off programs, batch
processing - Dynamic Applications
- web view technologies are a common example,
macros, configuration, rules from a db - Productivity
- not having to recompile and reload can be a huge
timesaver when in development, syntax is much
more relaxed so less busywork, try out APIs
interactively - JSRs 223 (Scripting/BSF) and 274 (BeanShell)
31Some Major Scripting Languages for the VM
- Rhino JavaScript from Mozilla.org
- JRuby Jython let you run Ruby/Python scripts
in the Java VM (though they dont have perfect
fidelity to the mother language) - Groovy New language (under JSR 241) that is
trying to bring the lessons of Ruby to Java - BeanShell One of the oldest/mature, it trades
ease-of-use for fidelity to the Java language
32BeanShell Syntax
- Very easy to move back and forth between
BeanShell and Java because the languages are very
similar - BeanShells syntax is (essentially) a super-set
of Javas syntax
33Java Syntax in BeanShell
- // Use a Map
- Map map new HashMap()
- Date date new Date()
- map.put("today", date)
- // Print the current clock value
- print(System.currentTimeMillis())
- // Loop
- for (int i0 ilt5 i)
- print(i)
- // Pop up a frame with a button in it
- JButton button new JButton("My Button")
- JFrame frame new JFrame("My Frame")
- frame.getContentPane().add(button, "Center")
- frame.pack()
- frame.setVisible(true)
34Dynamic-Typing Java Syntax in BeanShell
- // Use a Map
- map new HashMap()
- date new Date()
- map.put("today", date)
- // Print the current clock value
- print(System.currentTimeMillis())
- // Loop
- for (int i0 ilt5 i)
- print(i)
- // Pop up a frame with a button in it
- button new JButton("My Button")
- frame new JFrame("My Frame")
- frame.getContentPane().add(button, "Center")
- frame.pack()
- frame.setVisible(true)
35Groovy SQL and XML
- import groovy.sql.Sql
- import groovy.xml.MarkupBuilder
- def sql Sql.newInstance("jdbcmysql//localhost
3306/mydb", "user", - "pswd", "com.mysql.jdbc.Driv
er") - def xml new MarkupBuilder()
- def ignore 'James'
- sql.eachRow("select from person where firstname
! ignore") person - xml.customer(idperson.id, type'Customer')
- name(person.firstname " "
person.lastname) -
-
- ltcustomersgt
- ltcustomer id"234" type"Customer"gt
- ltnamegtMichelle Taublt/namegt
- lt/customergt
36Bean Scripting Framework
- BSF provides a generic interface for scripting
languages to interact with Java programs - Originally from IBM, its now an Apache project
- JSR 223 (to be a part of Java 6) is bringing it
in to the core of the platform
37Use in Ant
- To add the ability to do BeanShell scripting in
Ant, put the bsh.jar file in ant.home/lib - ltscript language"beanshell"gtlt!CDATA //
beanshell codegtlt/scriptgt
38Ant Scripting Example
- lttarget name"copy.dist" description"Copy the
distributions to the remote servers"
depends"copy.dist.prep"gt - ltscript language"beanshell"gtlt!CDATA
- parallel project.createTask("parallel")
- // this is defined in the
"_dummy.for.copy.dist" target above - pFtp.maybeConfigure() // need to "prime"
the target - StringTokenizer tokenizer new
StringTokenizer(project.getProperties().get("deplo
y.servers"), ",") - while(tokenizer.hasMoreTokens())
- serverName tokenizer.nextToken()
- ftpTask project.createTask("progressftp"
) - ftpTask.copy(pFtp) // use pFtp as a
template - ftpTask.setServerName(serverName)
- parallel.addTask(ftpTask)
-
- parallel.execute()
- gtlt/scriptgt
- lt/targetgt
39Adding Interactive Scripting
- JFrame frame new JFrame("BeanShell")
- JConsole console new JConsole()
- Container contentPane frame.getContentPane()
- contentPane.setLayout(new GridLayout(1, 1))
- contentPane.add(console)
- frame.setBounds(100, 100, 1000, 500)
- Interpreter interpreter new Interpreter(console)
- interpreter.setShowResults(true)
- new Thread(interpreter).start()
- frame.setVisible(true)
40Misc
41Invoke-Method example from Ruby
- serviceLocation "http//127.0.0.19090/ProductSe
rvice" - service SOAPRPCDriver.new(serviceLocation)
- products service.getAllProducts()
42The Future
- Java 6 SE (aka Mustang)
- Scripting functionality (BSF) will be part of the
platform - Rhino (JavaScript) will be part of the standard
SDK - JavaC is being exposed programmatically (mostly
to support APT and annotations) - Current plans for Java 7 SE (Dolphin)
- invokedynamic byte-code will improve performance
and increase dynamic capabilities - Closures would make Java much simpler and more
object-oriented, bringing it closer to Ruby,
Python, Smalltalk, Haskel, etc.
43Q A