- Introduction to JSR 168—The Java Portlet Specification (pdf)
- Understanding the Java Portlet Specification
- I18n in portlets
A developer's blog.
autowireBeanProperties instead of autowireBean (otherwise my services didn't get populated).
Let us imagine a situation when you are writing an application sitting on the ESB, or providing a web service enabled interface. In both cases you will probably end up having some XML Schema describing your data transfer format. Also, good chances are that you will have to have a RDBMS schema, too. Usually both are designed, implemented and documented separately. But when you write your application from scratch, you have a unique possibility to seriously reduce amount of work need to be done. Here I want to share some of my ideas how to achieve this. Few variants are possible. You can start with DDL, generate JPA-annotated beans using Hibernate Tools for example, and then annotate it with some JAXB stuff (or use something not requiring annotations at all, like XStream). You will be able to get an XSD using some JavaBeans-to-XSD tool (like you have in IBM Rational tools when generating WSDLs for given beans), or just generate a bunch of sample XML files by marshaling some test data and use any modern XML editor to generate XSD by example. But I must warn you that the XSD will be rather ugly, because usually you don't have too much control over the whole process, that's why the proper tooling is vital for success. Nevertheless, this approach is quite common and supported by many powerful tools, such as my favorite IBM Rational Software Architect 7.5.
From the other hand, you can start with some UML and generate Java Beans, then put all the necessary annotations (both JAXB and JPA) inside. But you will have to do a double amount of work fixing the beans structure and hardcoding annotations for both technologies. Once again, you will need to fix the resulting XSD manually, that's for sure.
What I prefer to do is design the data layer entirely in XSD (which maps to Java classes in a more natural way than DDL), then generate Java beans using JAXB or something similar, enrich it with JPA annotations and generate DDL as the result. Sounds pretty nice, but there are some problems, particularly at the JPA annotations stage. The major one is that you lose flexibility in XSD changing, because after each change your beans will be generated again and you will lose all your precious annotations (yes, you can keep JPA configuration in XML, but this approach has its own drawbacks, and it's beyond the scope of this post anyway).
Fortunately there exists a tool which reduces (and in some cases can even eliminate it at all) the amount of the manual work at the JPA stage. It is implemented by Aleksei Valikov and called HyperJAXB 3 (version 1 is outdated and version 2 supports Hibernate instead of pure JPA). It is more-or-less a plugin set for XJC, adding JPA annotations to JAXB-generated beans. It is distributed as an easy to use bundle containing everything (including build.xml) to start converting your XSDs to JAXB + JPA enabled Java Beans.
Here comes the concepts of relationships and keys. The problem is, when not specified explicitly, HyperJAXB creates an autogenerated integer ID for every entity, which is not always what you really want to get. Let me explain. I want to automate not only the data schema creation, but also the API to access data. For example, when there comes an XML from the client, I don't want to check if the same piece of data is already present in my DB (in fact it can be a hell lot of work to do, especially when some complex, deeply nested XML structures are considered). I want the intelligent middleware to merge it automatically with the existing data. But it won't happen by default, because of the autogenerated IDs, which are always issued new. So, if you will try to persist the same XML twice, it will put two copies in your DB, which is probably not what you expect to see.
To fix this behavior, you need to explicitly specify the meaningful IDs for your entities. With HyperJAXB you can specify it directly in your XSD by marking some of the entity fields with the special XSD annotation in the same way you document your schemas (For details please consult HyperJAXB documentation. Yes, you still can't use the XSD uniqueness constraints support because it's a bit too hard to parse by XJC-like tool). Same is true for the relationship options – for example, you can define one-to-many with all the possible JPA attributes, so it's quite flexible in case you need it.
So far, so good. Things start being complicated when you have compound IDs (and I think it happens really soon in the real life applications). Fortunately HyperJAXB gained support for IdClass few weeks ago. But here comes another problem of “cascading” IDs – when you have a complex primary key (in entity A) used as a foreign key in another entity (B), which at the same time is a part of its (B's) primary key. We had a brief discussion on this topic with Aleksei (BTW, I want to say THANKS! for his great instant support for HyperJAXB and related stuff), and it seems to be too hard to implement in the foreseeable future due to some limitations of XJC extension mechanisms. So, the only way out is to tweak generated beans manually. Well, I think it is something like 20% of the job, and another 80% is done automatically.
So, in the end the results are pretty sweet. You design your data structure as XML Schema (which itself can be generated based on XML samples). Then you put some metadata (mostly ID information) inside to make sure it is complete. Now you run HyperJAXB against your XSDs and fix the generated Java Beans in case you need to handle some “complex” situations. Then, using one of the tools (either Hibernate Tools or OpenJPA Mapping Tool) you get DDL in a matter of seconds. After that you are able to (un)marshal your entities in a single line of code using JAXB, and load / merge them from / to any RDBMS in a single LOC using JPA. That totally eliminates all the serialization and storage-related code, reducing complexity, improving reliability, bla-bla-bla :)
P. S.: I must warn you that there are some issues when using this approach with different JPA providers. I've tried both Hibernate and OpenJPA and they seem to be not really compatible with each other for anything but the most trivial models. It worth a separate post and I'm not going to explain it here, just to make it short: I prefer OpenJPA over Hibernate nowadays, because I find it less restricting in defining relationships and complex IDs. Also, from the tooling point of view, those are pretty close.
P. P. S.: HyperJAXB functionality is growing rapidly, so I won't be surprised to see the majority of the issues mentioned in this post addressed in the upcoming releases. I wish this project good luck and can't wait to see it gaining popularity in the JEE development community.
I was trying to find something for easy implementation of web services in any CGI language. Firstly I considered PHP. A lot of negative emotions, nothing really simple and a wasted day. Perl has some better support for the stuff, but I've chosen Python (mostly because I've got less experience in it and wanted to give it a try).@url_pattern("/users/${username}/plans/${year}", ['GET', 'PUT'])I'm gonna use it to implement a very first version of Pomodoro Server. Some brief impressions:
def get_plans (username, year, request):
return "Inside get_plans('%s', '%s')" % (username, year)
@Path("/users/{username}")
public class UserResource {
@GET
@Produces("text/xml")
public String getUser(@PathParam("username") String userName) {
}
}
Update2: found a very similar solution for Python called Bottle. Sample code:@route('/hello/:name')
def hello_name(name):
return 'Hello %s!' % name
run(host='localhost', port=8080)
Now I want to point at a really mind-blowing tool called JetBrains Meta Programming System. You see, some time ago to implement your own Domain-Specific Language it was necessary to develop a grammar, implement a parser (or use such tools as GNU Bison for example) which normally operates in XML SAX manner and finally do something with the results obtained. Nowadays these new tools enable you to do virtually all this stuff in kinda type-safe way. It strictly watches at all your manipulations and alerts violations.
Today I was reading a book about software metrics called "Object-Oriented Metrics in Practice" by Michele Lanza and Radu Marinescu. It's abouth things like "Design Harmony" and so on....you cannot understand the beauty of a painting by measuring its frame or understand the depth of a poem by counting the lines...But at the same time it's obvious that you won't see the beauty of the poem looking on it's grammar, syntax or verse structure (these are more-or-less analogues for software design metrics), without actually reading and understanding the sense. That's why my conclusion is that for creating a harmonious software design it's necessary (but not sufficient) for the metrics to be harmonious, too.
...metrics can help to evaluate and improve designs, but those have to be meaningful metrics that are put in a context of design harmony...
What to do if you need to test the performance of your client-server application, which is not on the Web? For example, some kind of Lotus Notes one. The problem is - you can't even execute several Lotus instances on a single machine, so it's quite a tricky task to simulate multiple simultaneous users.
I was surprised to find some hardware XML processors, called XML Appliances. They can do XSLT,validation, encryption and many more. Implemented as a separate network device it can be useful in SOA.
Here it is. Seems that RTC is even better than I thought... Among cool things mentioned, there are:
What is the major problem of using the Pomodoro Technique? I think it's a sharing one. You see, when you're "in the middle of a pomodoro", no one really cares - your team mates will go on interrupting you anyway!<url-pattern>/stations/*/departure/*</url-pattern>
<security-constraint>
<display-name>Station 14 constraint</display-name>
<web-resource-collection>
<web-resource-name>All station 14'th resources</web-resource-name>
<url-pattern>/stations/14/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>STATION_14</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<display-name>View arrival constraint</display-name>
<web-resource-collection>
<web-resource-name>View arrival page</web-resource-name>
<url-pattern>/stations/14/arrival/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>VIEW_ARRIVAL</role-name>
</auth-constraint>
</security-constraint>
D:\projects
D:\projects\trac
D:\projects\trac\rw
D:\projects\repos
D:\projects\repos\rw
D:\projects\tools
D:\projects\tools\Python25
D:\projects\tools\svn-win32-1.5.5d:\projects\repos (you can accept defaults for all other options)d:\projects\tools, optionally add its bin folder to PATHsvnadmin create d:\projects\repos\rw) and create a standard folder structure (trunk, tags, etc) manuallyD:\projects\repos\rw\conf\passwd and uncomment a line in D:\projects\repos\rw\conf\svnserve.conf). Now you can browse it using this URL and newly created login: svn://localhost/rw/svnserve.exe -r d:\projects\repos -dd:\Python25d:\Python25 to PATH system environment variablesvn-win32-1.5.5_py.zip to d:\Python25\Lib\site-packagessvn-win32-1.5.5.zip\svn-win32-1.5.5\bin to d:\Python25\Lib\site-packages\libsvncopy d:\Python25\Lib\site-packages\libsvn\*.dll d:\Python25\Lib\site-packages\libsvn\*.pydmkdir d:\projects\trac\rwtrac-admin d:\projects\trac\rw initenv, enter the project name and d:\projects\repos\rw when asked for Subversion repository location. Leave all other values default.tracd --port 8000 d:\projects\trac\rwtrac-digest.py and fill it with code from this pagepython trac-digest.py -u adm -p adm >> d:\projects\trac\rw\digest.txttrac-admin d:\projects\trac\rw permission add adm TRAC_ADMINtracd -p 80 --auth=rw,trac\rw\digest.txt,trac trac\rwtrac.ini:[attachment]
max_size = 262144000trac-post-commit-hook and trac-post-commit-hook.cmd from here and follow instructions in trac-post-commit-hook.cmd.d:\projects\repos\rw\hooks and modify .cmd file like that:SET TRAC_ENV=D:\projects\trac\rweasy_install http://trac-hacks.org/svn/accountmanagerplugin/trunktrac.web.auth.LoginModule = disabledD:\projects\repos\rw\conf\passwd)tools\Python25\Scripts\tracd.exe -p 80 trac\rwD:\projects\tools\Python25 directory and it won't override your changes.
Again, thanks to Henrik Kniberg's blog I've got a brief introduction to Pomodoro Technique, which is essentially a way to improve one's productivity. The PDF describing it is quite a simple one and is fun to read (for those lazy enough there exists a 5-minute guide too).We can stimulate this ability to feel time in a different way by means of a series of exercises which serve to enhance consciousness of passing time among Pomodoro users. This different awareness of the passage of time seems to lead Pomodoro users to a higher level of concentration in performing the activity at hand.BTW, the concept is thoroughly developed and there exist various tools dedicated to help using it, so it should be a fun thing to advance this technique, but I'm going to use it's simplest, hardware form. Yes, gonna try this on Monday! :)
for $statement in document(https://www.sample.com/sample.xml)//post
let $comment := $statement/comment
where $statement/postedby = 'userBob'
return <quotebob>{$comment}</quotebob>
Nice, isn't it?
99 9[1-$][\$@$@$@$@\/*=[1-$$[%\1-$@]?0=[\$.' ,\]?]?]#It's a program which prints all primes up to 100. It's so impressively smart, that inspired creation of K, F and Y programming languages, which in turn are... somewhat similar to J and Q.
new java.util.Scanner(url.openConnection().getInputStream()).useDelimiter("\\Z").next();
Thanks to CT Arrington's Weblog and Core Java Technologies Tech Tips magazine.FileUtils.readFileToString(file);
I think that's a fresh idea and it's not too late to start something like that in mid-February :)If you start a new year off with massive success in the first month, it’s amazing how fast it can snowball and help propel you to your best year EVER.
And yes, I wish you good luck, because I'm afraid, some cool features (closures, etc) which can improve DSL implementation in Java won't be included in JSE 7. That's why I'm looking at Groovy with increasing interest and can't wait to see good IDE support for it.Product p = new Product();
ListsoldOutProducts =
db.from(p).where(p.unitsInStock).is(0).select();