tag:blogger.com,1999:blog-18467253630103064632024-03-13T11:40:41.097+02:00Fred, Let it go!Mainly about Java, Open Source and the OpenJDKAnonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.comBlogger34125tag:blogger.com,1999:blog-1846725363010306463.post-10419035381518559942014-05-16T20:09:00.003+03:002014-05-16T20:09:47.556+03:00What's wrong with Chinese downloads?<div dir="ltr" style="text-align: left;" trbidi="on">
<p>Here an example of the download statistics of Groovy 2.3.0 from <a href="https://bintray.com">bintray.com</a></p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://bintray.com/groovy/maven/groovy/view/statistics" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPSCHbIAD7iqKt4LJC-RMbrjZ9Nmo8-bdGP62LpmRD5tnQvQvDz4GGiMxgb62OevLxpWlPlbmDULVjug02ByF0X9Fgtl0R7rWooczQJyR-Ts3OUk_6DIwOC18-WCUG_7LJ2Py7ToKnunDF/s320/Groovy230Downloads.png" /></a></div><br/>
<h3>Why are we receiving so many downloads from China?</h3>
<br/>
<p>Since the creation of JFrog, every time one of our user was providing popular content and downloads, we get hit by huge amount of queries from China.<br/>
We tried desperately to find a pattern in theses queries. A faulty download manager, may be the agent name will tell us how to fix this, the pattern of action, and so on.
We kind of find a way to stop this, but still every year something new appears.</p>
<p>For info, the pattern is extremely damaging to our servers. A robot of some kind is opening thousands of requests to download something, then starts to get the first few bytes, but immediately stops and keep the connection open.</p>
<p>The issue is that using smart tools on our side to find the above pattern, will block good traffic based on AJAX and long running REST API. Our products (Artifactory and Bintray) needs many parallel connections and long running HTTP sockets to work correctly. So, we are a lot more vulnerable than a standard web site.</p>
<p>Still, I keep thinking! Why people are creating theses robots? Why from China?</p>
<p><b>Than it hit me!</b></p>
<p>By running theses robots, they may force us to take the decision to complete block Chinese traffic to our servers. And if we do this, what are the consequences?</p>
<p>Chinese entrepreneurs will create the equivalent of our services inside the firewall. Then the services will run on data centers controlled by the Chinese government and under Chinese law. And we will not be able to complain or fight back.</p>
<p>At the end of the day, we are the bad guys! We unilaterally decided to block China!</p>
<p>I'm wondering if this scenario actually happened to many other website like twitter, amazon, youtube, hulu or facebook, and so paved the ground for <a href="http://www.fastcompany.com/1715042/youtube-youku-websites-and-their-chinese-equivalents">the equivalents</a> to be created inside the great firewall.</p>
<b>Am I wrong?</b>
<br /></div>Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com2tag:blogger.com,1999:blog-1846725363010306463.post-37479497180839009162011-07-05T18:43:00.002+03:002011-07-05T18:48:48.877+03:00Extended Enums usageSince the re-launch of extended enums I'm paying attention in my everyday coding (yes I still write code :) if extended enums will help me.<br />Here are 2 new examples:<br />1) I found out that most of the time the name() of the enum is not what I need. I need it to map an XML or HTML tag, an external ID, an entry name in excel or simple type name in a JSON object. So I write something like:<br /><pre><br /> public enum ConfigName {<br /> ALL("local-all"),<br /> INTERNAL("local-int"),<br /> OR("local-int-ext");<br /><br /> private final String xmlKey;<br /><br /> LdapConfig(String xmlKey) {<br /> this.xmlKey = xmlKey;<br /> }<br /><br /> public String getXmlKey() {<br /> return xmlKey;<br /> }<br /> }<br /></pre><br />I could remove the getter, and the IDE helping a lot writing the boiler plate code but why? Here is how it should look:<br /><pre> public enum ConfigName extends AlternateEnumKey {<br /> ALL("local-all"),<br /> INTERNAL("local-int"),<br /> OR("local-int-ext");<br /> }<br /></pre><br />The extra feature here is that the name() of the enum (ALL, INTERNAL, OR) is a constant that is not recognized as such by the javac compiler. So:<br /><pre> @XmlTag(tag = ConfigName.ALL)</pre><br />will not compile and so:<br /><pre> @XmlTag(tag = ConfigName.ALL.xmlKey)</pre><br />will for sure not.<br /><br />But with extended enum you'll have:<br /><pre> public @interface XmlTag { AlternateEnumKey tag(); }<br /><br /> // The framework managing XmlTag will take the alternate key value<br /> @XmlTag(tag = ConfigName.ALL)<br /></pre><br />2) Since extended enums also supports generics for enums, and I just have this issue associating also a long (ID) to an enums, you can now write:<br /><pre> public enum ConfigName extends EnumPairExtension<Long, String> {<br /> ALL(45L, "local-all"),<br /> INTERNAL(56L, "local-int"),<br /> OR(98L, "local-int-ext");<br /> }<br /><br /> assert ConfigName.OR.a == 98L;<br /></pre><br />With this, parsing definitions are a lot cleaner to write.Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com0tag:blogger.com,1999:blog-1846725363010306463.post-21400593300187113822011-06-14T15:35:00.002+03:002011-06-14T15:39:37.969+03:00A new push for extended enums!At Devoxx09, Joe Darcy presented the status and future of the Coin project, and how changes to the language are selected and implemented (or vice versa). :)<br />During his talk, he showed the cost classification of a language change: trivial, small, medium, big, or huge, and emphasized the fact that each change is also a benefit (hard to measure a priori) that can be estimated as big, medium, or small.<br />So for example, the new loop syntax introduced in Java5 was a small change with big benefits—a no "brainer", let's do it!<br /> <br />However, in his talk he showed how "Extended Enums" were at least medium cost with a small benefit.<br /> <br />I started working on "Extended Enums" (previously "abstract enum") since the release of OpenJDK and the launch of the now defunct KSL (Kitchen Sink Language) in 2006. From the amount of hits this blog is getting on "extended enums", I know this issue is of big concern for many Java developers. <br />I developed a working solution, but stopped pushing for it for two main reasons:<ul><li>This addition to the language is a change to the Java-type system. Moreover, it cannot be a small modification; it is at least a medium change.</li><li>Looking at Scala Traits or Fantom Mixin, I had the feeling that it was pushing Java too much, and perhaps in the wrong direction.</li></ul><br /> <br />So I talked with Joe Darcy at Devoxx09 about all the things I discovered implementing this change to the javac compiler (and other needed changes to the JDK classes). It was clear that the change is medium size, but I disagree that the benefits are small. <br />The benefits of "Extended enums" as implemented today:<ul><li>Ability for enum declaration to extend an actual abstract class<br />This is the evident benefit, and it is a small benefit. Using delegation and/or in-lined anonymous classes is not too verbose and provides the same benefits. Still it is nicer and cleaner to have the normal OO inheritance.</li><li>Ability to use Generics in Enum classes<br />With "Extended enums" you can have code like this:<br /><pre><br />public enum ActionQuery<T extends Action> {<br /> ALL<Action> {<br /> public List<Action> getResults() {...}<br /> },<br /> EDIT_ACTION<EditAction> {<br /> public List<EditAction> getResults() {...}<br /> },<br /> VIEW_ACTION<ViewAction> {<br /> public List<ViewAction> getResults() {...}<br /> };<br /> public abstract List<T> getResults();<br />}<br /></pre> <br /> I find "Extended enums" very useful in organizing SQL queries and their results, playing with properties and their types, and so on.</li><li>The most important feature and the reason why I developed "Extended enums" was to have the ability to define annotation enum parameters without having to specify their list of values in advance. You can already see this issue in today's JPA specification. There is an enum FetchType that is fixed in the spec to LAZY and EAGER, but Hibernate also supports SUBSELECT, which is approximately between LAZY and EAGER. To support SUBSELECT, you need to use the Hibernate specific annotation in combination with the standard one. If the FetchType was an abstract enum, the JPA specification does not need to enforce a well-defined list, but could have a proposed DefaultFetchType and let JPA implementation and application developers define a new enum with their desired list of FetchType. This already works great in the "abstract enum" implementation and provides me with great benefits in many other areas: (such as BindingType in JSR-299 Context and Dependency Injection, Cache declaration using enum instead of error prone string for region, Group in JSR-303 Bean Validation using user defined enums instead of empty interfaces, and more).</li></ul><br /> <br />From my point of view (and I think/hope I'm not alone), Joe Darcy missed the benefit point of the extended enum. It is a big benefit to the Java language.<br />This was and is my position for some time. What pushed me to re-launch "Vote for Extended Enums for the Coin project!", is of course Christof May from <a href="http://soplets.org">soplets.org</a> (which setup the extended-enums site: <a href="http://www.extended-enums.org/">http://www.extended-enums.org/</a>), and the fact that I found a way to make the change a "small" one. Until now, I was sure that to implement this correctly a new flag was needed in the class byte code, and many changes to the Java type management were necessary.<br /><br />So, if you are interested or want to learn more please check the extended enums web site: <a href="http://www.extended-enums.org/">http://www.extended-enums.org/</a>Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com0tag:blogger.com,1999:blog-1846725363010306463.post-15916476073300439832009-10-29T16:53:00.009+02:002009-11-10T17:19:05.678+02:00No singletons allowed in a WebLogic EAR!<h2>The context</h2><br />There is a big EJB3 application (835 Entities, 88 stateless, 1 MDB) that works on JBoss (Server and Embedded) in production with no problem.<br />We now want to support WebLogic 10.3 and WebSphere 7.0!<br /><br /><h2>The problem</h2><br />The application contains "of course" some framework jars to manage cross cutting services (logger, metadata, XML marshalling, ...) using immutable static maps that are initialized at bootstrap time. Nothing extraordinary in my point of view!<br />Still, we found out that under WebLogic 10.3 the <b>final static</b> maps are created multiple times!<br /><br /><h2>No way!</h2><br />I did not believe it!<br />I'm working with WebLogic since it was a company (not under BEA), and I always managed and enjoyed creating big enterprise application with it.<br />Putting JBoss aside (this thread is about WebLogic), in 1999-2002, every presale competition against IBM WebSphere if no politics were involved, WebLogic always won.<br />From my experience, I always managed to understand the logical behavior of WebLogic, and found a way to deliver the applications to my customers.<br />Is this crazy behavior due to the influence of Oracle buying BEA almost 2 years ago?<br /><br /><h2>The small test case</h2><br />To prove the point, we created a small ejb3 application that can be easily build with Maven 2. Side note: this simple app can be useful to others that wish to test their EJB3 container.<br />The source code is under subversion <a href="http://subversion.jfrog.org/jfrog/greenhouse/simple-ejb3-app">here</a>.<br /><br /><h3>The modules</h3><br />This Enterprise Application has the simplest but complete set of features we need from an EJB3 container. It is made of the following modules (by order of dependency):<br /><ol><li><b>simple-framework</b><br/>A simple framework jar that will be part of the EAR and used by the WEB and EJB classes. This module uses only 2 external jars: log4j and slf4j.</li><li><b>another-ejb-sample</b><br/>A pure Stateless session bean used from different layer of the other modules to test EJB injection.</li><li><b>ejb-sample</b><br/>A simple EJB3 jar with different kind of beans: a Stateful, a Stateless and an Entity. This module contains the persistence.xml that defined the connection to the DB. By default the persistence.xml is configured for a MySQL (the line for Oracle is commented) DB data source with JNDI Name "jdbc/ejb3_ds" which contain one table "customer"</li><li><b>web-sample</b><br/>A webapp <a href="http://localhost:7001/web-sample">http://localhost:7001/web-sample</a> with a servlet that can activate the different tests.</li><li><b>ear</b><br/>A maven module that will create "sample-ejb3-ear.ear" file that can be deployed in WebLogic Server 10.3.</li></ol><br /><br /><h3>How to build</h3><br />Use standard maven 2.0.9 or above and run "mvn install" under the root folder of the project. All needed dependencies are coming from <a href="http://hibernate.artifactoryonline.com/">this repository</a>.<br/><br />After a successful build the "ear/target/sample-ejb3-ear.ear" can be deployed on a correctly configured WebLogic 10.3 Server.<br /><h4>WebLogic and DB configuration</h4><br /><ul><li>For MySQL:<pre>create table customer (<br /> id int(10) unsigned not null auto_increment,<br /> name varchar(255) default null,<br /> primary key (id));</pre></li><li>For Oracle:<pre>create table customer (<br /> ID NUMBER(12,0) NOT NULL ENABLE,<br /> NAME VARCHAR2(200),<br /> CONSTRAINT CUSTOMER PRIMARY KEY (ID) USING INDEX COMPUTE STATISTICS);<br /><br /> create sequence CORE.hibernate_sequence<br /> start with 1 increment by 1 nomaxvalue;</pre><li>Need to create a data source with JNDI Name "jdbc/ejb3_ds" for the DB.</li><li>Deploy the "sample-ejb3-ear.ear" application in WLS 10.3.</li></ul><br /><br /><h2>The Results</h2><br />You will see in the log that a pure and simple singleton LogServiceImpl available in the "simple-framework" module is initialized 3 times (which is 2 times too much for a singleton :). The 3 times match the 3 beans (2 stateless, 1 entity) where the standard log variables appears <pre>private static final Log log = LogService.getLog(...);</pre><br />Any solution to solve this problem will be extremely painful, since basically ALL our static members are not static anymore. Any solution will have to be based on a ThreadLocal entry hoping that one single thread is doing the code analysis :).<br />What's even more worrying for us, is that these classes loaded with different class loader (static stack), are not discarded after code analysis, but assembled together!<br /><br /><h3>Possible Solutions?</h3><br /><ol><li>We added a <classloader-structure> in the weblogic-application.xml file to enforce a single class loader for the whole EAR, it still in the code and did not work.</li><li>We tested with Sun JVM 1.6 and JRockit. Both gave the same results</li></ol><br /><b>Are we missing a flag "unified class loader for EAR"?</b><br /><br /><h3>Who is doing what?</h3><br />Here is the full stack of <b>3 different creations of the same singleton</b>. It's hard to write something like this after 12 years of Java development :( :<br /><pre><br />[04-11-09 14:52:18.867] INFO SessionFactoryImpl - building session factory<br />java.lang.Exception: THIS SHOULD HAPPEN ONLY ONCE<br /> at greenhouse.ejb3.sample.framework.LogServiceImpl.<init>(LogServiceImpl.java:54)<br /> at greenhouse.ejb3.sample.framework.LogServiceImpl.<clinit>(LogServiceImpl.java:51)<br /> at greenhouse.ejb3.sample.framework.LogService.getLog(LogService.java:23)<br /> at greenhouse.ejb3.sample.Customer.<clinit>(Customer.java:35)<br /> at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)<br /> at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)<br /> at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)<br /> at java.lang.reflect.Constructor.newInstance(Constructor.java:513)<br /> at org.hibernate.engine.UnsavedValueFactory.instantiate(UnsavedValueFactory.java:22)<br /> at org.hibernate.engine.UnsavedValueFactory.getUnsavedIdentifierValue(UnsavedValueFactory.java:44)<br /> at org.hibernate.tuple.PropertyFactory.buildIdentifierProperty(PropertyFactory.java:44)<br /> at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:124)<br /> at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:434)<br /> at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:109)<br /> at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:55)<br /> at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:226)<br /> at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1300)<br /> at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:859)<br /> at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)<br /> at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:132)<br /> at weblogic.deployment.PersistenceUnitInfoImpl.createEntityManagerFactory(PersistenceUnitInfoImpl.java:330)<br /> at weblogic.deployment.PersistenceUnitInfoImpl.<init>(PersistenceUnitInfoImpl.java:123)<br /> at weblogic.deployment.AbstractPersistenceUnitRegistry.storeDescriptors(AbstractPersistenceUnitRegistry.java:331)<br /> at weblogic.deployment.AbstractPersistenceUnitRegistry.loadPersistenceDescriptor(AbstractPersistenceUnitRegistry.java:245)<br /> at weblogic.deployment.ModulePersistenceUnitRegistry.<init>(ModulePersistenceUnitRegistry.java:63)<br /> at weblogic.ejb.container.deployer.EJBModule.setupPersistenceUnitRegistry(EJBModule.java:209)<br /> at weblogic.ejb.container.deployer.EJBModule$1.execute(EJBModule.java:310)<br /> at weblogic.deployment.PersistenceUnitRegistryInitializer.setupPersistenceUnitRegistries(PersistenceUnitRegistryInitializer.java:62)<br /> at weblogic.ejb.container.deployer.EJBModule.prepare(EJBModule.java:376)<br /> at weblogic.application.internal.flow.ModuleListenerInvoker.prepare(ModuleListenerInvoker.java:93)<br /> at weblogic.application.internal.flow.DeploymentCallbackFlow$1.next(DeploymentCallbackFlow.java:387)<br /> at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:37)<br /> at weblogic.application.internal.flow.DeploymentCallbackFlow.prepare(DeploymentCallbackFlow.java:58)<br /> at weblogic.application.internal.flow.DeploymentCallbackFlow.prepare(DeploymentCallbackFlow.java:42)<br /> at weblogic.application.internal.BaseDeployment$1.next(BaseDeployment.java:615)<br /> at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:37)<br /> at weblogic.application.internal.BaseDeployment.prepare(BaseDeployment.java:191)<br /> at weblogic.application.internal.EarDeployment.prepare(EarDeployment.java:16)<br /> at weblogic.application.internal.DeploymentStateChecker.prepare(DeploymentStateChecker.java:155)<br /> at weblogic.deploy.internal.targetserver.AppContainerInvoker.prepare(AppContainerInvoker.java:60)<br /> at weblogic.deploy.internal.targetserver.AppDeployment.prepare(AppDeployment.java:141)<br /> at weblogic.management.deploy.internal.DeploymentAdapter$1.doPrepare(DeploymentAdapter.java:39)<br /> at weblogic.management.deploy.internal.DeploymentAdapter.prepare(DeploymentAdapter.java:187)<br /> at weblogic.management.deploy.internal.AppTransition$1.transitionApp(AppTransition.java:21)<br /> at weblogic.management.deploy.internal.ConfiguredDeployments.transitionApps(ConfiguredDeployments.java:233)<br /> at weblogic.management.deploy.internal.ConfiguredDeployments.prepare(ConfiguredDeployments.java:165)<br /> at weblogic.management.deploy.internal.ConfiguredDeployments.deploy(ConfiguredDeployments.java:122)<br /> at weblogic.management.deploy.internal.DeploymentServerService.resume(DeploymentServerService.java:173)<br /> at weblogic.management.deploy.internal.DeploymentServerService.start(DeploymentServerService.java:89)<br /> at weblogic.t3.srvr.SubsystemRequest.run(SubsystemRequest.java:64)<br /> at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)<br /> at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)<br />[04-11-09 14:52:19.117] INFO Customer - A new customer is created<br />[04-11-09 14:52:19.492] INFO SessionFactoryObjectFactory - Not binding factory to JNDI, no JNDI name configured<br />[04-11-09 14:52:19.495] INFO NamingHelper - JNDI InitialContext properties:{}<br />java.lang.Exception: THIS SHOULD HAPPEN ONLY ONCE<br /> at greenhouse.ejb3.sample.framework.LogServiceImpl.<init>(LogServiceImpl.java:54)<br /> at greenhouse.ejb3.sample.framework.LogServiceImpl.<clinit>(LogServiceImpl.java:51)<br /> at greenhouse.ejb3.sample.framework.LogService.getLog(LogService.java:23)<br /> at greenhouse.ejb3.sample.CustomerDAOBean.<clinit>(CustomerDAOBean.java:26)<br /> at java.lang.Class.forName0(Native Method)<br /> at java.lang.Class.forName(Class.java:247)<br /> at weblogic.j2ee.dd.xml.validator.AnnotationValidatorHelper.getClass(AnnotationValidatorHelper.java:14)<br /> at weblogic.j2ee.dd.xml.validator.injectiontarget.BaseValidator.getClass(BaseValidator.java:38)<br /> at weblogic.j2ee.dd.xml.validator.AbstractAnnotationValidator.validate(AbstractAnnotationValidator.java:22)<br /> at weblogic.j2ee.dd.xml.validator.AnnotationValidatorVisitor.visitInjectionTargetBean(AnnotationValidatorVisitor.java:48)<br /> at weblogic.j2ee.dd.xml.validator.AnnotationValidatorVisitor.visit(AnnotationValidatorVisitor.java:25)<br /> at weblogic.descriptor.internal.AbstractDescriptorBean.accept(AbstractDescriptorBean.java:1124)<br /> at weblogic.descriptor.internal.AbstractDescriptorBean.accept(AbstractDescriptorBean.java:1128)<br /> at weblogic.descriptor.internal.AbstractDescriptorBean.accept(AbstractDescriptorBean.java:1128)<br /> at weblogic.descriptor.internal.AbstractDescriptorBean.accept(AbstractDescriptorBean.java:1128)<br /> at weblogic.descriptor.internal.AbstractDescriptorBean.accept(AbstractDescriptorBean.java:1128)<br /> at weblogic.j2ee.dd.xml.BaseJ2eeAnnotationProcessor.validate(BaseJ2eeAnnotationProcessor.java:143)<br /> at weblogic.j2ee.dd.xml.BaseJ2eeAnnotationProcessor.validate(BaseJ2eeAnnotationProcessor.java:131)<br /> at weblogic.ejb.container.dd.xml.EjbAnnotationProcessor.processAnnotations(EjbAnnotationProcessor.java:205)<br /> at weblogic.ejb.container.dd.xml.EjbDescriptorReaderImpl.processStandardAnnotations(EjbDescriptorReaderImpl.java:324)<br /> at weblogic.ejb.container.dd.xml.EjbDescriptorReaderImpl.createReadOnlyDescriptorFromJarFile(EjbDescriptorReaderImpl.java:190)<br /> at weblogic.ejb.spi.EjbDescriptorFactory.createReadOnlyDescriptorFromJarFile(EjbDescriptorFactory.java:93)<br /> at weblogic.ejb.container.deployer.EJBModule.loadEJBDescriptor(EJBModule.java:1198)<br /> at weblogic.ejb.container.deployer.EJBModule.prepare(EJBModule.java:380)<br /> at weblogic.application.internal.flow.ModuleListenerInvoker.prepare(ModuleListenerInvoker.java:93)<br /> at weblogic.application.internal.flow.DeploymentCallbackFlow$1.next(DeploymentCallbackFlow.java:387)<br /> at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:37)<br /> at weblogic.application.internal.flow.DeploymentCallbackFlow.prepare(DeploymentCallbackFlow.java:58)<br /> at weblogic.application.internal.flow.DeploymentCallbackFlow.prepare(DeploymentCallbackFlow.java:42)<br /> at weblogic.application.internal.BaseDeployment$1.next(BaseDeployment.java:615)<br /> at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:37)<br /> at weblogic.application.internal.BaseDeployment.prepare(BaseDeployment.java:191)<br /> at weblogic.application.internal.EarDeployment.prepare(EarDeployment.java:16)<br /> at weblogic.application.internal.DeploymentStateChecker.prepare(DeploymentStateChecker.java:155)<br /> at weblogic.deploy.internal.targetserver.AppContainerInvoker.prepare(AppContainerInvoker.java:60)<br /> at weblogic.deploy.internal.targetserver.AppDeployment.prepare(AppDeployment.java:141)<br /> at weblogic.management.deploy.internal.DeploymentAdapter$1.doPrepare(DeploymentAdapter.java:39)<br /> at weblogic.management.deploy.internal.DeploymentAdapter.prepare(DeploymentAdapter.java:187)<br /> at weblogic.management.deploy.internal.AppTransition$1.transitionApp(AppTransition.java:21)<br /> at weblogic.management.deploy.internal.ConfiguredDeployments.transitionApps(ConfiguredDeployments.java:233)<br /> at weblogic.management.deploy.internal.ConfiguredDeployments.prepare(ConfiguredDeployments.java:165)<br /> at weblogic.management.deploy.internal.ConfiguredDeployments.deploy(ConfiguredDeployments.java:122)<br /> at weblogic.management.deploy.internal.DeploymentServerService.resume(DeploymentServerService.java:173)<br /> at weblogic.management.deploy.internal.DeploymentServerService.start(DeploymentServerService.java:89)<br /> at weblogic.t3.srvr.SubsystemRequest.run(SubsystemRequest.java:64)<br /> at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)<br /> at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)<br />java.lang.Exception: THIS SHOULD HAPPEN ONLY ONCE<br /> at greenhouse.ejb3.sample.framework.LogServiceImpl.<init>(LogServiceImpl.java:54)<br /> at greenhouse.ejb3.sample.framework.LogServiceImpl.<clinit>(LogServiceImpl.java:51)<br /> at greenhouse.ejb3.sample.framework.LogService.getLog(LogService.java:23)<br /> at greenhouse.ejb3.sample.RandomNumberGeneratorBean.<clinit>(RandomNumberGeneratorBean.java:16)<br /> at java.lang.Class.forName0(Native Method)<br /> at java.lang.Class.forName(Class.java:247)<br /> at weblogic.ejb.container.dd.xml.EjbAnnotationProcessor.processWLSAnnotations(EjbAnnotationProcessor.java:1699)<br /> at weblogic.ejb.container.dd.xml.EjbDescriptorReaderImpl.processWLSAnnotations(EjbDescriptorReaderImpl.java:346)<br /> at weblogic.ejb.container.dd.xml.EjbDescriptorReaderImpl.createReadOnlyDescriptorFromJarFile(EjbDescriptorReaderImpl.java:192)<br /> at weblogic.ejb.spi.EjbDescriptorFactory.createReadOnlyDescriptorFromJarFile(EjbDescriptorFactory.java:93)<br /> at weblogic.ejb.container.deployer.EJBModule.loadEJBDescriptor(EJBModule.java:1198)<br /> at weblogic.ejb.container.deployer.EJBModule.prepare(EJBModule.java:380)<br /> at weblogic.application.internal.flow.ModuleListenerInvoker.prepare(ModuleListenerInvoker.java:93)<br /> at weblogic.application.internal.flow.DeploymentCallbackFlow$1.next(DeploymentCallbackFlow.java:387)<br /> at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:37)<br /> at weblogic.application.internal.flow.DeploymentCallbackFlow.prepare(DeploymentCallbackFlow.java:58)<br /> at weblogic.application.internal.flow.DeploymentCallbackFlow.prepare(DeploymentCallbackFlow.java:42)<br /> at weblogic.application.internal.BaseDeployment$1.next(BaseDeployment.java:615)<br /> at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:37)<br /> at weblogic.application.internal.BaseDeployment.prepare(BaseDeployment.java:191)<br /> at weblogic.application.internal.EarDeployment.prepare(EarDeployment.java:16)<br /> at weblogic.application.internal.DeploymentStateChecker.prepare(DeploymentStateChecker.java:155)<br /> at weblogic.deploy.internal.targetserver.AppContainerInvoker.prepare(AppContainerInvoker.java:60)<br /> at weblogic.deploy.internal.targetserver.AppDeployment.prepare(AppDeployment.java:141)<br /> at weblogic.management.deploy.internal.DeploymentAdapter$1.doPrepare(DeploymentAdapter.java:39)<br /> at weblogic.management.deploy.internal.DeploymentAdapter.prepare(DeploymentAdapter.java:187)<br /> at weblogic.management.deploy.internal.AppTransition$1.transitionApp(AppTransition.java:21)<br /> at weblogic.management.deploy.internal.ConfiguredDeployments.transitionApps(ConfiguredDeployments.java:233)<br /> at weblogic.management.deploy.internal.ConfiguredDeployments.prepare(ConfiguredDeployments.java:165)<br /> at weblogic.management.deploy.internal.ConfiguredDeployments.deploy(ConfiguredDeployments.java:122)<br /> at weblogic.management.deploy.internal.DeploymentServerService.resume(DeploymentServerService.java:173)<br /> at weblogic.management.deploy.internal.DeploymentServerService.start(DeploymentServerService.java:89)<br /> at weblogic.t3.srvr.SubsystemRequest.run(SubsystemRequest.java:64)<br /> at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)<br /> at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)<br /></pre><br /><br /><h3>Update on Nov 10th 2009</h3><br />Thanks to <a href="http://drorbr.blogspot.com/">Dror Bereznetsky</a> for the heads up on the code analysis of <i>"EjbDescriptorReaderImpl.createReadOnlyDescriptorFromJarFile(EjbDescriptorReaderImpl.java:192)"</i> I managed to create a small patch to weblogic.jar that solved the problem.<br/><br />The <b>"stupid"</b> issue is that the new class loader created for bean analysis was using the parent class loader of the EAR classloader, basically ignoring all the classes of my application that where reloaded on each analysis...<br/><br />I went very strong on my patch making the parent of the bean analyzer class loader the current thread class loader, and it works. More tests coming, and a small hope that "Oracle" will solve the bug soon :(Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com7tag:blogger.com,1999:blog-1846725363010306463.post-33833809201844353122009-09-11T00:15:00.005+03:002009-09-11T00:58:22.219+03:00Java6 and IntelliJ on MacOS XIt's the third time now that I'm going through this, and each time I'm forgetting something...<br /><br />The main problems I'm having are:<br /><ol><li>How to enforce Java6 64bit JVM as the default on MacOS?</li><br /><li>How to make IntelliJ use it?</li><br /><li>How to make Safari (and may be one day Firefox) use it</li></ol><br /><br />I know I'm loosing SWT, and many soft (like NetBeans and IntelliJ) enforce Java 5 has hard coded default on the Mac, but I'm developing in <a href="http://fandev.org/">Fan</a> and the <a href="http://wiki.jfrog.org/confluence/display/FANP/Home">IntelliJ Fan Plugin</a>, and Java 6 is kind of a must :)<br /><br />So, here is what I do:<br /><b>On each update of Java6 from Apple</b><br /><br /><ol><li>As root I go under:<br /><span style="font-family: courier new;font-size:12px">cd /System/Library/Frameworks/JavaVM.framework/Versions/</span></li><br /><li>There should be a symlink: CurrentJDK -> 1.5</li><br /><li>Then I change the link:<br /><span style="font-family: courier new;font-size:12px">rm CurrentJDK && ln -s 1.6 CurrentJDK</span></li></ol><br /><br /><b>On each update of IntelliJ</b><br /><br /><ol><li>Download the idea-XXX.dmg, the idea-XXX.tar.gz (64 bit not the jdk15 version), and idea-XXX-dev.zip. I hope JetBrains will start giving dmg files for the 64 bit JVM, because it's big downloads :(</li><br /><li>Copy the "IntelliJ IDEA XXX.app" folder from DMG to Applications. I have /Applications/IntelliJ and /Applications/NetBeans with the versions I used, it helps when I'm messing up :)</li><br /><li>Do a copy of it under "IntelliJ IDEA XXX-jdk15.app" for backup and to be able to compile IntelliJ plugin for 1.5</li><br /><li>Extract the idea-XXX.tar.gz under /Applications/IntelliJ</li><br /><li>Copy all the jar files from idea-XXX to "IntelliJ IDEA XXX.app". I do as root under idea-XXX:<br /><span style="font-family: courier new;font-size:12px">find . -name "*.jar" -exec cp \{\} ../IntelliJ\ IDEA\ XXX.app/\{\} \;</span></li><br /><li>Change the "IntelliJ IDEA XXX.app/Contents/Info.plist" with:<span style="font-family: courier new;font-size:12px"><br /> <key>JVMVersion</key><br /> <string>1.6*</string><br /><br /> <key>VMOptions</key><br /> <string>-Xms400m -Xmx1248m -XX:MaxPermSize=192m -XX:PermSize=192m -Xbootclasspath/a:../lib/boot.jar -ea</string></span><br /></li><br /><li>Here usually I try to run "open /Applications/IntelliJ IDEA XXX.app" and I get:<br /><span style="font-family: courier new;font-size:12px">LSOpenFromURLSpec() failed with error -10810 for the file /Applications/IntelliJ/IntelliJ IDEA XXX.app</span></li><br /><li>The the solution is (as root):<br /><span style="font-family: courier new;font-size:12px">cp /System/Library/Frameworks/JavaVM.framework/Resources/MacOS/JavaApplicationStub64 /Applications/IntelliJ/IntelliJ\ IDEA\ XXX.app/Contents/MacOS/idea</span></li><br /></ol><br /><br />For Safari and Firefox, I still don't manage to do it!<br /><br />Hope I won't have to do this too much in the future, once everyone agrees on JDK 1.6 64 bits as Mac OS X default.Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com1tag:blogger.com,1999:blog-1846725363010306463.post-76781764870682224692009-05-11T23:09:00.002+03:002009-05-11T23:12:23.505+03:00Maven and JavaFX, the story of TwitterFX POMI posted on the JFrog's mouth our story of <a href="http://blogs.jfrog.org/2009/05/maven-and-javafx-story-of-twitterfx-pom.html">migrating TwitterFX</a> codebase to Maven.<br />We had fun, and we'll show it all at JavaOne.<br /><a href="http://java.sun.com/javaone" target="_blank"><img src="http://www.cplan.com/javaone2009/creativetoolbox/images/09J1_200x200_Speaker_Button_Duke.gif" alt="I'm Speaking At JavaOne" width="200" height="200" border="0" /></a>Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com0tag:blogger.com,1999:blog-1846725363010306463.post-72326108497917013392008-12-30T10:56:00.001+02:002008-12-30T11:17:40.724+02:00Why natural selection did not kill the scientists?A new post on Nothing is Infinite seems good for software techies too :)<br /><a href="http://nothingisinfinite.blogspot.com/2008/12/why-natural-selection-did-not-kill.html">Why natural selection did not kill the scientists?</a>Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com0tag:blogger.com,1999:blog-1846725363010306463.post-7812016448466059802008-11-22T13:32:00.000+02:002008-11-22T13:41:38.537+02:00Obama from a 9 year old!Being a French man living in Israel, we have 3 languages at home: English, French and Hebrew.<br />And many of my friends around here have this trilingual environment.<br />Last week the 9 year old son of one of them told him:<br />- Dad, Obama is talking Hebrew?<br />- No, Why do you ask?<br />- Because he keep saying: Yes Oui Ken!<br /><br />Note: "Yes We Can" sounds like Yes, Oui (yes in French), Ken (yes in Hebrew).<br /><br />Amazing no?<br />I found out that it was <a href="http://frgdr.com/blog/2008/07/22/obama-hebrew-poster-oui-ken/">already used</a> in Obama's campaign.<br /><br />Anyway, international triple yes from an Israeli 9 year old kid...Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com0tag:blogger.com,1999:blog-1846725363010306463.post-25966634272922531482008-11-20T14:36:00.001+02:002008-11-20T15:28:04.451+02:00Lists and Contextual Menus, MMI nightmare!I'm more of a "server side" kind of developer.<br />When I see too much HTML, CSS and Javascript, I need pills!<br />Still, I like to challenge the MVC architecture of UI frameworks. I even wrote my own web framework for fun (but some poor developers, in India I think, are now suffering from it), and played with Swing developing Stellarium4Java.<br /><br />So, UI is not my cup of Tea. Now, for the latest release of <a href="http://artifactory.jfrog.org/">Artifactory</a>, I needed to managed the communication between the UI Designer and the Web developers. I learned a lot from this interesting experience.<br />During this process I encountered a really basic UI design issue. It was so basic I got worried I missed something!<br />The point is: The way we are used to manage lists, selections, actions and contextual menus is totally incoherent.<br /><br />In real UI applications (fat client and Ajax), you get a list of elements and then you can act on them. Usually, you select a line, then some Action (Buttons, Menus) become enabled and you can activate them. But to minimize the amount of clicks and mouse gestures there are also contextual menus. This is where it gets weird...<br />You select one line, and then can actually "right click" on another one. That way, the list of Actions on the contextual menus does not match the one in buttons and menus.<br />You can force select the line where you right click, but few Applications are doing it!<br /><br />The other issue is that contextual menus are really not that great (i.e. I hate them!):<br /><ul><li>They are not Web Browser friendly.</li><li>They don't actually save much in terms of clicks and gestures (right click, move, left click).</li><li>They get in the middle of reading the lists of elements.</li><li>They never disappear when you want them to, and always disappear before you find the menu item you want to click on.</li><li>To remove them go away you need to click elsewhere, crossing your finger you did not actually click on "buy in one click" button.</li></ul><br />One solution on the Web (and on the iPhone/iPod, where there is no right click :), is to add action buttons directly in the list itself as columns. That works and can be nice looking (with good icons) but this technique get very heavy (bunch of garbage icons all over). Anyway, it is not scalable: 5 icons it's already too much.<br /><br />So, the UI designer came with the really cool idea: A hovering toolbox appearing on the side of the list when rollover the line element.<br />At first, I thought:<br /><ul><li>It may work but we'd be going against a big UI muscle memory about how to use a list.</li><li>People will hate it!</li><li>The toolbox is too far from where my mouse is, and going there will be very annoying.</li><li>We are not here to reinvent UI and Men Machine Interaction!</li></ul><br />But, anyway I took the chance and we implemented it. To see it, you can go to <a href="http://repo.jfrog.org/artifactory/">Artifactory live demo</a>, do a quick search on "log" for example, and hover above the list. It's still a beta version and the previous select/link actions are not removed, so it may be confusing. As anonymous user your action list is limited, but you can still get the feel of it.<br /><br />I'm using this feature for 2 weeks now and frankly: I love it!<br />I hover on the list in the left side of it, I can read the line I'm on, and then activate the action with one click. Just natural moves and ONLY ONE click.<br /><br />May be I'm under the influence (it's our application at the end :), and that's why I'm anxiously waiting for the feedback!<br />What do you think?Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com6tag:blogger.com,1999:blog-1846725363010306463.post-72847893854656391312008-10-30T16:19:00.001+02:002008-10-30T19:12:23.007+02:00IT opportunities in the current financial crisis?I'm not optimistic, but here is a fact: For more than 20 years (since the 1987 crash) or in some cases since the usage of computers in companies, the IT budgets of financial institutions (banks, insurance companies, stock markets etc.) ALWAYS go up.<br />In the meantime, technologies went from Mainframe, to Client/Server, to Web 1.0, to Web 2.0, to SOA, to Virtualization and now Cloud Computing. But in spite of all the technological advances, IT budgets ALWAYS go up. I've given consulting services to many banks and insurance companies, and one thing got increasingly clear: If you're trying to sell a software that will reduce their IT budget... Forget it! <p style="margin-bottom: 0in;" align="left"><br />Of course, the financial institutions' needs from IT increased in the last 20 years. They want to setup new services and products (online banking, new policies, new mortgages :) faster than their competitors. But the increase in end user demands is an order of magnitude lower than the technological advances in hardware and software. IT budgets should have gone down, and insurance premiums and bank fees also. But no - IT budgets ALWAYS go up.</p> <p style="margin-bottom: 0in;" align="left"><br />I think the main reason is Wall Street. If you are Bank of America, and someone finds out you're reducing your IT budget... Your stock will go down immediately!</p><div class="Ih2E3d"><br />A month ago after 20 years of IT budget increases all the CIO and IT department in financial companies have a huge amount of cash fat.<br />Where the fat goes?<br /><ul><li>Buying hard to install and unmaintainable software (you need to keep all these engineers) from BIG vendors.</li><li>Buying low performance hardware for incredible amounts of money.</li><li>Of course, a big team of developers and system engineers to oil down the cranky machines.</li></ul></div><div class="Ih2E3d"><br />And now, for the first time all the CIOs have only one goal: Reduce your IT budget!<br />IT department in financial companies will never be the same!<br /><br />From my knowledge, and experience with theses companies their IT budget is about 3 to 5 times bigger than it should be. I don't think they will go all the way and slash 80% of the IT department, but what's for sure, they'll slash the vendors, and contractors.<br /><br /></div>I think one big software/hardware company will suffer big time from this change because it's living and breathing of this fat. The saying was that a CIO choosing IBM will never get fired for his choice (even he wasted time and money on a failed project). Today that thinking changed.<div class="Ih2E3d"><br />So, where are the opportunities?<br />Well, now you can really sell and prove the advantages of modern technological advances to financial CIO. They will be sensitive to TCO, developer productivity, software quality and maintenance.<br /></div>The issue is that no CIO will start a costly migration project now! So the current state of IT will be frozen for some time. But, some companies will really analyze what's going on and make a decision to go with open source, agile and distributed all the way.<br /><br />Things will change in banks and insurance companies IT departments, let's hope WebsFear does not blackmail their customers again...<br /><br />Originally posted on <a href="http://java.dzone.com/articles/it-opportunities-current-finan">dzone</a>Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com0tag:blogger.com,1999:blog-1846725363010306463.post-47486283423834485122008-09-10T11:41:00.000+03:002008-09-10T12:09:09.262+03:00All new?The amount of new Web adventures going on around me starts to make a big pile. So, instead of twittering them with 144 characters, here they are:<br /><ol><li>A very good content Podcast about Java on server side from AlphaCSP consultants: <a href="http://alphacsp.libsyn.com/">The Alpha Pub</a>. I really enjoyed the show, and the latest interview with <a href="http://blog.springsource.com/main/author/alefa/">Alef Arendsen</a> has very good content. Thanks, Ophir for setting up this!</li><li>The <a href="http://www.alphacsp.com/Events/JavaEdge-2008/JavaEdge-2008.htm">JavaEdge 2008</a> is on the way, and it's going to be even better than last year!</li><li><a href="http://www.jfrog.org/">JFrog.org</a> just released the version <a href="http://www.nabble.com/-ANN--Artifactory-1.3.0-beta-3-td19368349.html">1.3.0-beta-3</a> of <a href="http://www.jfrog.org/sites/artifactory/latest/">Artifactory</a> with the <a href="http://freddy33.blogspot.com/2008/07/using-jersey-for-exposing-rest-services.html">integration of Jersey</a>, which was a lot of fun to do.</li><li>I sarted a <a href="http://nothingisinfinite.blogspot.com/">new blog</a> to release in the wild my toughts around Space, Physics and the <a href="http://www.math.columbia.edu/%7Ewoit/wordpress/">bad taste</a> left by the <a href="http://www.thetroublewithphysics.com/">failure</a> of Super String Theory!</li></ol><br />That's a lot of good stuff coming, and I'm really missing <a href="http://stellarium4java.sourceforge.net/">Stellarium4Java</a> and <a href="http://openjdk.java.net/">OpenJDK</a>, but that's life... Need to set priorities, and be happy about what you did not do!Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com0tag:blogger.com,1999:blog-1846725363010306463.post-89552208728264367632008-07-30T11:21:00.006+03:002008-09-03T17:40:32.954+03:00Using Jersey for exposing REST servicesI just started integrating <a href="https://jersey.dev.java.net/servlets/ProjectDocumentList?folderID=7653&expandFolder=7653&folderID=0">Jersey</a> in <a href="http://www.jfrog.org/sites/artifactory/latest/">Artifactory</a> and I have to say: I'm impressed!<br />Like the XFire (still crying on its death :( ) I really like the process of: Write a simple annotated POJO, compile and run, that's it.<br /><br />Anyway, since I encountered a couple of issues, and implemented some nice extra (XStream adapter and Spring beans injection) here are my findings.<br />First thanks to <a href="http://blog.spaceprogram.com/2008/01/getting-started-with-jax-rs-and-jersey.html">getting started entry</a> and <a href="https://jersey.dev.java.net/use/getting-started.html">getting started with jersey</a> that convinced me Jersey is the way to go.<br /><h4>Getting started</h4><br />I'm using Maven and Jetty and so running the HelloWorld example got this <a href="https://jersey.dev.java.net/issues/show_bug.cgi?id=70">bug 70</a>. Setting up the Annotation scanner per Java packages solves the problem, and anyway sounds a lot more manageable to me. So here is my web.xml (for 0.8):<br /><pre style="line-height: 100%;font-family:courier new;font-size:80%;background-color:#ffffff; border-width:0.01mm; border-color:#000000; border-style:solid; padding:4px;"><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">servlet</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">servlet-name</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">Jersey</span><span style="background-color:#ffffff;"> </span><span style="background-color:#ffffff;font-weight:bold;">Web</span><span style="background-color:#ffffff;"> </span><span style="background-color:#ffffff;font-weight:bold;">Application</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">servlet-name</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">servlet-class</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">org.artifactory.rest.servlet.ArtifactoryRestServlet</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">servlet-class</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">init-param</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">param-name</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">com.sun.jersey.config.property.resourceConfigClass</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">param-name</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">param-value</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">com.sun.jersey.api.core.PackagesResourceConfig</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">param-value</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">init-param</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">init-param</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">param-name</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">com.sun.jersey.config.property.packages</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">param-name</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">param-value</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">org.artifactory.rest</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">param-value</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">init-param</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="color:#808080;background-color:#ffffff;font-style:italic;"><!-- Usable only in 0.9 version of Jersey<br /> <init-param><br /> <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name><br /> <param-value>org.artifactory.rest.common.AuthorizationContainerRequestFilter</param-value><br /> </init-param><br /> --><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">load-on-startup</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">1</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">load-on-startup</span><span style="background-color:#efefef;">><br /></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">servlet</span><span style="background-color:#efefef;">><br /><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">servlet-mapping</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">servlet-name</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">Jersey</span><span style="background-color:#ffffff;"> </span><span style="background-color:#ffffff;font-weight:bold;">Web</span><span style="background-color:#ffffff;"> </span><span style="background-color:#ffffff;font-weight:bold;">Application</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">servlet-name</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">url-pattern</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">/api/*</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">url-pattern</span><span style="background-color:#efefef;">><br /></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">servlet-mapping</span><span style="background-color:#efefef;">><br /></span></pre><br />So now the annotations scanner reads correctly my classes, and I needed only 2 dependencies in my pom.xml:<br /><pre style="line-height: 100%;font-family:courier new;font-size:80%;background-color:#ffffff; border-width:0.01mm; border-color:#000000; border-style:solid; padding:4px;"><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">dependency</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">groupId</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">javax.servlet</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">groupId</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">artifactId</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">servlet-api</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">artifactId</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">version</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">2.5</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">version</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">scope</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">provided</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">scope</span><span style="background-color:#efefef;">><br /></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">dependency</span><span style="background-color:#efefef;">><br /><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">dependency</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">groupId</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">com.sun.jersey</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">groupId</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">artifactId</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">jersey</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">artifactId</span><span style="background-color:#efefef;">><br /></span><span style="background-color:#ffffff;"> </span><span style="background-color:#efefef;"><</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">version</span><span style="background-color:#efefef;">></span><span style="background-color:#ffffff;font-weight:bold;">${jersey.version}</span><span style="background-color:#efefef;"></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">version</span><span style="background-color:#efefef;">><br /></</span><span style="color:#000080;background-color:#efefef;font-weight:bold;">dependency</span><span style="background-color:#efefef;">><br /></span></pre><br /><h4>XStream Message Reader and Writer</h4><br />Most of my object model classes are using XStream, so I wanted Jersey to marshall/unmarshall automatically any XStream class. It was amazingly easy, here is my XStream message reader provider class:<br /><pre style="line-height: 100%;font-family:courier new;font-size:80%;background-color:#ffffff; border-width:0.01mm; border-color:#000000; border-style:solid; padding:4px;"><span style="color:#808000;background-color:#ffffff;">@ProduceMime(</span><span style="background-color:#ffffff;">{</span><span style="color:#008000;background-color:#ffffff;font-weight:bold;">"application/xml"</span><span style="background-color:#ffffff;">, </span><span style="color:#008000;background-color:#ffffff;font-weight:bold;">"text/xml"</span><span style="background-color:#ffffff;">, </span><span style="color:#008000;background-color:#ffffff;font-weight:bold;">"*/*"</span><span style="background-color:#ffffff;">})<br /></span><span style="color:#808000;background-color:#ffffff;">@ConsumeMime(</span><span style="background-color:#ffffff;">{</span><span style="color:#008000;background-color:#ffffff;font-weight:bold;">"application/xml"</span><span style="background-color:#ffffff;">, </span><span style="color:#008000;background-color:#ffffff;font-weight:bold;">"text/xml"</span><span style="background-color:#ffffff;">, </span><span style="color:#008000;background-color:#ffffff;font-weight:bold;">"*/*"</span><span style="background-color:#ffffff;">})<br /></span><span style="color:#808000;background-color:#ffffff;">@Provider<br /></span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">public</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">class</span><span style="background-color:#ffffff;"> XStreamAliasProvider </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">extends</span><span style="background-color:#ffffff;"> AbstractMessageReaderWriterProvider<Object> {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">private</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">static</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">final</span><span style="background-color:#ffffff;"> Set<Class> </span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;font-style:italic;">processed </span><span style="background-color:#ffffff;">= </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">new</span><span style="background-color:#ffffff;"> HashSet<Class>();<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">private</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">static</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">final</span><span style="background-color:#ffffff;"> XStream </span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;font-style:italic;">xstream </span><span style="background-color:#ffffff;">= </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">new</span><span style="background-color:#ffffff;"> XStream();<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">private</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">static</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">final</span><span style="background-color:#ffffff;"> String </span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;font-style:italic;">DEFAULT_ENCODING </span><span style="background-color:#ffffff;">= </span><span style="color:#008000;background-color:#ffffff;font-weight:bold;">"utf-8"</span><span style="background-color:#ffffff;">;<br /><br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">public</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">boolean</span><span style="background-color:#ffffff;"> isReadable(Class<?> type, Type genericType, Annotation annotations[]) {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">return</span><span style="background-color:#ffffff;"> type.getAnnotation(</span><span style="color:#808000;background-color:#ffffff;">XStreamAlias.</span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">class</span><span style="background-color:#ffffff;">) != </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">null</span><span style="background-color:#ffffff;">;<br /> }<br /><br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">public</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">boolean</span><span style="background-color:#ffffff;"> isWriteable(Class<?> type, Type genericType, Annotation annotations[]) {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">return</span><span style="background-color:#ffffff;"> type.getAnnotation(</span><span style="color:#808000;background-color:#ffffff;">XStreamAlias.</span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">class</span><span style="background-color:#ffffff;">) != </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">null</span><span style="background-color:#ffffff;">;<br /> }<br /><br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">protected</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">static</span><span style="background-color:#ffffff;"> String getCharsetAsString(MediaType m) {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">if</span><span style="background-color:#ffffff;"> (m == </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">null</span><span style="background-color:#ffffff;">) {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">return</span><span style="background-color:#ffffff;"> </span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;font-style:italic;">DEFAULT_ENCODING;<br /></span><span style="background-color:#ffffff;"> }<br /> String result = m.getParameters().get(</span><span style="color:#008000;background-color:#ffffff;font-weight:bold;">"charset"</span><span style="background-color:#ffffff;">);<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">return</span><span style="background-color:#ffffff;"> (result == </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">null</span><span style="background-color:#ffffff;">) ? </span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;font-style:italic;">DEFAULT_ENCODING </span><span style="background-color:#ffffff;">: result;<br /> }<br /><br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">protected</span><span style="background-color:#ffffff;"> XStream getXStream(Class type) {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">synchronized</span><span style="background-color:#ffffff;"> (</span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;font-style:italic;">processed)</span><span style="background-color:#ffffff;"> {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">if</span><span style="background-color:#ffffff;"> (!</span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;font-style:italic;">processed.</span><span style="background-color:#ffffff;">contains(type)) {<br /> </span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;font-style:italic;">xstream.</span><span style="background-color:#ffffff;">processAnnotations(type);<br /> </span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;font-style:italic;">processed.</span><span style="background-color:#ffffff;">add(type);<br /> }<br /> }<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">return</span><span style="background-color:#ffffff;"> </span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;font-style:italic;">xstream;<br /></span><span style="background-color:#ffffff;"> }<br /><br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">public</span><span style="background-color:#ffffff;"> Object readFrom(Class<Object> aClass, Type genericType, Annotation[] annotations,<br /> MediaType mediaType, MultivaluedMap<String, String> map, InputStream stream)<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">throws</span><span style="background-color:#ffffff;"> IOException, WebApplicationException {<br /> String encoding = </span><span style="background-color:#ffffff;font-style:italic;">getCharsetAsString(</span><span style="background-color:#ffffff;">mediaType);<br /> XStream xStream = getXStream(aClass);<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">return</span><span style="background-color:#ffffff;"> xStream.fromXML(</span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">new</span><span style="background-color:#ffffff;"> InputStreamReader(stream, encoding));<br /> }<br /><br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">public</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">void</span><span style="background-color:#ffffff;"> writeTo(Object o, Class<?> aClass, Type type, Annotation[] annotations,<br /> MediaType mediaType, MultivaluedMap<String, Object> map, OutputStream stream)<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">throws</span><span style="background-color:#ffffff;"> IOException, WebApplicationException {<br /> String encoding = </span><span style="background-color:#ffffff;font-style:italic;">getCharsetAsString(</span><span style="background-color:#ffffff;">mediaType);<br /> XStream xStream = getXStream(o.getClass());<br /> xStream.toXML(o, </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">new</span><span style="background-color:#ffffff;"> OutputStreamWriter(stream, encoding));<br /> }<br />}<br /></span></pre><br /><h4>Spring integration</h4><br />All my backend objects are Spring service bean, so I wanted autowired injection of Spring beans. Here again it was really nice. I defined my own annotation @SpringAutowired, and created a SpringBeanInjector for it that was fetching my context for a bean of the type of the injected field. Here I'm adding manually the list of "injectable" interfaces, because: I don't have an annotation to identify them :) With EJB3 it should be a lot cleaner to use @Stateless.<br />Here is my annotation:<br /><pre style="line-height: 100%;font-family:courier new;font-size:80%;background-color:#ffffff; border-width:0.01mm; border-color:#000000; border-style:solid; padding:4px;"><span style="color:#808000;background-color:#ffffff;">@Target(</span><span style="background-color:#ffffff;">{ElementType.</span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;font-style:italic;">PARAMETER,</span><span style="background-color:#ffffff;"> ElementType.</span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;font-style:italic;">METHOD,</span><span style="background-color:#ffffff;"> ElementType.</span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;font-style:italic;">FIELD}</span><span style="background-color:#ffffff;">)<br /></span><span style="color:#808000;background-color:#ffffff;">@Retention(</span><span style="background-color:#ffffff;">RetentionPolicy.</span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;font-style:italic;">RUNTIME)<br /></span><span style="color:#808000;background-color:#ffffff;">@Documented<br /></span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">public</span><span style="background-color:#ffffff;"> @</span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">interface</span><span style="background-color:#ffffff;"> </span><span style="color:#808000;background-color:#ffffff;">SpringAutowired </span><span style="background-color:#ffffff;">{<br />}<br /></span></pre><br /><br />And here the bean injector class as inner class of my Servlet:<br /><pre style="line-height: 100%;font-family:courier new;font-size:80%;background-color:#ffffff; border-width:0.01mm; border-color:#000000; border-style:solid; padding:4px;"><span style="color:#000080;background-color:#ffffff;font-weight:bold;">public</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">class</span><span style="background-color:#ffffff;"> ArtifactoryRestServlet </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">extends</span><span style="background-color:#ffffff;"> ServletContainer {<br /> </span><span style="color:#808000;background-color:#ffffff;">@Override<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">protected</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">void</span><span style="background-color:#ffffff;"> configure(ServletConfig config, ResourceConfig rc,<br /> WebApplication application) {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">super</span><span style="background-color:#ffffff;">.configure(config, rc, application);<br /><br /> Set<Object> pi = rc.getProviderInstances();<br /> pi.add(</span><span style="background-color:#ffffff;font-style:italic;">getSpringBeanInjector(</span><span style="background-color:#ffffff;">AuthorizationService.</span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">class</span><span style="background-color:#ffffff;">));<br /> pi.add(</span><span style="background-color:#ffffff;font-style:italic;">getSpringBeanInjector(</span><span style="background-color:#ffffff;">CentralConfigService.</span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">class</span><span style="background-color:#ffffff;">));<br /> pi.add(</span><span style="background-color:#ffffff;font-style:italic;">getSpringBeanInjector(</span><span style="background-color:#ffffff;">UserGroupService.</span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">class</span><span style="background-color:#ffffff;">));<br /> pi.add(</span><span style="background-color:#ffffff;font-style:italic;">getSpringBeanInjector(</span><span style="background-color:#ffffff;">AclService.</span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">class</span><span style="background-color:#ffffff;">));<br /> pi.add(</span><span style="background-color:#ffffff;font-style:italic;">getSpringBeanInjector(</span><span style="background-color:#ffffff;">RepositoryService.</span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">class</span><span style="background-color:#ffffff;">));<br /> pi.add(</span><span style="background-color:#ffffff;font-style:italic;">getSpringBeanInjector(</span><span style="background-color:#ffffff;">ArtifactoryContext.</span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">class</span><span style="background-color:#ffffff;">));<br /> pi.add(</span><span style="background-color:#ffffff;font-style:italic;">getSpringBeanInjector(</span><span style="background-color:#ffffff;">SecurityService.</span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">class</span><span style="background-color:#ffffff;">));<br /> }<br /><br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">public</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">static</span><span style="background-color:#ffffff;"> <T> SpringBeanInjector<T> getSpringBeanInjector(Class<T> beanInterface) {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">return</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">new</span><span style="background-color:#ffffff;"> SpringBeanInjector<T>(beanInterface);<br /> }<br /><br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">public</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">static</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">class</span><span style="background-color:#ffffff;"> SpringBeanInjector<T><br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">implements</span><span style="background-color:#ffffff;"> InjectableProvider<</span><span style="color:#808000;background-color:#ffffff;">SpringAutowired,</span><span style="background-color:#ffffff;"> Type>, Injectable<T> {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">private</span><span style="background-color:#ffffff;"> Class<T> </span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;">type;<br /><br /></span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">public</span><span style="background-color:#ffffff;"> SpringBeanInjector(Class<T> t) {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">this</span><span style="background-color:#ffffff;">.</span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;">type </span><span style="background-color:#ffffff;">= t;<br /> }<br /><br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">public</span><span style="background-color:#ffffff;"> ComponentProvider.Scope getScope() {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">return</span><span style="background-color:#ffffff;"> ComponentProvider.Scope.</span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;font-style:italic;">PerRequest;<br /></span><span style="background-color:#ffffff;"> }<br /><br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">public</span><span style="background-color:#ffffff;"> Injectable getInjectable(ComponentContext ic,<br /> </span><span style="color:#808000;background-color:#ffffff;">SpringAutowired </span><span style="background-color:#ffffff;">autowired, Type type) {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">if</span><span style="background-color:#ffffff;"> (type.equals(</span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">this</span><span style="background-color:#ffffff;">.</span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;">type)</span><span style="background-color:#ffffff;">) {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">return</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">this</span><span style="background-color:#ffffff;">;<br /> } </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">else</span><span style="background-color:#ffffff;"> {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">return</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">null</span><span style="background-color:#ffffff;">;<br /> }<br /> }<br /><br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">public</span><span style="background-color:#ffffff;"> T getValue(HttpContext context) {<br /> </span><span style="color:#808080;background-color:#ffffff;font-style:italic;">/*<br /> (ArtifactoryContext) context<br /> .getAttribute("org.springframework.web.context.ROOT");<br /> */<br /></span><span style="background-color:#ffffff;"> ArtifactoryContext springContext = ContextHelper.</span><span style="background-color:#ffffff;font-style:italic;">get(</span><span style="background-color:#ffffff;">);<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">if</span><span style="background-color:#ffffff;"> (springContext == </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">null</span><span style="background-color:#ffffff;">) {<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">return</span><span style="background-color:#ffffff;"> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">null</span><span style="background-color:#ffffff;">;<br /> }<br /> </span><span style="color:#000080;background-color:#ffffff;font-weight:bold;">return</span><span style="background-color:#ffffff;"> springContext.beanForType(</span><span style="color:#660e7a;background-color:#ffffff;font-weight:bold;">type)</span><span style="background-color:#ffffff;">;<br /> }<br /> }<br />}<br /></span></pre><br /><h4>Conclusion</h4><br />I really liked the WebBeans consept and the Guice injection, but actually working with these nice modern Framework architecture on a real case proved that's the way to go.<br />Morale: "Chapeau bas for Paul Sandoz at Sun"Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com0tag:blogger.com,1999:blog-1846725363010306463.post-241078354416383352008-02-29T21:11:00.001+02:002008-02-29T21:31:36.665+02:00Stellarium For Java Alpha release!After a lot of ups and downs, we (Jerome Beau and myself) are really happy to release an alpha version of Stellarium For Java (S4J in short).<br />This project is a migration of the very successful C++ project <a href="http://stellarium.org/">Stellarium</a> created by Fabien Chereau.<br />For the record, I really like this C++ version but I am missing a lot of features:<br /><ol><li>Ability to add stars catalogs like in <a href="http://celestia.sourceforge.net/">Celestia</a></li><li>Loading data on demand from the web instead of the resources in the installation</li><li>Resizable window (I have a Widescreen and need to play with config file)</li></ol>So, as a open source minded guy, I looked inside the code... And I got flashbacks! I found myself, back in time, when I was doing C++ for Video servers, and MFC applications.<br />I laughed, and then tried to find a Java version of any Astronomy software. I found <a href="http://stellarium4java.sourceforge.net/">Stellarium4Java</a>.<br />The project had started a year before with Jerome and Arnaud Barre. At the time, it was in the middle of the pure code migration from Stellarium C++ to Java.<br />It looked like a small decision at the time, so I joined the project! Today I can say: It took time and energy to get were we are today.<br />But, thanks to the great work of the JOGL team in Sun, and all the Java open source projects, <a href="https://stellarium4java.dev.java.net/files/documents/4463/87940/stellarium.jnlp">here</a> or <a href="http://stellarium4java.sourceforge.net/stellarium4java/jnlp/stellarium.jnlp">here</a> is the alpha version loading with Web Start. I'm still working on the web distribution of resources, so for the moment you will have to wait for 13Mo of download :(<br />There is a <a href="http://www.jfrog.org/confluence/display/S4J/Welcome+to+Stellarium4java">Wiki page</a> on jfrog with the jnlp links (they are still a moving target ;-) and the bug report access (be nice it's still alpha:-).<br />The most interesting part is that we got selected for a presentation at <a href="http://java.sun.com/javaone">JavaOne</a> this year to present this application. We will show how Java and the open source projects really helped us doing this, and what features we got for free from Java!<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://java.sun.com/javaone"><img style="margin: 0pt 0pt 10px 10px; float: left; cursor: pointer; width: 170px;" src="http://java.sun.com/javaone/images/2008/170x93_Speaker_v4.gif" alt="" border="0" /></a><br />Side note: This project makes me love Java, every time I'm freeing myself for it.Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com5tag:blogger.com,1999:blog-1846725363010306463.post-48779137195413617232008-02-18T12:19:00.000+02:002008-09-03T17:37:50.218+03:00Closure Campaign 2008After many discussion, it is <a href="http://java.net/pub/pq/196">election time (year) for closure</a>.<br />I voted for the readable, easy to grasp, and "almost" complete implementation of closure: FCM.<br />The posts of Stephen on the differences are very instructive:<br /><ol><li><a href="http://www.jroller.com/scolebourne/entry/closures_comparing_the_core_of">Closures - Comparing the core of BGGA, CICE and FCM</a></li><br /><li><a href="http://www.jroller.com/scolebourne/entry/closures_comparing_control_structures_of">Closures - Comparing control structures of BGGA, ARM and JCA</a></li><br /><li><a href="http://www.jroller.com/scolebourne/entry/java_7_comparing_closure_type">Closures - Comparing closure type inference</a></li></ol><br /><br />I hope this vote will have an influence on the JCP...Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com0tag:blogger.com,1999:blog-1846725363010306463.post-84540670432272716842008-01-28T21:54:00.000+02:002008-01-29T09:06:56.565+02:00Wild Java Properties, The Wild PartFollowing <a href="http://freddy33.blogspot.com/2008/01/wild-java-properties-road-so-far.html">my previous blog entry</a>, I tried to use Remi's property implementation for JPA or WebBeans. These 2 recent (WebBeans being still in diapers) frameworks really represent what I need from the property proposal. Generally I'd like to be able to do things like:<br /><h4>JPA (Hibernate)</h4><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@Id<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public property</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">long</span><span style="background-color: rgb(255, 255, 255);"> id get;<br /></span><span style="color: rgb(128, 0, 0);"><br /></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@Column(</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"FIRST_NAME"</span><span style="background-color: rgb(255, 255, 255);">)<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;"> property</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">firstName;<br /></span><br /><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> Criteria(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person</span><span><span style="background-color: rgb(255, 255, 255);">#</span></span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">firstName,</span><span style="background-color: rgb(255, 255, 255);"> value);</span></pre><h4>Validations</h4><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">protected</span><span style="background-color: rgb(255, 255, 255);"> <B,T> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">void</span><span style="background-color: rgb(255, 255, 255);"> propertyChanged(<br />java.lang.Property<B,T> </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">property,</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;"><br />Object </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">oldValue,</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Object </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">newValue)</span><span style="background-color: rgb(255, 255, 255);"> {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255); font-style: italic;">// Activate validation rules and so stop setting the value<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><span style="color: rgb(128, 0, 0);"> </span></pre><h4>WebBeans (JSR-299) or Guice</h4><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@Log<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">static</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;"> property</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Logger </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">log;</span><br /></pre><h4>Wicket or Swing</h4><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> TextField(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person</span><span><span style="background-color: rgb(255, 255, 255);">#</span></span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">firstName)</span><span style="background-color: rgb(255, 255, 255);">;<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> DynamicPanel().addAll(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person</span><span style="background-color: rgb(255, 255, 255);">.properties());</span><br /></pre>I'd like to say that Remi's work is truly amazing and is a good first draft. It is open source for us to analyze and contribute to. The benefits of properties in the cases above are:<br /><ol><li>No issue of annotations on either a field and/or getter/setter methods. All is centralized on one property declaration.</li><li>No reflection. All method calls from and to the framework are compiled and wired without using reflection. This is a great boost for UI and Dependency Injection framework.</li><li>Introspection without reflection.</li></ol>Trying to write the properties for the logger example (in fact any DI/IoC framework) and validations framework, I found that this implementation is not helping, and even worse - It's stopping me from doing what I need. Here are the limitations:<br /><ol><li>The first problem I encountered is that writing get and set blocks inline looks really good but breaks Object Orientation. I cannot do inheritance or use polymorphisms in these blocks. I ended up having more boilerplate code than without the usage of properties.</li><li>The second is that the private field exists only if there is no get/set block. So, if you wish to write getter/setter that uses a field, you need to declare this field. Suddenly, a lot of the generated syntactic sugar disappears and you find yourself writing almost as much as before.</li><li>The third issue is that encapsulation is asymmetric. What I mean by that is <span style="font-family:courier new;">System.out.println(firstName)</span> will use directly the field, but <span style="font-family:courier new;">this.firstName = "toto"</span> will become <span style="font-family:courier new;">this.setFirstName("toto");</span></li></ol><br />So, I tried to see how I can solve these limitations. Since modularity is the most important feature for me, a clean solution for the DI framework property issue is critical. This can really turn Java into a true Component based platform at its root. So as for the Logger issue I actually want to write:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">static</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;"> property</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Logger </span><span style="background-color: rgb(255, 255, 255);">log<br />init {</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">log </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Logger.</span><span style="background-color: rgb(255, 255, 255); font-style: italic;">getLogger(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person.</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);">.getName());};</span></pre>I added here some <span style="font-family:courier new;">init</span> block in the same line as the get/set block, since this is really what I want - to declare how the field is initialized. But, I'd like to write this once and reuse it. Furthermore, I want the <span style="font-family:courier new;">init</span> to be executed when the field (either static or instance) is declared, or on demand (lazy init). The only good way to do it is to have a class wrapping the Type2 property. It would look something like:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">final</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">static</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Property<Logger></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">log </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> LazyInitProperty() {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">protected</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">void</span><span style="background-color: rgb(255, 255, 255);"> init() {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">value </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Logger.</span><span style="background-color: rgb(255, 255, 255); font-style: italic;">getLogger(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person.</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);">.getName());<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);"> };<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">final</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Property<String></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">lastName </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Property<String></span><span style="background-color: rgb(255, 255, 255);">();<br /></span><span style="background-color: rgb(255, 255, 255);">}<br /></span><br /><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public class</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Property<</span><span style="background-color: rgb(255, 255, 255);">T> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">implements</span><span style="background-color: rgb(255, 255, 255);"> BaseProperty<T> {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> T </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">value;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> T get() {</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">value;</span><span style="background-color: rgb(255, 255, 255);">}</span><span style="color: rgb(128, 0, 0);"><br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">void</span><span style="background-color: rgb(255, 255, 255);"> set(T </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">value)</span><span style="background-color: rgb(255, 255, 255);"> {</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">this</span><span style="background-color: rgb(255, 255, 255);">.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">value </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">value;</span><span style="background-color: rgb(255, 255, 255);">}<br /></span><span style="background-color: rgb(255, 255, 255);">}<br /></span><span style="color: rgb(128, 0, 0);"><br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public abstract</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);"> LazyInitProperty<T> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">implements</span><span style="background-color: rgb(255, 255, 255);"> ReadOnlyProperty<T> {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">protected</span><span style="background-color: rgb(255, 255, 255);"> T </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">value;<br /></span> <span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> T get() {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">if</span><span style="background-color: rgb(255, 255, 255);"> (</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">value </span><span style="background-color: rgb(255, 255, 255);">== </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">null</span><span style="background-color: rgb(255, 255, 255);">)<br /></span><span style="background-color: rgb(255, 255, 255);"> init();<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">value;<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">protected</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">abstract</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">void</span><span style="background-color: rgb(255, 255, 255);"> init();<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>Of course it is missing a lot of good (or not) <span style="font-family:courier new;">synchronized</span>, but the idea is here. Basically I ended up with the <a href="http://joda.sourceforge.net/beans.html">Joda Beans</a> or <a href="https://bean-properties.dev.java.net/">java.net bean properties</a> concept, and also Yardena's <a href="http://sensualjava.blogspot.com/2007/11/properties-static-and-yet-dynamic.html">idea</a>.<br />This is an old idea about the notion that properties don't need to be a language feature. Take a look at <a href="https://bean-properties.dev.java.net/10things.html">What Makes Bean-Properties Special</a>, and 2 discussions on The Java Posse Google group: <a href="http://groups.google.com/group/javaposse/browse_thread/thread/800fd874d9366df2"> Wonder what Joe thinks of this properties solution</a>, <a href="http://groups.google.com/group/javaposse/browse_thread/thread/a49aaef19d0efd21/2088555d8ed8d3b4?lnk=gst&q=properties#2088555d8ed8d3b4">Still hope for first-class properties</a>.<br /><h4>Conclusion</h4>The solution to all of my problems: <b>Properties should not be a language feature!</b><br />When I got there for the first time I thought: WTF! But that's a logical step, isn't it? Properties are field level encapsulation with accessors and events. You can do this in any OO language with a class wrapping your field. So <span style="font-weight: bold;">why are we suffering?</span><br /><br />The main problem with open source properties projects is that all the classes and interfaces of PropertyType2<T> and PropertyType1<B,T> belong in the JDK. They need to be made a standard so that all framework and component will use them. To be useful, the bean-properties project needs to be in a JSR and included in Java 7. Why didn't any open source property project became a de-facto standard? It's amazing how many Property classes already exists out there!<br /><ol><li>Joda does binding with no boilerplate but changes the getter/setter style.</li><li>Bean-properties does the binding boilerplate code (and even setter/getter) with bytecode generation. Personally I prefer good syntactic sugar.</li><li>Annotations on these specific "Property" fields are not understood by 3rd party framework like JPA.</li><li>You need to declare public final fields.</li><li>Even if the amount of code is quite low, you still repeat yourself in the field declaration.</li><li>Bean introspection and Property object access are done using Strings and reflection.</li><li>The amount of features (Read, Write, initialized, Lazy, bind), types (Simple, Array, Set, Map,...), Modifiers (private, public, synchronized, volatile, for field/getter/setter), are generating a combinator which is impossible to implement with a Property<T> class hierarchy.</li></ol>Personally, I don't find items 1 and 4 to be a problem. The getter/setter style is related to encapsulation. It's the OO convention for dealing with properties. For me, automatically transforming <span style="font-family:courier new;">person.firstName="toto";</span> to <span style="font-family:courier new;">person.setFirstName("toto");</span> in Java today is very confusing. With Joda style, the type of <span style="font-family:courier new;">person.firstName</span> is <span style="font-family:courier new;">Property<String></span>, so when "toto" is assigned to it, something needs to box the value! Transforming <span style="font-family:courier new;">person.firstName="toto";</span> to <span style="font-family:courier new;">person.firstName.set("toto");</span> looks very close to the boxing/unboxing feature, doesn't it? Basically I feel comfortable with the idea that if you want to encapsulate a field in a Property, you should use a class for the encapsulation, not getXXX() and setXXX() methods. And if it's a class, make it clear, don't hide it. So, as for point 4 - a property may be visible or not. Here, I have a strong issue with visibility control around the field, getter, setter trio. Today, I do use different modifiers for each of them. Is it really useful?<br /><h4>So what!</h4>Well, my final wild idea is:<br /><ul><li>I want a unique Type1 interface in the JDK (like Remi's <span style="font-family:courier new;">Property<B,T></span>) called <span style="font-family:courier new;">PropertyAdaptor<B,T></span> to be separated from bean-properties class. This can (and will in my kijaro branch) be implemented with an abstract enum.</li><li>I want <span style="font-family:courier new;">Person#firstName</span> to return the above Type1 enum instance, and then use it to remove the need to change the class format (similar to what needs to be done in Remi's implementation today).</li><li>I want a nice, small and simple Type2 property interfaces and classes hierarchy, that are making a heavy usage of Annotations and the above unique Type1 enum entry for initialization. Basically this means making some "kind of" bean-properties project part of the Kijaro JDK (KDK ;-).</li><li>The Type1 methods "<span style="font-family:courier new;">T get(B)</span>" and "<span style="font-family:courier new;">void set(B,T)</span>" should delegate (by the javac phase) to "<span style="font-family:courier new;">T get()</span>" and "<span style="font-family:courier new;">set(T)</span>" of the Type2 instance. This would remove the need for reflection.</li><li>There should be no restrictions on extending classes or interfaces in the JDK based <span style="font-family:courier new;">Property<T></span> (Type2) hierarchy and on using them. This way, WebBeans and JPA can provide state-of-the-art properties implementations tuned for their needs. This would provide the loose coupling and transparent state management at a language level without reflection.</li><li>The property keyword should be replaced by the above annotation. This Annotation will activate all the syntactic sugar that would remove the standard properties boilerplate code. But, most of the actual Type2 implementation will come from the super class and extra annotations.</li></ul>Each time I apply the concept of Type2 property class provided and implemented by frameworks, I find a new way to clean and optimize my code:<br /><ul><li>Dependency Injection (OSGi), dynamic object allocation and redirection - can be done by calling set on the required properties, by having a smart get or by setting a dirty flag. Whatever the solution be, it is totally transparent to the business code declaring the property field.</li><li>Persistence framework providing validations (from DB type, data and annotations) and listening to property changes.</li><li>Swing bindings of course, but used by higher level framework that can manage full business objects and all their properties.</li></ul><h4>What I'm gonna' do!</h4> Independently of the wild crazy idea of properties by annotation as a language feature, the property list introspection will be done using a unique abstract enum <span style="font-family:courier new;">java.property.PropertyDefinition<B,T></span>:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">abstract</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">enum</span><span style="background-color: rgb(255, 255, 255);"> PropertyDefinition<B, T><br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">implements</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyAdaptor<</span><span style="background-color: rgb(255, 255, 255);">B, T> {<br /></span><span style="color: rgb(128, 0, 0);"></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">abstract</span><span style="background-color: rgb(255, 255, 255);"> T get(B </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">bean)</span><span style="background-color: rgb(255, 255, 255);">;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">abstract</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">void</span><span style="background-color: rgb(255, 255, 255);"> set(B </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">bean,</span><span style="background-color: rgb(255, 255, 255);"> T </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">newValue)</span><span style="background-color: rgb(255, 255, 255);">;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public abstract</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Property<</span><span style="background-color: rgb(255, 255, 255);">T> getProperty(B </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">bean)</span><span style="background-color: rgb(255, 255, 255);">;</span><span style="background-color: rgb(255, 255, 255);"></span><br /><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="background-color: rgb(255, 255, 255);">propertyName() {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> name();<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Class<</span><span style="background-color: rgb(255, 255, 255);">B> getBeanClass() {...</span><span style="background-color: rgb(255, 255, 255);">}<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Class<</span><span style="background-color: rgb(255, 255, 255);">T> getPropertyType() {...</span><span style="background-color: rgb(255, 255, 255);">}<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Annotation[</span><span style="background-color: rgb(255, 255, 255);">] getAnnotations() {...</span><span style="background-color: rgb(255, 255, 255);">}<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">boolean</span><span style="background-color: rgb(255, 255, 255);"> isReadable() {...</span><span style="background-color: rgb(255, 255, 255);">}<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">boolean</span><span style="background-color: rgb(255, 255, 255);"> isWritable() {...</span><span style="background-color: rgb(255, 255, 255);">}<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">int</span><span style="background-color: rgb(255, 255, 255);"> getFieldModifiers() {...</span><span style="background-color: rgb(255, 255, 255);">}<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">int</span><span style="background-color: rgb(255, 255, 255);"> getGetterModifiers() {...</span><span style="background-color: rgb(255, 255, 255);">}<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">int</span><span style="background-color: rgb(255, 255, 255);"> getSetterModifiers() {...</span><span style="background-color: rgb(255, 255, 255);">}<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>And the javac generated code will look like:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="background-color: rgb(255, 255, 255);">[...]<span style="font-family:mon;"><span style="font-weight: bold;"><br /></span></span></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">static</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">enum</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">properties<</span><span style="background-color: rgb(255, 255, 255);">T> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">extends</span><span style="background-color: rgb(255, 255, 255);"> </span><span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyDefinition</span></span><span style="background-color: rgb(255, 255, 255);"><</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person,</span><span style="background-color: rgb(255, 255, 255);">T> {<br /></span><span style="background-color: rgb(255, 255, 255);"> <String> firstName,<br /></span><span style="background-color: rgb(255, 255, 255);"> <String> lastName,<br /></span><span style="background-color: rgb(255, 255, 255);"> <Integer> age<br /></span><span style="background-color: rgb(255, 255, 255);"></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><span style="color: rgb(128, 0, 0);"> </span></pre>The above work is a simple merge of Remi's implementation and the abstract enum. On top of that, I'll implement the generic Type2 thing. First an annotation needs to be associated with a <span style="font-family:courier new;">Property<T></span> (Type2) abstract class. I'll use a meta-annotation <span style="font-family:courier new;">PropertyClass</span>, so anyone can declare a future <span style="font-family:courier new;">@Property</span> annotation.<br /><br />The meta annotation:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@Retention(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">RetentionPolicy.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">RUNTIME)<br /></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@Target(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ElementType.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">ANNOTATION_TYPE)<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> @</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">interface</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">PropertyClass </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Class </span><span style="background-color: rgb(255, 255, 255);">value();<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>The specific annotation for a basic property:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@Retention(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">RetentionPolicy.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">RUNTIME)<br /></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@Target(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ElementType.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">FIELD)<br /></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@PropertyClass(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">BasePropertyImpl.</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);">)<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> @</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">interface</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">BasicProperty </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyAccess </span><span style="background-color: rgb(255, 255, 255);">value();<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>The specific annotation for a property that can be bound:<pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@Retention(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">RetentionPolicy.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">RUNTIME)<br /></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@Target(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ElementType.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">FIELD)<br /></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@PropertyClass(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ObservablePropertyImpl.</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);">)<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> @</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">interface</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">ObservableProperty </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255); font-style: italic;">// Using FCM<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span><span style="background-color: rgb(255, 255, 255);">#</span></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">void</span><span style="background-color: rgb(255, 255, 255);">(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyStateEvent)</span><span style="background-color: rgb(255, 255, 255);"> onSet </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">default</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">null</span><span style="background-color: rgb(255, 255, 255);">;<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>Then, the bean class:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@BasicProperty(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyAccess.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">READ_WRITE)<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">firstName;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@ObservableProperty(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person</span><span><span style="background-color: rgb(255, 255, 255);">#</span></span><span style="background-color: rgb(255, 255, 255);">firstNameChanged)<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="background-color: rgb(255, 255, 255);">lastName;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@BasicProperty(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyAccess.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">READ_ONLY)<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">int</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">age;<br /></span><span style="color: rgb(128, 0, 0);"><br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">void</span><span style="background-color: rgb(255, 255, 255);"> firstNameChanged(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyStateEvent </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">se)</span><span style="background-color: rgb(255, 255, 255);"> {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">System.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">out.</span><span style="background-color: rgb(255, 255, 255);">println(</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"property changed "</span><span style="background-color: rgb(255, 255, 255);">+</span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">se)</span><span style="background-color: rgb(255, 255, 255);">;<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>And so the boilerplate code generated by javac will look like:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@BasicProperty(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyAccess.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">READ_WRITE)<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">final</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">BasePropertyImpl<String></span><span style="background-color: rgb(255, 255, 255);"> firstName =<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> BasePropertyImpl<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String></span><span style="background-color: rgb(255, 255, 255);">(properties.firstName);<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@ObservableProperty(</span><span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person</span></span><span><span style="background-color: rgb(255, 255, 255);">#</span></span><span style="background-color: rgb(255, 255, 255);">firstNameChanged)<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">final</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ObservablePropertyImpl<String></span><span style="background-color: rgb(255, 255, 255);"> lastName =<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> ObservablePropertyImpl<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String></span><span style="background-color: rgb(255, 255, 255);">(properties.lastName);<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@BasicProperty(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyAccess.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">READ_ONLY)<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">final</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">BasePropertyImpl<Integer></span><span style="background-color: rgb(255, 255, 255);"> age =<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> BasePropertyImpl<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Integer></span><span style="background-color: rgb(255, 255, 255);">(properties.age);<br /></span><span style="color: rgb(128, 0, 0);"><br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">void</span><span style="background-color: rgb(255, 255, 255);"> firstNameChanged(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyStateEvent </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">se)</span><span style="background-color: rgb(255, 255, 255);"> {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">System.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">out.</span><span style="background-color: rgb(255, 255, 255);">println(</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"property changed "</span><span style="background-color: rgb(255, 255, 255);">+</span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">se)</span><span style="background-color: rgb(255, 255, 255);">;<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="color: rgb(128, 0, 0);"><br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">static</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">enum</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">properties<</span><span style="background-color: rgb(255, 255, 255);">T> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">extends</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyDefinition<Person,</span><span style="background-color: rgb(255, 255, 255);">T> {<br /></span><span style="background-color: rgb(255, 255, 255);"> <String> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">firstName,<br /></span><span style="background-color: rgb(255, 255, 255);"> <String> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">lastName,<br /></span><span style="background-color: rgb(255, 255, 255);"> <Integer> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">age<br /></span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;"> </span><span style="background-color: rgb(255, 255, 255);">}<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>And all accessors to <span style="font-family:courier new;">person.firstName</span> will be wrapped in javac with <span style="font-family:courier new;">person.firstName.set() </span>and <span style="font-family:courier new;">person.firstName.get()</span>.<br /><br />This proposition respects Object Orientation, it is very flexible and open for future extension. It removes a lot of boilerplate code and makes Java ready for easy-to-use components. For example, by applying this solution IoC frameworks can really be "inverted". What I mean by that is that instead of trying to invoke setXXX() on the components at the right time (object life cycle and/or component state), they can simply provide a state-of-the-art getter in the property type2 class that will fetch the right object at the right time, all the time. This is transparent decoupling, keeping type safety and without using reflection.<br /><br />So it solves some (but not all) of the issues like:<br /><ul><li>Yardena's need for <a href="http://sensualjava.blogspot.com/2007/11/null-safe-access-to-properties.html">flexible property behavior</a> and <a href="http://sensualjava.blogspot.com/2007/11/walls-and-bridges.html">generics issue with properties</a>,</li><li>Eric Burke's ability to have <a href="http://stuffthathappens.com/blog/2007/11/19/my-own-java-7-suggestion/">more flexible binding</a></li><li>My need for using FCM pointer in properties declaration. Which methods init, bind, listen, and so on.</li></ul>The only thing that property as a language feature will have a hard time providing is dynamic creation of properties, but that's another story.<br /><br />A few more white nights are ahead of me so I can put all this in kijaro, I guess ;-) Unless someone finds a good reason to stop me in my wild Java experience!Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com12tag:blogger.com,1999:blog-1846725363010306463.post-86802318929263759142008-01-28T12:51:00.000+02:002008-01-29T08:19:51.580+02:00Wild Java Properties, The Road So FarFirst I'd like to thank Alex Miller for keeping good track of links regarding <a href="http://tech.puredanger.com/java7#property">properties in Java 7</a>,<br />I don't have to repeat them!<br /><br />I'll just add a few links:<br /><ul><li>The <a href="http://kijaro.dev.java.net/">kijaro</a> project has the first version of Remi Forax's Property implementation.</li><li>The <a href="http://docs.google.com/View?docid=dfhbvdfw_1f7mzf2">google doc</a> by Remi that documents this first usage of property as a language feature (as far as I know it's the only one).</li><li>The usage of this implementation with Beans Binding in Remi's <a href="http://weblogs.java.net/blog/forax/archive/2007/09/mixing_property_1.html">blog entry</a>.</li></ul>After integrating my work on Abstract Enum in the kijaro project (<a href="https://kijaro.dev.java.net/svn/kijaro/branches/abstractenum/">abstract enum branch</a>, <span style="font-style: italic;">to access it you need to be a kijaro reader</span>), I started merging Remi Forax's <a href="https://kijaro.dev.java.net/svn/kijaro/branches/properties/">branch</a> with one simple goal: Having the list of properties of any class automatically generated (syntactic sugar) as an enum! One of Remi's comments about using enum for property enumeration complained on the inability to use Generics with enums. With Abstract Enum it is possible, and I'll show how here.<br /><br />The benefits of using abstract enum to enumerate properties are:<br /><ul><li>Easy and type-safe properties introspection: MyClass.Property.values() returns the collection of MyClass.Property<MyClass,?>;</li><li>Easy and type safe conversion from a string to a property object: MyClass.Property.valueOf("firstName") returns MyClass.Property<MyClass,String> MyClass#firstName;</li><li>I can switch (aProperty) {case firstName:...};</li><li>MyClass#myProperty is an instance of MyClass.Property and so I can use == comparator with no risk.</li><li>I can use MyClass#myProperty in annotations that accept the abstract Enum PropertyAdaptor as parameter. Things like @LinkTo(Person#firstName).<br /></li></ul>Before I started coding I played, reviewed and analyzed the current implementation, and I will try to describe how it works. Here is the basic example using property keyword ("property" is not really a keyword since it can be used only before the type declaration of a member, but anyway):<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public property</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String</span><span style="background-color: rgb(255, 255, 255);"> firstName;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">property</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String</span><span style="background-color: rgb(255, 255, 255);"> lastName;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">property</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">int</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">age;<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>Analyzing the syntactic sugar generated by Remi's implementation, I needed to clarify where are the Type1 (Bean-independent property: aka per-class, property-proxy, property adaptor) and Type2 (Bean-attached property: aka per-instance) properties classes and instances. These types are nicely defined in Stephen Colebourne's blog <a href="http://www.jroller.com/scolebourne/entry/java_7_properties_terminology">Java 7 - Properties terminology</a>. Remi calls the Type1 a "Property Literal" and it is implemented with an anonymous class inheriting from a new class in the JDK: <a href="https://kijaro.dev.java.net/svn/kijaro/branches/abstractenum/jdk/src/share/classes/java/lang/Property.java">java.lang.Property</a>.<br /><br />For Type2 there is no need for a class since the basic property boilerplate code generated is:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">firstName;<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="background-color: rgb(255, 255, 255);">getFirstName() {</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">firstName;</span><span style="background-color: rgb(255, 255, 255);">}<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">void</span><span style="background-color: rgb(255, 255, 255);"> setFirstName(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">param)</span><span style="background-color: rgb(255, 255, 255);"> {</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">firstName </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">param;</span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>The above code is the syntactic sugar created by javac, and so not editable in any way. For the Type1 the generated code is:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">static</span><span style="background-color: rgb(255, 255, 255);"> Property<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String></span><span style="background-color: rgb(255, 255, 255);"> firstName() {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> Property<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String></span><span style="background-color: rgb(255, 255, 255);">(<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"firstName"</span><span style="background-color: rgb(255, 255, 255);">,<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String.</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);">,<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person.</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);">) {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="background-color: rgb(255, 255, 255);">get(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">person)</span><span style="background-color: rgb(255, 255, 255);"> {</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">person.</span><span style="background-color: rgb(255, 255, 255);">getFirstName();}<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">void</span><span style="background-color: rgb(255, 255, 255);"> set(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">person,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">s)</span><span style="background-color: rgb(255, 255, 255);"> {</span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">person.</span><span style="background-color: rgb(255, 255, 255);">setFirstName(</span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">s)</span><span style="background-color: rgb(255, 255, 255);">;}<br /></span><span style="background-color: rgb(255, 255, 255);"> };<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>And for Bean introspection (getting the list of properties) another piece is generated:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">static</span><span style="background-color: rgb(255, 255, 255);"> Property<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person,</span><span style="background-color: rgb(255, 255, 255);">?>[] properties() {</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">$PROPERTIES;</span><span style="background-color: rgb(255, 255, 255);">};<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">static</span><span style="background-color: rgb(255, 255, 255);"> Property<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person,</span><span style="background-color: rgb(255, 255, 255);">?>[] $PROPERTIES = new Property[]{</span><span style="background-color: rgb(255, 255, 255); font-style: italic;">firstName(),lastName(),age()</span><span style="background-color: rgb(255, 255, 255);">};</span><br /></pre>This is the code for a basic property, but there are more features implemented like:<br /><ul><li>Generating a getter method only or a setter method only</li><li>Implementing getter and setter inline of the property declaration</li><li>And the very powerful 'bound' which allows automatic events on setXXX() without boilerplate code.</li></ul>For example if lastName is read only with a provided block and age is bound, the Person class will be:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> property String firstName;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> property String lastName get { </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"XXX"</span><span style="background-color: rgb(255, 255, 255);">; };<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> property </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">int</span><span style="background-color: rgb(255, 255, 255);"> age bound;<br /></span><span style="color: rgb(128, 0, 0);"><br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">protected</span><span style="background-color: rgb(255, 255, 255);"> <B,T> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">void</span><span style="background-color: rgb(255, 255, 255);"> propertyChanged(java.lang.Property<B,T> </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">property,</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Object </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">oldValue,</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Object </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">newValue)</span><span style="background-color: rgb(255, 255, 255);"> {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">System.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">out.</span><span style="background-color: rgb(255, 255, 255);">println(</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"property changed "</span><span style="background-color: rgb(255, 255, 255);">+</span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">property+</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">" "</span><span style="background-color: rgb(255, 255, 255);">+</span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">oldValue+</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">" "</span><span style="background-color: rgb(255, 255, 255);">+</span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">newValue)</span><span style="background-color: rgb(255, 255, 255);">;<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>Here is the generated code:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;"></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="background-color: rgb(255, 255, 255);">getLastName() {</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"XXX"</span><span style="background-color: rgb(255, 255, 255);">;}<br /></span><br /><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">static</span><span style="background-color: rgb(255, 255, 255);"> Property<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String></span><span style="background-color: rgb(255, 255, 255);"> lastName() {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> Property<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String></span><span style="background-color: rgb(255, 255, 255);">(<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"lastName"</span><span style="background-color: rgb(255, 255, 255);">,<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String.</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);">,<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person.</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);">) {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="background-color: rgb(255, 255, 255);">get(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">person)</span><span style="background-color: rgb(255, 255, 255);"> {</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">person.</span><span style="background-color: rgb(255, 255, 255);">getLastName();}<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">void</span><span style="background-color: rgb(255, 255, 255);"> set(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">person,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">s)</span><span style="background-color: rgb(255, 255, 255);"> {</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">throw</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> UnsupportedOperationException();}<br /></span><span style="background-color: rgb(255, 255, 255);"> };<br /></span><span style="background-color: rgb(255, 255, 255);">}<br /></span><br /><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">int</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">age;<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">int</span><span style="background-color: rgb(255, 255, 255);"> getAge() {</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">age;</span><span style="background-color: rgb(255, 255, 255);">}<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">void</span><span style="background-color: rgb(255, 255, 255);"> setAge(</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">int</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">param)</span><span style="background-color: rgb(255, 255, 255);"> {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">int</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">oldValue </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">age;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">age </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">param;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">this</span><span style="background-color: rgb(255, 255, 255);">.<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person,Integer></span><span style="background-color: rgb(255, 255, 255);">propertyChanged(</span><span style="background-color: rgb(255, 255, 255); font-style: italic;">age(</span><span style="background-color: rgb(255, 255, 255);">),</span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">oldValue,</span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">param)</span><span style="background-color: rgb(255, 255, 255);">;<br /></span><span style="background-color: rgb(255, 255, 255);">}<br /></span><br /><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">static</span><span style="background-color: rgb(255, 255, 255);"> Property<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Integer></span><span style="background-color: rgb(255, 255, 255);"> age() {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> Property<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Integer></span><span style="background-color: rgb(255, 255, 255);">(<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"age"</span><span style="background-color: rgb(255, 255, 255);">,<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">int</span><span style="background-color: rgb(255, 255, 255);">.</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);">,<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person.</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);">) {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Integer </span><span style="background-color: rgb(255, 255, 255);">get(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">person)</span><span style="background-color: rgb(255, 255, 255);"> {</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">person.</span><span style="background-color: rgb(255, 255, 255);">getAge();}<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">void</span><span style="background-color: rgb(255, 255, 255);"> set(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Person </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">person,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Integer </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">s)</span><span style="background-color: rgb(255, 255, 255);"> {</span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">person.</span><span style="background-color: rgb(255, 255, 255);">setAge(</span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">s)</span><span style="background-color: rgb(255, 255, 255);">;}<br /></span><span style="background-color: rgb(255, 255, 255);"> };<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>That's a lot of syntactic sugar, but that's the point of properties, isn't it: <a href="http://smallwig.blogspot.com/2007/10/value-objects-wtf2.html">Value objects WTF!!?!!2!</a>. This property implementation works very well for Swing and Beans Binding implementation like Remi's demo shows. You can also write very quickly generic equals and hashcode methods based on the properties list. But, as a backend developer I also need properties.<br /><br />Property as language feature is not just syntactic sugar generation it's really solving a problem that just CANNOT be solved in Java today: How can I safely (which means maintaining type safety) pass a field or method (which are the elements that represent a property today - getter/setter) to a framework like JPA, WebBeans, Validations framework, Wicket, Swing Bindings, and all the others developed out there? Today, you NEED to pass a String (EL) and do reflection. That does not make sense. When I know a UI component is bound to Person.firstName, why do I need to write bind(Person.class, "firstName") and loose type safety, compiler existence check (whether or not firstName property exists), and so refactoring ability.<br /><br /><a href="http://freddy33.blogspot.com/2008/01/wild-java-properties-wild-part.html">Next post</a>, I'll expose how I wish to have properties for all ;-)Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com2tag:blogger.com,1999:blog-1846725363010306463.post-19191969820899855562008-01-28T12:21:00.000+02:002008-01-28T23:55:10.157+02:00The Java Wild series!This blog has been silent for more than 2 months now... And this just after I started some good work on the great <a href="http://kijaro.dev.java.net/">kijaro project</a>. I'm really happy to say that it was for a great trip to Guatemala where we picked up our newly adopted child.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://lh4.google.com/frederic.simon/R1MC_G6QdqI/AAAAAAAABGU/R_ShWqiBpWU/pasaporte%201.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 158px; height: 212px;" src="http://lh4.google.com/frederic.simon/R1MC_G6QdqI/AAAAAAAABGU/R_ShWqiBpWU/pasaporte%201.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br />This is the first time ever since I discovered coding (1985) that I did not write one line of code for 2 months in a row ;-) Very relaxing, and I still have a very hard time going back ;-)<br /><br />Anyway, even without coding I've spent a lot of time reading blogs and article about The End of Java and other worrying thoughts. All this ended up in this Java Wild entries. Playing with Kijaro and the different patches that can change the Java language clarified what I really want from Java and the platform.<br /><br />The conclusion is that the most critical feature needed for Java 7 (and maybe even for 6 update N) is: Modularity. The JDK needs to be built out of nice dependent modules with superpackages and JSR-277 (or OSGi) packaging. This is critical for the future of Java. And Stephen's <a href="http://www.jroller.com/scolebourne/entry/is_the_jcp_broken">blog entry</a> about the JCP inefficiency and OSGi vs. JSR-277 war is, for me, the darkest cloud above Java.<br /><br />Mostly my thinking about the topics covered in my Java Wild series goes: "If it helps write to modules: good". But beside this I really went wild, and it was fun.<br /><ol><li>The first entry is about properties that really got <a href="http://weblogs.java.net/blog/cayhorstmann/archive/2007/12/properties_get_1.html">bad publicity</a> lately. One entry was too much, so there is: "<a href="http://freddy33.blogspot.com/2008/01/wild-java-properties-road-so-far.html">Wild Java Properties, the Road so Far</a>" and "<a href="http://freddy33.blogspot.com/2008/01/wild-java-properties-wild-part.html">Wild Java Properties, The Wild Part</a>".<br /></li><li>The second entry is about extension methods and how Modules and API can really benefits from them.</li><li>And the third is, again, about checked exceptions.</li></ol><br />I wanted to publish all these in one go, because I hate suspense ;-), but time is running out. So, I'll do it in steps.<br /><br />Anyway, the "sad" conclusion of all this work and thinking is that I bought the Scala book, and starting today, will start playing on the grass of Java neighbors. May be, it is really greener?Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com0tag:blogger.com,1999:blog-1846725363010306463.post-60154873842531799212007-11-12T20:14:00.000+02:002007-11-13T00:19:56.703+02:00The Ugly Duckling of Java!It took me time to find a good title. It could have been things like:<br /><ul><li>What's so ugly about explicit type parameters?</li><li>Done with inference!</li><li>Let's pave the way for reification and promote explicit type parameters!</li></ul>Chaotic java already made a similar point: <a href="http://chaoticjava.com/posts/can-someone-please-explain-type-inference-to-me/">Can someone please explain type inference to me?</a>.<br /><br />But all these compiler language terms, are showing off for no reason. The problem is not so complicated, but the stakes are high. Like Eric Burke says in his blog <a href="http://stuffthathappens.com/blog/2007/11/07/a-syntax-trick-i-was-not-aware-of/">A Syntax Trick I Was Not Aware Of</a>, there is a syntax in Java that very few people use and encounter: Explicit type arguments or parameters. One of the rare places where you may have encountered it, is in the JLS and javac code and test code. So, it looks like:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">List<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">empty </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Collections.</span><span style="background-color: rgb(255, 255, 255);"><</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String></span><span style="background-color: rgb(255, 255, 255); font-style: italic;">emptyList(</span><span style="background-color: rgb(255, 255, 255);">);</span></pre>The first reaction, for most Java developers, is: WTF?!<br /><br />But I remember the first time I started converting some 1.4 code to use generics and wrote:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(128, 0, 0);"></span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Map<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Integer,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Map<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String,Thing></span><span style="background-color: rgb(255, 255, 255);">> </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">messages;</span><span style="color: rgb(128, 0, 0);"></span></pre>Wow, that's a lot of <>! And when I saw the amount of bugs the compiler gave me (wrong casting and objects in put()), I really thanked the <>, and asked for more ;-)<br /><br />Why, the Java compiler wants to hide <> of explicit type parameter?<br />On IntelliJ the <String> before the emptyList method, is underlined with the remark: Explicit type arguments can be inferred. Basically, it means the compiler can be smart enough to replace the content of <> with the correct type. Great, at first. But wait?<br />Like Stephan says in <a href="http://stephan.reposita.org/archives/2007/11/05/explicit-static-types-are-not-for-the-compiler-but-for-the-developer-duh/">Explicit Static Types are not for the Compiler, but for the Developer - Duh</a>, the compiler knows a lot more stuff. He can remove a lot of all this types we are writing.<br />I love strongly type Java, and all the types repetition. I love the types in the code because it's more readable.<br /><br />Question: Why explicit type parameters are an exception?<br />Answer: It got the Ugly Duckling stamp for some reason! Some said that it was dangerous for kittens!<br /><br />Personally, I think there are 2 reasons:<br />- When Java 5 came out it looked like too much <> all over and Sun tried to remove some unneeded ones.<br />- It lacks consistency. I would really like to know, why explicit type parameters are declared BEFORE the method name? When, in constructor and type declaration, they are declared AFTER. In the later, they are enforced, and everybody is using them!<br /><br />Another worrying inconsistency that may appear in Java 7 is around the "Short instance creation" issue. For example the nicest proposal so far is Neal's <a href="http://gafter.blogspot.com/2007/07/constructor-type-inference.html">constructor type inference</a>. I really like this proposal because it enables inference to work, but you SEE it working. It's not hidden woodoo compiler stuff. According to this proposal instead of:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">List<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">list </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> ArrayList<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String></span><span style="background-color: rgb(255, 255, 255);">();</span></pre>you'd write:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">List<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String></span><span style="background-color: rgb(255, 255, 255);"> list = </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> ArrayList<>();</span></pre><br />Again, a strange sense of peculiarity for the method emptyList. In the <a href="http://tech.puredanger.com/java7#typeinference">type inference</a> block of Alex Miller Java 7 page, you see the peculiar treatment of methods compare to types.<br />Why nobody wants:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">List<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String></span><span style="background-color: rgb(255, 255, 255);"> empty = Collections.<>emptyList();</span></pre>It's the same, no? Let's be consistent!<br /><br />Now, the main big issue that I have with this inference vs. explicit issue, is that it's moving Java away from reification of generics. It's going in the wrong direction. I just refactored some JPA code from:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(128, 0, 0);"></span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255); font-style: italic;">// The Class of the bean implementaion provided by<br /></span><span style="color: rgb(128, 0, 0);"></span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255); font-style: italic;">// the framework and unknown to the client<br /></span><span style="color: rgb(128, 0, 0);"></span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Class </span><span style="background-color: rgb(255, 255, 255);">implClass = ...;<br /></span><span style="color: rgb(128, 0, 0);"></span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">MyBeanInterface </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">b </span><span style="background-color: rgb(255, 255, 255);">= (</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">MyBeanInterface)</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">em.</span><span style="background-color: rgb(255, 255, 255);">find(</span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">implClass,pk)</span><span style="background-color: rgb(255, 255, 255);">;</span><span style="color: rgb(128, 0, 0);"> </span><br /></pre>to<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">MyBeanInterface </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">b </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">em.</span><span style="background-color: rgb(255, 255, 255);"><</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">MyBeanInterface></span><span style="background-color: rgb(255, 255, 255);">find(</span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">implClass,pk)</span><span style="background-color: rgb(255, 255, 255);">;</span></pre>It may be just changing casting to generics. But that's the point of generics being way nicer and more powerful.<br /><br />The other point is, when generics will be reified I'd be closer to the perfect methods:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(128, 0, 0);"></span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">MyBeanInterface </span><span style="background-color: rgb(255, 255, 255);">b = </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">em.</span><span style="background-color: rgb(255, 255, 255);"><</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">MyBeanInterface></span><span style="background-color: rgb(255, 255, 255);">find(</span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">pk)</span><span style="background-color: rgb(255, 255, 255);">;<br />or with VISIBLE type inference<br /></span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">MyBeanInterface </span><span style="background-color: rgb(255, 255, 255);">b = </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">em.</span><span style="background-color: rgb(255, 255, 255);"><>find(</span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">pk)</span><span style="background-color: rgb(255, 255, 255);">;</span><span style="color: rgb(128, 0, 0);"> </span></pre>These methods will find the implementation from the interface. Exactly what I need, the client code doesn't know about the implementation class, and the code is very clean and readable.<br /><br />Today, because of erasure, in most methods (80%) that use generic types, you end up having Class<T> or Collection<T> as a parameter. So, inference works most of the time, and it's saving us from having to visualize the Ugly Duckling. For sure, it worked.<br /><br />Now, for the 20% that still resist the roman empire of javac guru inference power, a new wave is coming. They want to write a "smarter" javac, that will make inference work (Check Kevin Bourrillion and Bob Lee comments <a href="http://stuffthathappens.com/blog/2007/11/07/a-syntax-trick-i-was-not-aware-of/">here</a>).<br /><br />Here, there is a shift in the javac thinking, and it's going against readability, since: The "smarter" (or magical) the compiler is, the less "readable" your code is. Furthermore, inference will never be (by definition) 100% sure. So, why bother? The final code is more readable anyway...<br /><br />IMHO: The kittens are safe, and reifying generics is more important than inference.Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com5tag:blogger.com,1999:blog-1846725363010306463.post-39933273139575287422007-11-08T19:00:00.000+02:002007-11-08T09:26:32.429+02:00Is JSF following EJB road?First I have to be clear: I don't like JSF!<br /><br />But, I did not like EJB 1.0 when it came out. And still, I did bet on it's success.<br /><br />When EJB 1.0 came out I just finished my personal implementation of a CORBA Application Server, so this new Specification was "way below" my stuff. I was young, but still you cannot stop the machine coming from Sun, BEA and after quite some time IBM.<br />EJB came in a world were crazy techies (like me) thought they can build great servers which can handle enormous load. So, this specification really calm down crazy development and provided a good base for containers (usage and implementation).<br />But, it was flawed, right from the beginning.<br />All the API, interfaces and design concentrated on showing off the "great" power of the Application Server. Look how I can passivate/activate, look I can do security and transaction, and look I even save in DB for you. And for every "look" as a poor developer you needed to answer (implement, declare) something.<br />There was no escape, your code was full of unwanted pollution.<br />EJB 2.0 did not solve the problem and actually added more "look" at my beautiful AS: Messaging and CMP.<br /><br />We had to wait for JBoss guys to take over EJB specification for 3.0, to finally end the developer nightmare.<br /><br />And now, the funny trick. Please replace in the above EJB with JSF...<br />Amazing, it fits.<br /><br />JSF came when Web UI was a total mess (All Struts usage override most configuration and basic classes) and everyone had his own "best/better" implementation.<br />So, JSF did some clean up in Web UI design and implementation.<br />But, JSF is really "showing off": Look my nice lifecycle in 42 steps, Look my nice big list of jsp tags/attributes, Look my nice EL, Look my nice XML configuration, and so on.<br />By "showing off" I mean that you need to fill all this with a lot of unreadable and incomprehensible repetition. And the worst of it you need to master all this in order to:<br />- debug correctly,<br />- integrate external stuff (Ajax4JSF and so on),<br />- create just one JSF UI component (Does someone sells T-shirt with: I wrote my JSF component! without breaking the lifecycle?),<br />- write stupid HTML pages.<br /><br />A really good description of all JSF flaws are listed in Gavin blog: <a href="http://in.relation.to/Bloggers/Everyone/Tag/EE6+Wishlist">EE6 Wichlist</a><br />In this blog entries, the first one on EJB the second on JSF, looking quickly at the code examples you understand the gap. EJB is full of nice Annotations and Meta Annotations (the future for sure), and JSF full of ugly XML and Expression Language (scheduled to die).<br /><br />The biggest conceptual flaw of JSF is the usage of EL.<br />EL is breaking encapsulation, in term of IoC: it's on the wrong side of the road. Ophir pointed me to a nice essay from Terence Parr "<a href="http://www.cs.usfca.edu/%7Eparrt/papers/mvc.templates.pdf" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">Enforcing Strict Model-View Separation in Template Engines </a>", that really nicely proves my point.<br />A UI definition (Web page, Swing panel, ...) should not know about the object graph. If I am a UI designer, I'm not a business modeler.<br />The answer is in architecture like Wicket and JSR-295 (The EL in this Beans Binding is due to the lack of property support).<br />In these good architecture: The UI components have an ID related to the page/panel, and the Java developers bind data to these components and receive events from these components. This is the good way to do UI, integrate UI design and manage UI logic. From experience, it works great.<br /><br />All the other flaws are due to the age of JSF and the fact that it was written for ugly request/response Web UI behavior.<br /><br />So JSF is today at the stage of EJB 1.0, I can see JSF 2.0 pushing more in the wrong direction, and so having finally a JSF 3.0 were developers will stop having nervous shake when they hear: JSF!Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com3tag:blogger.com,1999:blog-1846725363010306463.post-38816667696317871262007-11-02T16:43:00.001+02:002007-11-07T18:05:42.467+02:00Playing with the full abstract enum!Since Neal Gafter released the <a href="http://gafter.blogspot.com/2007/10/java-closures-first-prototype.html">closure prototype</a>, Ricky Clarkson has been having a lot of fun. He wrote 2 nice blogs:<br /><ul><li><a href="http://rickyclarkson.blogspot.com/2007/10/java-7-example-pattern-matching.html">Java 7 Example - Pattern Matching</a></li><li><a href="http://rickyclarkson.blogspot.com/2007/11/java-7-example-writing-your-own-foreach.html">Java 7 Example - Writing Your Own Foreach</a></li></ul>Both have "Java 7 Example" in their titles - So closures is going in Java 7: Got that!<br /><br />The Java code is a little scary at first, but after a while it works, you can read it. IMHO: all the inlining of closure syntax can get very confusing. I know they supposed to be, but I played with the code and when you create variables for the closures it helps increased readability.<br /><br />Anyway, I really like the fact that you can now really test, today, closures and their impact on your code.<br />All this, gave me the idea to do the same for abstract enum.<br /><br />The reasons for abstract enum (and there are more I'm sure) are:<br /><ol><li>I wanted abstract enum for solving the property binding issue in a type safe way.</li><li>I found out that you cannot use String Enum.name() and int Enum.ordinal() methods as annotations parameters.</li><li>I know there are way too many strings in annotations (methods, fields, scopes, states, package, groups, ...). I don't like strings describing my code.</li><li>While I was at it, <a href="http://forums.java.net/jive/thread.jspa?threadID=26751&tstart=15">Steven Coco</a> asked for generics in enums, so it's there also. That happens to be quite an interesting feature, that was already there from Neal (but buggy ;-).<br /></li></ol>For all those reasons I know abstract enum is a good thing. Changing the javac to implement this feature is at least 2 orders of magnitude easier than implementing closures, so it was within my reach ;-)<br /><br />I have exposed some mercurial repositories for <a href="http://www.jfrog.org/hg/openJDK/MASTER/langtools/">langtools</a> and for the <a href="http://www.jfrog.org/hg/openJDK/MASTER/jdk/">jdk</a>. You need to have a mercurial working copy of openJDK, then inside langtools run:<br />hg pull http://www.jfrog.org/hg/openJDK/MASTER/langtools<br /><br />You can "hg log" to see what's going on, then do:<br />hg up<br /><br />The <a href="http://www.jfrog.org/hg/openJDK/MASTER/jdk/rev/4ed0e928e970">patch</a> for the JDK is very small, and actually (in my view), it is just another valid way (in a Java 5 environment) to do Class.isEnum() and Annotations parsing. The new JDK is needed for the tests to pass because abstract enum are not considered enum by java.lang.Class otherwise :-(.<br /><br /><h4>Type safe reflection</h4><br />The solution for field binding is straight forward. The abstract enum looks like:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">abstract</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">enum</span><span style="background-color: rgb(255, 255, 255);"> FieldDefinition {<br /></span><span style="background-color: rgb(255, 255, 255);"></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> Field reflectField;<br /></span><span style="color: rgb(128, 0, 0);"><br /></span><span style="background-color: rgb(255, 255, 255);"></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> Field getField() {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">if</span><span style="background-color: rgb(255, 255, 255);"> (reflectField == </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">null</span><span style="background-color: rgb(255, 255, 255);">) {<br /></span><span style="background-color: rgb(255, 255, 255);"> Class modelClass = </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">null</span><span style="background-color: rgb(255, 255, 255);">;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">try</span><span style="background-color: rgb(255, 255, 255);"> {<br /></span><span style="background-color: rgb(255, 255, 255);"> modelClass = </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">this</span><span style="background-color: rgb(255, 255, 255);">.getClass().getEnclosingClass();<br /></span><span style="background-color: rgb(255, 255, 255);"> reflectField = modelClass.getDeclaredField(name());<br /></span><span style="background-color: rgb(255, 255, 255);"> } </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">catch</span><span style="background-color: rgb(255, 255, 255);"> (NoSuchFieldException e) {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">throw</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> ObjectMappingException(</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"Field "</span><span style="background-color: rgb(255, 255, 255);"> + </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">this</span><span style="background-color: rgb(255, 255, 255);"> +</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;"></span><span style="background-color: rgb(255, 255, 255);"><br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">" does not exists in "</span><span style="background-color: rgb(255, 255, 255);"> + modelClass, e);<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> reflectField;<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span>}<br /></pre><br />And to use it in my Value Object it looks like:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;"><span style="font-family:monospace;">p</span>ublic</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ModelMock </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">firstName;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">lastName;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">int</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">age;<br /></span><span style="color: rgb(128, 0, 0);"><br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">static</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">enum</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">fields </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">extends</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">FieldDefinition </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">firstName,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">lastName,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">age;<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>Of course is not as good as properties as a language support, but it solves my problem. From the above, I extended to property using generics. So, the PropertyDefinition takes the property type as generic parameter, so the generic getter/setter methods are generic typed. I took (type 1 and 2) from Stephen Colebourne's Weblog <a href="http://www.jroller.com/scolebourne/entry/java_7_properties_terminology"><b>Java 7 - Properties terminology</b></a>, and converted it.<br /><br />Before abstract enum there was:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">MyBeanBefore </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">firstName;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">lastName;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">BigDecimal </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">height;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Date </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">dob;<br /></span><span style="color: rgb(128, 0, 0);"><br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyDefinition<MyBeanBefore,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String></span><span style="background-color: rgb(255, 255, 255);"> firstNameProperty() {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> ReflectionAttachedProperty.create(</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">this</span><span style="background-color: rgb(255, 255, 255);">, </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"firstName"</span><span style="background-color: rgb(255, 255, 255);">);<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyDefinition<MyBeanBefore,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String></span><span style="background-color: rgb(255, 255, 255);"> lastNameProperty() {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> ReflectionAttachedProperty.create(</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">this</span><span style="background-color: rgb(255, 255, 255);">, </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"lastName"</span><span style="background-color: rgb(255, 255, 255);">);<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyDefinition<MyBeanBefore,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">BigDecimal></span><span style="background-color: rgb(255, 255, 255);"> heightProperty() {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> ReflectionAttachedProperty.create(</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">this</span><span style="background-color: rgb(255, 255, 255);">, </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"height"</span><span style="background-color: rgb(255, 255, 255);">);<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyDefinition<MyBeanBefore,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Date></span><span style="background-color: rgb(255, 255, 255);"> dobProperty() {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> ReflectionAttachedProperty.create(</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">this</span><span style="background-color: rgb(255, 255, 255);">, </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"dob"</span><span style="background-color: rgb(255, 255, 255);">);<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>always using strings :-( And now:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@FieldPrefix(</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"_"</span><span style="background-color: rgb(255, 255, 255);">)<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">MyBean </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">_firstName;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">_lastName;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">BigDecimal </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">_height;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Date </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">_dob;<br /></span><span style="color: rgb(128, 0, 0);"><br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">static</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">enum</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">properties<</span><span style="background-color: rgb(255, 255, 255);">V> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">extends</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyDefinition<MyBean,</span><span style="background-color: rgb(255, 255, 255);">V> {<br /></span><span style="background-color: rgb(255, 255, 255);"> <String> firstName,<br /></span><span style="background-color: rgb(255, 255, 255);"> <String> lastName,<br /></span><span style="background-color: rgb(255, 255, 255);"> <BigDecimal> height,<br /></span><span style="background-color: rgb(255, 255, 255);"> <Date> dob<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>This code actually compile and run (with the strange _ prefix ;-). Cool, no. The full code is under subversion <a href="https://www.jfrog.org/svn-jfrog/abstract-enum/fields-enum">here</a>.<br />Now, with this, I can find usages, refactor, and get compilation errors for every binding using a field that does not exist. Like in here:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(128, 0, 0);"></span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">MyBean </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">bean </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">MyBean(</span><span style="background-color: rgb(255, 255, 255);">);<br /></span><span style="color: rgb(128, 0, 0);"></span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyAdaptor<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">MyBean,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Date></span><span style="background-color: rgb(255, 255, 255);"> dobProperty = MyBean.properties.dob;<br /></span><span style="color: rgb(128, 0, 0);"></span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PropertyInstance<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Date></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">dobPropertyInstance </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">dobProperty.</span><span style="background-color: rgb(255, 255, 255);">getPropertyInstance(</span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">bean)</span><span style="background-color: rgb(255, 255, 255);">;</span><br /></pre>The type safety is not entirely true, since in my own Model class I get Runtime error for mismatching fields in the "fields" enumeration. This can be solve in 2 ways: make fields a keyword in Java and generate it automatically ;-), and/or test your model class and fields enumeration correctly.<br /><br /><h4>abstract enum in Annotations</h4><br />Like with closures, today when I encounter a problem in some projects, I often end up with: That will have been a lot faster and nicer with closures, and that will be solved perfectly with abstract enum. Now, I know it's the standard disease of being too much into it ;) But still I think it's true.<br /><br />And abstract enum in Annotations is, for me, a really powerful feature.<br /><br />So, one problem I had was with JPA schema names, cache names, and fields associations. All those information need to be provided as strings inside annotations. And of course they are repeating themselves a lot, they get misspelled, and basically you loose the strong typing.<br />So, I wanted to use enum (Schemas, Caches, Fields) to control the strings. But I would hit a dead end: Enum.name() is not a string literal, so you cannot use it in Annotations.<br />Now, with abstract enum, I have way more flexibility and type safety.<br />For the caches for example I can have Hibernate declaring something like:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">abstract</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">enum</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">CacheDefinition </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="color: rgb(128, 0, 0);"></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">CacheConcurrencyStrategy </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">defaultUsage;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">defaultInclude;<br /></span><span style="color: rgb(128, 0, 0);"><br /></span><span style="background-color: rgb(255, 255, 255);"> CacheDefinition(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">CacheConcurrencyStrategy </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">defaultUsage,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">defaultInclude)</span><span style="background-color: rgb(255, 255, 255);"> {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">this</span><span style="background-color: rgb(255, 255, 255);">.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">defaultUsage </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">defaultUsage;<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">this</span><span style="background-color: rgb(255, 255, 255);">.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">defaultInclude </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">defaultInclude;<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="color: rgb(128, 0, 0);"><br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">CacheConcurrencyStrategy </span><span style="background-color: rgb(255, 255, 255);">getDefaultUsage() {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">defaultUsage;<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="color: rgb(128, 0, 0);"><br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="background-color: rgb(255, 255, 255);">getDefaultInclude() {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">defaultInclude;<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><span style="color: rgb(128, 0, 0);"> </span></pre>and then in my application:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">enum</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">MyCaches </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">extends</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">CacheDefinition </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">references(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">CacheConcurrencyStrategy.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">READ_ONLY,</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"all"</span><span style="background-color: rgb(255, 255, 255);">),<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">business(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">CacheConcurrencyStrategy.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">TRANSACTIONAL,</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"non-lazy"</span><span style="background-color: rgb(255, 255, 255);">);<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre>to use in:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@Cache(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">MyCaches.</span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold; font-style: italic;">business)<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Action </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="background-color: rgb(255, 255, 255);"> ...<br /></span><span style="background-color: rgb(255, 255, 255);">}</span><br /></pre><br />I wrote a blog (<a href="http://freddy33.blogspot.com/2007/07/jpa-namedqueries-and-jdbc-40.html">JPA NamedQueries and JDBC 4.0</a>) about how to solve the string association issue in JPA named queries. Frank Cornelis <a href="http://cup-of-java.blogspot.com/2007/08/java-ee-6-wishlist-continued.html">answered</a> with an addition that enables the reuse of query methods. The main problem with this addition is it adds more strings in annotations.<br />This case can also be solved with abstract enum.<br /><br />So, if you reached there and you like the language feature of abstract enum: Vote for the RFE: <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570766">6570766</a>.Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com2tag:blogger.com,1999:blog-1846725363010306463.post-35762213236337248592007-10-28T14:42:00.000+02:002007-11-03T11:23:42.204+02:00Web Beans and Modules!After some good work, the JSR-299 group released an early draft, first published on <a href="http://in.relation.to/Bloggers/JSR299WebBeansEarlyDraft">Gavin King's blog</a>, and now on the <a href="http://jcp.org/aboutJava/communityprocess/edr/jsr299/">JCP site</a>.<br /><br />The <a href="http://in.relation.to/Bloggers/TheWebBeansManifesto">spirit of Web Beans</a> is really good, and the way the annotations came out is very promising. I have nothing to say but compliment the Component Types, Component Bindings, Scopes, Injection, and Interceptors. The Event has the good approach (Event type filter), but looks young at the moment.<br /><br />Web Beans is really the state of the art "Educational Framework". The technical base is already explored (Guice, Spring, Seam) and is not so complex, but the impact on the developer thinking is really significant. Like every good "Educational Framework" (Struts, Spring, Seam), it makes it harder to do the "bad thing" (hacking, ugly coupling) than the right one (framework driven injection and loose coupling).<br />I know that if developers start to use these Annotations their code will get cleaner, more readable and manageable.<br /><br />But, reading through the specs and especially, "4.4.2 Interceptors bindings" and "8. Packaging and configuration", I felt like something was wrong: Where are my Web Beans modules?<br />I don't want to get into the argument of OSGi or JSR-277, but I was expecting a more modular approach of Web Beans Injection.<br />What I mean, is that I would like to see a Web Beans "core" defining all the above Annotations for a pure J2SE environment. This would be the specification of how to use Dependency Injection Annotations. On top of that, another specification on how to provide "Components Provider/Injectors" for JEE, JSF, EJB, MDB and so on.<br />For example, I want to be able to do:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(128, 0, 0);"></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@Log<br /></span><span style="color: rgb(128, 0, 0);"></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">private</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Logger </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">log;</span></pre><br /><br />just by adding log4j-web-beans.jar in my classpath. In this jar Log4J will provide the Web Beans Component for my class and my environment.<br />So, with this approach all the EJB, JSF & JEE stuff that really don't have to be there, can be specified separately as: jee5-web-beans.jar, ejb-web-beans.jar, mdb-web-beans.jar, etc.<br />I think it will make the specifications easier to read and a lot more flexible for all the great future components ;-)<br /><br />Since I don't like people that complain without proposing something of their own, I tried to see how to do this with the current specification. And, basically it's not missing much.<br />Today in EJB3 environment, the first thing I do is creating an Interceptor that can inject components from Spring or other sources in my Session Beans. The injection is based on my project level Annotations and it bridges Spring and EJB3 nicely.<br />So a first solution (not good but...) is to use javax.interceptor.InvocationContext. If the Web Beans container is adding some entry in getContextData(), I can find out the Component Type, the Scope, and other information and decide how to populate all the @Log fields.<br /><br />A nicer solution will be to have Annotations specified by JSR-299, that will allow me to write something like:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@ComponentProvider<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Jee5ComponentProvider </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="color: rgb(128, 0, 0);"><br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@Provides(EJB.</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);">)<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Object </span><span style="background-color: rgb(255, 255, 255);">getEJB(</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">WebBeansContext </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">wbc)</span><span style="background-color: rgb(255, 255, 255);"> {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">try</span><span style="background-color: rgb(255, 255, 255);"> {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">return</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> InitialContext().lookup(<br /></span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);"> wbc.</span><span style="background-color: rgb(255, 255, 255);">getDestinationField().getType().getName());<br /></span><span style="background-color: rgb(255, 255, 255);"> } </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">catch</span><span style="background-color: rgb(255, 255, 255);"> (</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">NamingException </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">e)</span><span style="background-color: rgb(255, 255, 255);"> {<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">e.</span><span style="background-color: rgb(255, 255, 255);">printStackTrace();<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">throw</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> RuntimeException(</span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">e)</span><span style="background-color: rgb(255, 255, 255);">;<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);"> }<br /></span><span style="background-color: rgb(255, 255, 255);">}</span></pre><br />Here I really did not investigate enough, but I know I'm missing @ComponentProvider and WebBeansContext in the current specification.<br />What do you think?Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com3tag:blogger.com,1999:blog-1846725363010306463.post-44463564541403722502007-10-17T20:34:00.000+02:002007-10-30T00:02:17.125+02:00JSR-299 or Web BeansAfter postponing for too long, I finally decided to look at <a href="http://jcp.org/en/jsr/detail?id=299">Web Beans</a> or JSR-299.<br /><br />The story is that for our seminar <a href="http://www.pc.co.il/Index.asp?CategoryID=82&ArticleID=649">JavaEdge 2007</a> we invited Gavin King. He accepted to come and to talk about his new JSR, and this was the first time I encountered <span style="font-weight: bold;">"Web Beans"</span>.<br />And to tell the truth: The name gave me a cold shower ;-)<br />What? Gavin started as a backend guru for O/R Mapping, then decided to target the issue of Web development with Seam, and now is "may be" going even higher in the stack with some UI components spec!<br />It really sounded like Gavin was leading the new spec for some JSF UI widgets :-(<br /><br />This name really put me off, and so I postponed reading about "Web Beans".<br />That was a mistake, and a really bad move.<br /><br />When I saw in Gavin <a href="http://in.relation.to/2570.lace">blog</a>, that he was excited about exposing the work done in JSR-299 group, I decided to get into it.<br /><br />And the conclusion is:<br /><ol><li>From my personal technical glossary, "Web Beans" has nothing to do with Web, and Beans are not UI JavaBeans.</li><li>Gavin did it again.</li></ol>Before Hibernate the O/R Mapping tools concentrated more on showing off their feature list than helping developer having a persistent model. For Gavin what's important is how the user (poor developer) will communicate with the framework. Powerful features should not show off and complicate the API or the tool. Once the usage is clear, the framework follows.<br />So after Seam and easy @Conversation, he's leading this great JSR.<br /><br />"Web Beans" is basically a good (meaning pushing forward) standardization of IoC and DI concepts using Annotations. The overview from <a href="http://in.relation.to/2595.lace">Gavin slides of the Silicon Valley JUG</a>, is a really good start to understand what JSR-299 is about.<br /><br />"Web Beans" really uses the good Guice framework, removes the issue of static scopes in Seam, and helps you create your own meaningful project Annotations. And all this is done true to the Java spirit: in a readable way.<br />JSR-299 answers some of my needs I had in <a href="http://freddy33.blogspot.com/2006/01/mda-is-dead-long-live-aada.html">AADA</a> and I hope it will help projects moving towards creation of more custom Annotations.<br /><br />So, please, change the name...<br /><ul><li>First, for once the JSR number is very easy to remember ( 300 - 1 easy to find an association).</li><li>Second I always associated <span style="font-weight: bold;">Beans</span> with <span style="font-weight: bold;">JavaBeans</span> Swing UI or Struts, and I never felt it was connected with the concept of <span style="font-weight: bold;">Components</span> used in Spring, Guice, Seam or JSR-299. By the way, in "Web Beans" there is no @Bean but only @Component.</li><li>Third, I found the term API (Application Programming Interface) does not match today's specification code and technique. EJB3, JAXWS and so on don't export a DLL API. They help you code. For example, In JPA (<a href="http://jcp.org/en/jsr/detail?id=317">Java Persistence API</a>) more than 90% of the code are Annotations not Interfaces. It should be Java Persistence Annotations, no? You can argue that Annotations are indeed interfaces in Java, and that it will not change the acronym ;-)</li></ul>Anyway here are 2 possible names:<br />- Dependency Injection API (or Annotations)<br />- Components Injection API (or Java Components Injection Annotations ;-)<br /><br />Finally, JSR-299 DIA also generalizes the concept of Injector injected by injection from the Dependency Injection framework, and I'm really happy about it ;-)Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com1tag:blogger.com,1999:blog-1846725363010306463.post-17428212563318879142007-08-01T00:26:00.001+03:002008-09-28T14:59:04.323+03:00JPA NamedQueries and JDBC 4.0In one project doing a migration from EJB 2.0 to EJB 3, I found this:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@Entity(</span><span style="background-color: rgb(255, 255, 255);">name = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"Action"</span><span style="background-color: rgb(255, 255, 255);">)<br /></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@NamedQueries(</span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@NamedQuery(</span><span style="background-color: rgb(255, 255, 255);">name = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"Action.findAll"</span><span style="background-color: rgb(255, 255, 255);">, query = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"SELECT o FROM Action o"</span><span style="background-color: rgb(255, 255, 255);">),<br /></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@NamedQuery(</span><span style="background-color: rgb(255, 255, 255);">name = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"Action.findByExtCode"</span><span style="background-color: rgb(255, 255, 255);">, query = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"SELECT o FROM Action o WHERE o.externalCode = ?1"</span><span style="background-color: rgb(255, 255, 255);">),<br /></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@NamedQuery(</span><span style="background-color: rgb(255, 255, 255);">name = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"Action.findByDescription"</span><span style="background-color: rgb(255, 255, 255);">, query = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"SELECT o FROM Action o WHERE o.description = ?1"</span><span style="background-color: rgb(255, 255, 255);">),<br /></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@NamedQuery(</span><span style="background-color: rgb(255, 255, 255);">name = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"Action.findManualActions"</span><span style="background-color: rgb(255, 255, 255);">, query = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"SELECT o FROM Action o WHERE o.manual=?1"</span><span style="background-color: rgb(255, 255, 255);">),<br /></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@NamedQuery(</span><span style="background-color: rgb(255, 255, 255);">name = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"Action.findSelectedActions"</span><span style="background-color: rgb(255, 255, 255);">, query = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"SELECT o FROM Action o WHERE o.actionType.id <> 3"</span><span style="background-color: rgb(255, 255, 255);">),<br /></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@NamedQuery(</span><span style="background-color: rgb(255, 255, 255);">name = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"Action.findFlowActions"</span><span style="background-color: rgb(255, 255, 255);">, query = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"SELECT o FROM Action o WHERE o.actionType.id=3"</span><span style="background-color: rgb(255, 255, 255);">),<br /></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@NamedQuery(</span><span style="background-color: rgb(255, 255, 255);">name = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"Action.findByActionFlowId"</span><span style="background-color: rgb(255, 255, 255);">, query = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"SELECT o FROM Action o JOIN o.actionFlows af WHERE af.id = ?1"</span><span style="background-color: rgb(255, 255, 255);">)<br />})<br /></span></pre>The code looks like this, because when doing named queries in JPA the name need to be unique for the WHOLE persistence unit. So, we agreed about the naming convention "[entity name].[finder name]" for the name of the query.<br />It is actually quite nicer an more manageable than EJBQL in xml files, but still there is quite a bunch of copy/paste, String that are not constants, and the usage of named queries is here more problematic than EJB 2.0 home interfaces.<br />The usage looks like:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="background-color: rgb(255, 255, 255);"></span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Query </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">namedQuery </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">em.</span><span style="background-color: rgb(255, 255, 255);">createNamedQuery(</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"Action.findByExtCode"</span><span style="background-color: rgb(255, 255, 255);">);<br /></span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">namedQuery.</span><span style="background-color: rgb(255, 255, 255);">setParameter(</span><span style="color: rgb(0, 0, 255); background-color: rgb(255, 255, 255);">1</span><span style="background-color: rgb(255, 255, 255);">, </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"001"</span><span style="background-color: rgb(255, 255, 255);">);<br /></span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ActionBean </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">actionBean </span><span style="background-color: rgb(255, 255, 255);">= (</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ActionBean)</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">namedQuery.</span><span style="background-color: rgb(255, 255, 255);">getSingleResult();<br /></span></pre>And this is for only one parameter...<br /><br />The possible code errors (due to lack of static typing) we get here are:<br /><ol><li>Errors on the string name for the namedQuery</li><li>Errors on the parameter position (the named queries annotation is in the model not close to the business logic executing queries)</li><li>Errors in Casting</li></ol>So, when looking at this, I thought about <a href="http://jcp.org/aboutJava/communityprocess/edr/jsr221/index2.html">JDBC 4.0</a> (jsr 221 chapter 20 of the spec) and finally managed to create a nice <a href="http://www.jfrog.org/viewvc/jfrog/greenhouse/jpa/trunk/src/main/java/org/jfrog/greenhouse/jpa/framework/NamedQueryDynamicProxy.java?view=markup">dynamic proxy</a> doing the work for JPA.<br />It is quite clear looking at the code above, a JPA named query can be defined as an interface method. It has:<br /><ul><li>a name (entityName + methodName),</li><li>a list of parameters (ordered or named),</li><li>and a result (list or single).</li></ul>So, with the dynamic proxy the usage code looks like:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ActionQuery </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">actionQuery </span><span style="background-color: rgb(255, 255, 255);">= </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">NamedQueriesFactory.</span><span style="background-color: rgb(255, 255, 255); font-style: italic;">getQueryProxy(</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ActionQuery.</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">class</span><span style="background-color: rgb(255, 255, 255);">, </span><span style="color: rgb(102, 14, 122); background-color: rgb(255, 255, 255); font-weight: bold;">em)</span><span style="background-color: rgb(255, 255, 255);">;<br /></span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ActionBean </span><span style="background-color: rgb(255, 255, 255);">action = </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">actionQuery.</span><span style="background-color: rgb(255, 255, 255);">findByExtCode(</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"001"</span><span style="background-color: rgb(255, 255, 255);">);<br /></span></pre>And the Queries interface:<br /><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@JpaQueriesInterface(</span><span style="background-color: rgb(255, 255, 255);">prefix = </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"Action"</span><span style="background-color: rgb(255, 255, 255);">)<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">interface</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ActionQuery </span><span style="background-color: rgb(255, 255, 255);">{<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Collection<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ActionBean></span><span style="background-color: rgb(255, 255, 255);"> findAll();<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ActionBean </span><span style="background-color: rgb(255, 255, 255);">findByExtCode(</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">extCode)</span><span style="background-color: rgb(255, 255, 255);">;<br /></span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@JpaQueryUseParamNames<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ActionBean </span><span style="background-color: rgb(255, 255, 255);">findByDescription(</span><span style="color: rgb(128, 128, 0); background-color: rgb(255, 255, 255);">@JpaParamName(</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"description"</span><span style="background-color: rgb(255, 255, 255);">)</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">String </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">description)</span><span style="background-color: rgb(255, 255, 255);">;<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Collection<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ActionBean></span><span style="background-color: rgb(255, 255, 255);"> findManualActions(</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">boolean</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">manual)</span><span style="background-color: rgb(255, 255, 255);">;<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Collection<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ActionBean></span><span style="background-color: rgb(255, 255, 255);"> findSelectedActions();<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Collection<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ActionBean></span><span style="background-color: rgb(255, 255, 255);"> findFlowActions();<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">public</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">Collection<</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">ActionBean></span><span style="background-color: rgb(255, 255, 255);"> findByFlowActionId(</span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">long</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">flowActionId)</span><span style="background-color: rgb(255, 255, 255);">;<br />}<br /></span></pre>Which gets all the advantage of strong Java typing.<br />So, the code of my small running example is here:<br /><a href="http://subversion.jfrog.org/jfrog/greenhouse/jpa/trunk/">http://subversion.jfrog.org/jfrog/greenhouse/jpa/trunk/</a> and it's using maven of course...<br />Now, the next step is to use the Annotated Query Interface has NamedQuery provider so it will really look like JDBC 4.0.Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com6tag:blogger.com,1999:blog-1846725363010306463.post-6243992318679784722007-07-14T09:56:00.000+03:002007-08-01T01:19:46.702+03:00The need for RAEWith all the discussions around language changes in Java7, there is a need for democratic vote on what should be included or not.<br />But in today's <a href="http://bugs.sun.com/bugdatabase/index.jsp">Bug Database</a> of Sun you can only vote <span style="font-weight: bold;">for</span> a RFE (Request For Enhancements), you cannot vote <span style="font-weight: bold;">against</span>. And when you look inside the <a href="http://bugs.sun.com/bugdatabase/top25_rfes.do">Top 25 RFEs</a> you can see that there is big controversy on most of them, and that Sun act as a final "benevolent dictator".<br />For example here is an extract of the top 25 RFEs that may have an impact on Java7/OpenJDK and the language:<br /><table border="0" cellspacing="0" cols="3" frame="void" rules="none"> <colgroup><col width="54"><col width="86"><col width="541"></colgroup> <tbody> <tr> <td style="border: 1px solid rgb(0, 0, 0);" align="left" height="17" width="54"><b>Votes</b></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left" width="86"><b>Bug ID </b></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left" width="541"><b>Synopsis</b></td> </tr> <tr> <td style="border: 1px solid rgb(0, 0, 0);" sdval="580" sdnum="1033;" align="left" height="17"><span style="color: rgb(255, 0, 0);">580</span></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left"><a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4449383">4449383</a></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left">Support For 'Design by Contract', beyond "a simple assertion facility"</td> </tr> <tr> <td style="border: 1px solid rgb(0, 0, 0);" sdval="341" sdnum="1033;" align="left" height="17"><span style="color: rgb(255, 0, 0);">341</span></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left"><a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4820062">4820062</a></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left">Provide "struct" syntax in the Java language</td> </tr> <tr> <td style="border: 1px solid rgb(0, 0, 0);" sdval="303" sdnum="1033;" align="left" height="17"><span style="color: rgb(255, 0, 0);">303</span></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left"><a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4267080">4267080</a></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left">break up rt.jar into downloadable-on-demand components to reduce jre size</td> </tr> <tr> <td style="border: 1px solid rgb(0, 0, 0);" sdval="197" sdnum="1033;" align="left" height="17"><span style="color: rgb(255, 0, 0);">197</span></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left"><a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4093687">4093687</a></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left">Extension of 'Interface' definition to include class (static) methods.</td> </tr> <tr> <td style="border: 1px solid rgb(0, 0, 0);" sdval="172" sdnum="1033;" align="left" height="17"><span style="color: rgb(255, 0, 0);">172</span></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left"><a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4905919">4905919</a></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left">RFE: Operator overloading</td> </tr> <tr> <td style="border: 1px solid rgb(0, 0, 0);" sdval="171" sdnum="1033;" align="left" height="17"><span style="color: rgb(255, 0, 0);">171</span></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left"><a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4801527">4801527</a></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left">Support Repository in Java Web Start</td> </tr> <tr> <td style="border: 1px solid rgb(0, 0, 0);" sdval="152" sdnum="1033;" align="left" height="17"><span style="color: rgb(255, 0, 0);">152</span></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left"><a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4727550">4727550</a></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left">Advanced & Raw Socket Support (ICMP, ICMPv6, ping, traceroute, ...)</td> </tr> <tr> <td style="border: 1px solid rgb(0, 0, 0);" sdval="125" sdnum="1033;" align="left" height="17"><span style="color: rgb(255, 0, 0);">125</span></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left"><a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4313887">4313887</a></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left">New I/O: Improved filesystem interface</td> </tr> <tr> <td style="border: 1px solid rgb(0, 0, 0);" sdval="122" sdnum="1033;" align="left" height="17"><span style="color: rgb(255, 0, 0);">122</span></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left"><a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4129445">4129445</a></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left">An API to incrementally update ZIP files</td> </tr> <tr> <td style="border: 1px solid rgb(0, 0, 0);" sdval="122" sdnum="1033;" align="left" height="17"><span style="color: rgb(255, 0, 0);">122</span></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left"><a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4650689">4650689</a></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left">RFE: Java needs public API for FTP</td> </tr> <tr> <td style="border: 1px solid rgb(0, 0, 0);" sdval="113" sdnum="1033;" align="left" height="17"><span style="color: rgb(255, 0, 0);">113</span></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left"><a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4648386">4648386</a></td> <td style="border: 1px solid rgb(0, 0, 0);" align="left">Simplify deployment and versioning by embedding JAR files within each other</td> </tr> </tbody> </table><br />From this list, I'm personally <span style="font-weight: bold;">for</span> "java kernel: 4267080", "New IO: 4313887", <span style="font-weight: bold;">against</span> "Operator overloading: 4905919", "Design By Contract: 4449383", and still <span style="font-weight: bold;">undecided</span> on "struct: 4820062".<br />So, how can we compile all the votes?<br />Sun needs to create RAE (Request Against Enhancements) in parallel of each controversial RFE.<br />To compile the votes, we will need better access to the Bug Database, since listing all RFEs and RAEs by importance is impossible from the current Web Interface.<br />The need for RAE came from the big controversy around <a href="http://freddy33.blogspot.com/2007/07/voting-for-good-exception-handling.html">checked exceptions</a> and I was really missing a nice compilation result of for/against.<br /><br />Today, Java is Open Source and the full activation of the <a href="http://openjdk.java.net/groups/gb/">OpenJDK Governance Board</a> is in progress. I will really like to know what to expect in the language. Having a compilation of popular RFE/RAE will help.<br />But until the process of the Governance Board is not clarified, Sun position will be the decisive one. And here the current position of Danny Coward, JavaSE Platform lead, is very confusing: "Seeking a small number of changes for Java SE 7 platform" (from <a href="http://developers.sun.com/learning/javaoneonline/j1sessn.jsp?sessn=TS-2383&yr=2007&track=5">Java One presentation</a>).Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com0tag:blogger.com,1999:blog-1846725363010306463.post-49535728098893756682007-07-10T21:05:00.000+03:002007-08-01T01:20:35.282+03:00Voting for Good Exception Handling<div style="text-align: justify;">When getting ready for a conference I gave for Sun (<a href="http://www.il.sun.com/sunnews/events/2007/javaday/pdf/track1/Java7-A.lot.to.be.waiting.for_v03.pdf">Java 7 - A lot to be waiting for</a> !), I came across this blog: <a href="http://cafe.elharo.com/java/voting-for-checked-exceptions/">Voting for Checked Exceptions</a>. It was in response of Neal Gafter's blog: <a href="http://gafter.blogspot.com/2007/05/removing-language-features.html">Removing Language Features?</a>.<br />The list of comments is very long, and I never found the time to read them, until now. I really liked what went on there (except the personal attacks), and I want to try to summarize the arguments, as I view them. The arguments are also exposed in Neal's blog comments but there was a lot less arguments...<br />I'm not trying to be impartial, since for me it's clear: <span style="font-style: italic;">Checked Exceptions should go.</span><br />Page 49 of the presentation has the bullets that summarize my view on Checked Exceptions.<br /></div><br />So here are the valid arguments I saw in the blog comments:<br /><br /><span style="font-weight: bold;">Checked Exceptions avoid the digging of what can go wrong</span><br /><span style="font-style: italic;"><br />Description:</span><br /><div style="text-align: justify;">In other languages that does not have checked exceptions, it takes a good amount of time, thinking, QA cycles, and production crashes before you know which exception types can be thrown by a specific method.<br />Basically, since the API does not declare what it can throws, as a caller you need to "guess" what can happen or catch everything and try to re-throw what should not have been catch.<br /></div><span style="font-style: italic;"><br />Validity:</span><br /><div style="text-align: justify;">The point is totally valid, but for me it does not make the balance tip on either side of the checked/unchecked issue.<br />Good API should declare a good throws clause list of what can happen. This is good design and OO practice. And a caller that knows what to do in case of an exception should catch them and handle them correctly. This is valid for Exceptions in general, checked or unchecked. The issue is that in Java nobody declares unchecked exceptions in the throws clause, it looks stupid. I don't know why, I think it's just a stupid habit.<br /></div><br /><div style="text-align: justify;">Still there is a point against checked exceptions here. As an API writer, you are "forcing" the caller to catch ALL of the "checked" exceptions declared in your throws clause. This simple fact, breaks OO, forces some design concept on the caller (where to put the exception handler and method throws clauses), and generate all the "bloat".<br /></div><br /><br /><span style="font-weight: bold;">Checked Exceptions helps you remember that you need to handle them</span><br /><br /><span style="font-style: italic;">Description:</span><br /><div style="text-align: justify;">During coding you encounter methods throwing exceptions and so you need to handle them at some point. So, with checked exceptions, for a certain class or module, the list of exceptions to handle is well define.<br />This point was made especially when some lazy developers will ignore unchecked exceptions all together. If the compiler will not bother, exceptions are ignore.<br /></div><br /><span style="font-style: italic;">Validity:</span><br />Here the point fails on multiple accounts:<br /><div style="text-align: justify;">1) Forcing the catching of an exception on a lazy developer is worse than let him go along. You end up with things like:<br /></div><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">try</span><span style="background-color: rgb(255, 255, 255);"> {<br /></span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">o </span><span style="background-color: rgb(255, 255, 255);">= getObject(</span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">id)</span><span style="background-color: rgb(255, 255, 255);">;<br />} </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">catch</span><span style="background-color: rgb(255, 255, 255);"> (</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PersistenceException </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">e)</span><span style="background-color: rgb(255, 255, 255);"> {<br /></span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255); font-style: italic;">// Should not happen I just saved it before<br /></span><span style="background-color: rgb(255, 255, 255);">}<br /></span></pre><div style="text-align: justify;">Which is my personal nightmare on many projects. When the code is full of these it's totally impossible to debug, understand the behavior, or move forward. It's desperate. Simply put:<br /></div><span style="font-style: italic;">"Empty catch block are worse than no catch at all"</span><br /><br /><div style="text-align: justify;">2) Listing and catching all checked exceptions does not cover your needs in exception handling. Even in Java there are unchecked exceptions, and in today's framework you have more and more of them. So exceptions will slip through anyway.<br /></div><br /><div style="text-align: justify;">3) Putting the error handling in the middle of the logical code is a very bad practice. You end up copy/pasting catch block all over, and if you need a small change in error handling, well... forget it.<br />The error handling is a layer of your module/component/architecture, that should be transparent and decoupled from your code.<br />This is the only way to make sure you are handling correctly ALL exceptions. This is the power and design in modern framework using AOP Interceptors. So, like in Spring, JBossMC, EJB3, Hibernate, you need a framework layer to catch Throwable and find out which exception handler should take care of what at which layer. Perfect, unbeatable, robust, user friendly, HA, and more.<br /></div><br /><br /><span style="font-weight: bold;">You don't have to handle checked exception just pass them on</span><br /><br /><span style="font-style: italic;">Description:</span><br /><div style="text-align: justify;">If inside a method you are calling a method with checked exceptions and you don't know how to handle it, just add it to your (big) list of throws clause, someone up the call stack will take care of it.<br /></div><br /><span style="font-style: italic;">Validity:</span><br /><div style="text-align: justify;">This is the most non valid argument for checked exceptions, and the main reason why Java should have only unchecked exceptions.<br />I don't know many projects where any developer can just add a checked exception to the signature without blinking (the same for removing one). Checked Exceptions makes API throws clause fixed for eternity. If you add, you suffer, if you remove, you're lynched...<br /></div><div style="text-align: justify;">So, the only way is to create non meaningful generic Super Exception class (like IOException) that every methods throws.<br />Basically, this argument contradict the 2 previous ones which are a lot more valid.<br />On the other hand this feature is mandatory for normal coding. Everybody agree:<br /></div><span style="font-style: italic;">"If you don't know what to do with an exception, don't handle it"<br /><br /></span><div style="text-align: justify;">This is critical, for "robust" application, so you need to find a way to answer this argument. Here is the proof that checked exceptions are contradicting their own benefits.<br /></div><br /><br /><span style="font-weight: bold;">Checked Exceptions are recoverable, Unchecked are bugs</span><br /><br /><span style="font-style: italic;">Description:</span><br /><div style="text-align: justify;">The principle of separation between checked/unchecked is well defined by ELH:<br />"as in section 8 of <a href="http://www.amazon.com/exec/obidos/ISBN=0201310058/ref=nosim/cafeaulaitA">Effective Java</a>. [...] checked exceptions are for unpredictable environmental conditions such as I/O errors and and XML well-formedness violations while unchecked exceptions are for program failures that should be caught during testing, such as array index out of bounds or null pointers."<br /></div><br /><span style="font-style: italic;">Validity:</span><br /><div style="text-align: justify;">Classifying, and understanding what the error IS, is a critical step in good error handling. You need to send a good type of exception, for the good type of error, with the maximum amount of information (which file, to read, to write, which DB, which XML tag, ...).<br />Forcing yourself to create meaningful Exception is a difficult step, but one that always pays off. Add all the parameters you can, create meaningful messages, and use the good exception class.<br />But, the separation "unpredictable environmental conditions" vs. "program failures" is highly subjective, and always false once you climb one layer in your architecture. The kind of comment <span style="font-style: italic;">"Should not happen I just saved it before"</span> proves my point.<br />Typing is good (IOException, NPE), but to enforce the global decision for all Java software ever written that IOException is an "unpredictable environmental conditions" does not make any sense.<br />Furthermore, the "forcing" of handling of "unpredictable environmental conditions" generates a lot of "development by exceptions". Basically, if you know that the file may not be there, I really prefer if the developer just create a File() object and test file.exists() instead of waiting for IOException.<br /></div><br /><span style="font-weight: bold;">Experiences with Checked Exceptions</span><br /><br /><div style="text-align: justify;">1) In my experience to handle correctly an exception you need a lot of infrastructure information: How to display errors to the user (Web or Fat client), How to log, How to translate (code, language), How to trap, Severity detector, transaction access, ...<br />And to provide all this information to the inner logical code that need to wrap checked exceptions is a big burden for the application. Just pass the exception, my exception handler will handle it correctly.<br />Since, creating an exception handler with IOC and/or AOP that has access to all the above managers, is quite easy and clean.<br /></div><br /><div style="text-align: justify;">2) We are doing lately a lot of migration to JPA, and more than 50% of our headaches are on checked exceptions. We found out that checked exceptions promotes indirectly the bad habit of development by exceptions:<br /></div><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">try</span><span style="background-color: rgb(255, 255, 255);"> {<br />o = getObject(</span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">id)</span><span style="background-color: rgb(255, 255, 255);">;<br />} </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">catch</span><span style="background-color: rgb(255, 255, 255);"> (</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">PersistenceException </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">e)</span><span style="background-color: rgb(255, 255, 255);"> {<br /></span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255); font-style: italic;">// Object not found create it<br /></span><span style="background-color: rgb(255, 255, 255);"> o = create();<br />}<br /></span></pre><div style="text-align: justify;">And changing the API signatures, removing FinderException from EJB 2.0, or the annoying CloneableException is a true nightmare.<br /></div><br /><div style="text-align: justify;">3) Good coding with checked exceptions is sometimes very very tedious. For example the correct management of FileInputStream.close() and it's IOException is getting out of hand:<br /></div><pre style="border: 0.01mm solid rgb(0, 0, 0); padding: 4px; line-height: 130%; background-color: rgb(255, 255, 255);font-family:monospace;"><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">FileInputStream </span><span style="background-color: rgb(255, 255, 255);">is = </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">null</span><span style="background-color: rgb(255, 255, 255);">;<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">try</span><span style="background-color: rgb(255, 255, 255);"> {<br />is = </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> FileInputStream(</span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">fileName)</span><span style="background-color: rgb(255, 255, 255);">;<br /><br /></span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255); font-style: italic;">// Some work...<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">int</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">n </span><span style="background-color: rgb(255, 255, 255);">= is.read();<br /><br /></span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255); font-style: italic;">// Need to close here so caller will know file in unstable state<br /></span><span style="background-color: rgb(255, 255, 255);"> is.close();<br /></span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255); font-style: italic;">// Need to set null to avoid double close<br /></span><span style="background-color: rgb(255, 255, 255);"> is = </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">null</span><span style="background-color: rgb(255, 255, 255);">;<br />} </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">catch</span><span style="background-color: rgb(255, 255, 255);"> (</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">IOException </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">e)</span><span style="background-color: rgb(255, 255, 255);"> {<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">throw</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">new</span><span style="background-color: rgb(255, 255, 255);"> PersistenceException(</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"Error reading file "</span><span style="background-color: rgb(255, 255, 255);">+</span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255);">fileName,</span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">e)</span><span style="background-color: rgb(255, 255, 255);">;<br />} </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">finally</span><span style="background-color: rgb(255, 255, 255);"> {<br /></span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">if</span><span style="background-color: rgb(255, 255, 255);"> (is != </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">null</span><span style="background-color: rgb(255, 255, 255);">) {<br /> </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">try</span><span style="background-color: rgb(255, 255, 255);"> {<br /> is.close();<br /> } </span><span style="color: rgb(0, 0, 128); background-color: rgb(255, 255, 255); font-weight: bold;">catch</span><span style="background-color: rgb(255, 255, 255);"> (</span><span style="color: rgb(153, 153, 0); background-color: rgb(255, 255, 255); font-weight: bold;">IOException </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">ignore)</span><span style="background-color: rgb(255, 255, 255);"> {<br /> </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255); font-style: italic;">// Well I try to close, but it does not close<br /></span><span style="background-color: rgb(255, 255, 255);"> </span><span style="color: rgb(128, 128, 128); background-color: rgb(255, 255, 255); font-style: italic;">// SO may be I should close ;-)<br /></span><span style="background-color: rgb(255, 255, 255);"> log.debug(</span><span style="color: rgb(0, 128, 0); background-color: rgb(255, 255, 255); font-weight: bold;">"Ignoring on close of "</span><span style="background-color: rgb(255, 255, 255);">, </span><span style="color: rgb(128, 0, 0); background-color: rgb(255, 255, 255);">ignore)</span><span style="background-color: rgb(255, 255, 255);">;<br /> }<br />}<br />}<br /></span></pre><br /><span style="font-weight: bold;">Conclusion</span><br /><div style="text-align: justify;">Independently, of the discussion on closures, I really hope that the compiler enforcement of catching checked exceptions will be removed in the openJDK very soon...<br /></div>Anonymoushttp://www.blogger.com/profile/01537253748863675494noreply@blogger.com3