|
Project Wonder 2.0 | ||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object er.extensions.ERXCompilerProxy
ERXCompilerProxy is a class that creates a rapid-turnaround mode for WebObjects
5 for Java similar to how you use WebScript with WO 4.5.1.
Instead of recompiling your Application or Frameworks, you simply change the source code in question and reload your page. In some cases, you may also have to restart your Application but you won't have to rebuild it.
ERXCompilerProxy is especially well suited for DirectToWeb applications. The restrictions of Java's classloading are partially compensated by the highly dynamic nature of D2W apps.
Check if you have jikes
installed in /usr/bin
. On
Windows, install jikes.exe
in $NEXT_ROOT/Local/Library/Executables/
To use this framework you must complete a few easy steps and you will very seldom have to rebuild or even restart your project again:
~/WebObjects.properties
file add a line
er.extensions.ERXCompilerProxyEnabled=true
CPFileList.txt
in your
project's and your framework's root directory. This file should contain lines
with "./project_relative_path_to_Someclass.java:package_of_SomeClass_or_empty<return>
"
for every file you want to get recompiled. On Windows, this is currently your
only option unless someone writes a shell script that mimics what the supplied
unix script does (find all java classes under the project root, grep for package
and class names and put it into a CPFileList.txt
file)
sh "${TARGET_BUILD_DIR}/ERExtensions.framework/Resources/InstallCompilerProxySupport.sh"
CPFileList.txt
file.The ERXCompilerProxy does several things to works it's magic. First, on startup,
it registers for the ApplicationDidFinishLaunching
Notification.
When the App starts, it reads the CPFileList.txt
files from your
currently opened projects to find out about the files to watch. So remember
to have your framework projects open in PB.
It also registers for the ApplicationWillDispatchRequest
Notification,
which gets triggered whenever a page is requested. It tries to compile the files
that have changed and throws an Exception describing the errors if there where
any and then aborts further handling of the request - you will get an error
from your browser. However, if everything went well, it creates a new ClassLoader
and throws away the component definition cache and a few other things. Then,
when the next "pageWithName" is called, the updated class will be used.
This is slightly different from how WebScript handled things. In Java, you simply can't change an Object's class implementation at runtime - so if you already have a page (or any other Object) this object will not use the newer class. Only Objects created after the compilation will have new behaviour.
The freshly compiled files will be put into your App's Resources/Java
directory into the proper package hierarchy. So, if you simply restart your
App, the newer files will be used. When you re-build your project, your normal
.jar
will contains the correct classes anyway.
NOTE: Since all new class files end up in Resources/Java
,
when you clean-build your App, you also need to recompile your frameworks when
you have changed classes there! A normal build will not delete the files, so
recompilation of the frameworks is not needed.
"IllegalAccess in KeyValueCodingProtectedAccessor"
.
You will probably have defined a new variable in your component with protected
access. Either set the scope of the variable to public or restart your app.
The number of these messages is greatly reduced if your components and EOs
are in a package hierarchy and you have a KeyValueCodingProtectedAccessor
subclass for this package.
CompilerProxyDidCompileClassesNotification
and reset the cache when you recieve it.
public WOComponent detailsAction() { Details newPage = (Details)pageWithName("Details"); newPage.setObject(currentObject); return newPage; }
public WOComponent detailsAction() { WOComponent newPage = pageWithName("Details"); newPage.takeValueForKey(currentObject, "object"); return newPage; }
Field Summary | |
protected String |
_className
|
protected static String |
_classPath
Holds the classpath of the current app. |
protected static ERXCompilerProxy |
_defaultProxy
Holds the Compilerproxy singleton |
protected String |
_destinationPath
Holds the path where the compiled .class files go.
|
protected NSMutableDictionary |
_filesToWatch
Holds the files to watch. |
protected static String |
_jikesPath
Path to the jikes binary. |
protected NSArray |
_projectSearchPath
|
protected static boolean |
_raiseOnError
Holds a boolean that tells wether an error should raise an Exception or only log the error. |
protected NSMutableSet |
classFiles
Currently compiled classes. |
protected static ERXLogger |
classLoaderLog
|
static String |
CompilerProxyDidCompileClassesNotification
Notification you can register to when the Compiler Proxy reloads classes. |
protected static String |
CPFileList
denotes the name of file which describes in each line a path to java class to watch for. |
protected boolean |
initialized
|
protected static ERXLogger |
log
|
Constructor Summary | |
ERXCompilerProxy()
Contructor - does nothing special. |
Method Summary | |
void |
checkAndCompileOnNotification(NSNotification theNotification)
Method that will be called upon ApplicationWillDispatchRequest . |
Class |
classForName(String className)
Returns the class registered for the name className . |
static ERXCompilerProxy |
defaultProxy()
Returns the Compiler Proxy Singleton. |
void |
initialize()
Initializes the CopilerProxy singleton. |
static boolean |
isClassContainedBySet(String classNameWithPackage,
NSSet cacheEntries)
Tests whether or not the class name with package is contained in the set of CacheEntry objects. |
protected String |
pathForCPFileList(String directory)
|
String |
projectInSearchPath(String bundleName)
Returns an array of paths to the opened projects that have a CPFileList.txt . |
protected NSArray |
projectPaths()
|
void |
setClassForName(Class clazz,
String className)
Sets the class registered for the name className to the given class. |
static void |
setDefaultProxy(ERXCompilerProxy p)
|
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
protected static final ERXLogger log
protected static final ERXLogger classLoaderLog
public static final String CompilerProxyDidCompileClassesNotification
protected static final String CPFileList
protected static String _jikesPath
protected static ERXCompilerProxy _defaultProxy
protected static String _classPath
protected static boolean _raiseOnError
protected boolean initialized
protected NSMutableDictionary _filesToWatch
protected String _className
protected String _destinationPath
.class
files go.
Default is Contents/Resources/Java
.
protected NSMutableSet classFiles
protected NSArray _projectSearchPath
Constructor Detail |
public ERXCompilerProxy()
Method Detail |
public static ERXCompilerProxy defaultProxy()
public static void setDefaultProxy(ERXCompilerProxy p)
protected String pathForCPFileList(String directory)
public String projectInSearchPath(String bundleName)
CPFileList.txt
.NSProjectSearchPath
to the paths to your projects:
(/Users/ak/Wonder/Common/Frameworks,/Users/Work)
will look for directories with a CPFileList.txt in all loaded bundles.
So when you link to ERExtensions.framework
,
/Users/ak/Wonder/Common/Frameworks/ERExtensions
will get found.
protected NSArray projectPaths()
public Class classForName(String className)
className
.
className
- class name
public void setClassForName(Class clazz, String className)
className
to the given class.
clazz
- class objectclassName
- name for the class - normally clazz.getName()public void initialize()
public void checkAndCompileOnNotification(NSNotification theNotification)
ApplicationWillDispatchRequest
.#checkAndCompileOnNotification()
theNotification
- notification sent upon
ApplicationWillDispatchRequestpublic static boolean isClassContainedBySet(String classNameWithPackage, NSSet cacheEntries)
classNameWithPackage
- string of the class namecacheEntries
- NSSet contains CacheEntry objects;
typically obtained by a notification's object() method
|
Last updated: Do, Dez 9, 2004 12:46 PM CET | ||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |