Java and transactions strategies

There is great series of articles writed by Mark Richards about transaction and transaction strategies in java:

At this moment are desribed two types of strategies:

I hope that in near future there will occur articles for:

  • High Concurrency transaction strategy
  • High-Speed Processing transaction strategy

Great reading.

Apache Mina and Spring Framework integration

In red corner we have:

Apache MINA is a network application framework which helps users develop high performance and high scalability network applications easily. It provides an abstract · event-driven · asynchronous API over various transports such as TCP/IP and UDP/IP via Java NIO.

and in blue corner:

Spring is an open source framework created to address the complexity of enterprise application development. One of the chief advantages of the Spring framework is its layered architecture, which allows you to be selective about which of its components you use while also providing a cohesive framework for J2EE application development.

Lets try to put them together. This is part of appliaction context used in project I am involved in:

  1.  
  2. ...
  3. <import resource="protocol-context.xml"/>
  4.  
  5. <bean id="minaHandler"
  6. class="pl.burningice.server.net.minaExtensions.ExtendedDemuxingIoHandler">
  7. <property name="messageHandlers" ref="handlersMapping" />
  8. </bean>
  9.  
  10. <bean id="codecFactory"
  11. class="pl.burningice.server.net.minaExtensions.ExtendedDemuxingProtocolCodecFactory">
  12. <property name="decoders" ref="decodersList" />
  13. <property name="encoders" ref="encodersList" />
  14. </bean>
  15.  
  16. <bean id="codecFilter"
  17. class="org.apache.mina.filter.codec.ProtocolCodecFilter">
  18. <constructor-arg>
  19. <ref local="codecFactory"/>
  20. </constructor-arg>
  21. </bean>
  22.  
  23. <bean id="loggingFilter"
  24. class="org.apache.mina.filter.LoggingFilter" />
  25.  
  26. <bean id="filterChainBuilder"
  27. class="org.apache.mina.integration.spring.DefaultIoFilterChainBuilderFactoryBean">
  28. <property name="filters">
  29. <list>
  30. <ref local="loggingFilter"/>
  31. <ref local="codecFilter"/>
  32. </list>
  33. </property>
  34. </bean>
  35.  
  36. <bean id="serverSocket"
  37. class="java.net.InetSocketAddress">
  38. <constructor-arg type="int" value="${server.port}" />
  39. </bean>
  40.  
  41. <bean id="minaConfig"
  42. class="org.apache.mina.transport.socket.nio.SocketAcceptorConfig">
  43. <property name="reuseAddress" value="true"/>
  44. <property name="filterChainBuilder" ref="filterChainBuilder" />
  45. </bean>
  46.  
  47. <bean id="ioAcceptor"
  48. class="org.apache.mina.transport.socket.nio.SocketAcceptor" />
  49.  
  50. <bean id="ioAcceptorDecorator"
  51. class="pl.burningice.server.net.minaExtensions.SocketAcceptorDecorator"
  52. init-method="bind"
  53. destroy-method="unbind">
  54. <constructor-arg>
  55. <ref bean="ioAcceptor"/>
  56. </constructor-arg>
  57. <property name="socketAddres" ref="serverSocket" />
  58. <property name="ioHandler" ref="minaHandler" />
  59. <property name="ioServiceConfig" ref="minaConfig" />
  60. </bean>
  61. ...
  62.  

Class SocketAcceptorDecorator is simple decorator. I used it, becouse orginal bind method require parameters, and Spring not allow to set parameters in init-method:

  1.  
  2. package pl.burningice.server.net.minaExtensions;
  3.  
  4. import java.io.IOException;
  5. import java.net.SocketAddress;
  6.  
  7. import org.apache.mina.common.IoAcceptor;
  8. import org.apache.mina.common.IoHandler;
  9. import org.apache.mina.common.IoServiceConfig;
  10.  
  11.  
  12. public class SocketAcceptorDecorator {
  13.  
  14. private SocketAddress socketAddres;
  15.  
  16. private IoHandler ioHandler;
  17.  
  18. private IoServiceConfig ioServiceConfig;
  19.  
  20. private IoAcceptor socketAcceptor;
  21.  
  22. public SocketAcceptorDecorator(IoAcceptor socketAcceptor){
  23. this.socketAcceptor = socketAcceptor;
  24. }
  25.  
  26. public void setSocketAddres(SocketAddress socketAddres) {
  27. this.socketAddres = socketAddres;
  28. }
  29.  
  30. public SocketAddress getSocketAddres() {
  31. return socketAddres;
  32. }
  33.  
  34. public void setIoHandler(IoHandler ioHandler) {
  35. this.ioHandler = ioHandler;
  36. }
  37.  
  38. public IoHandler getIoHandler() {
  39. return ioHandler;
  40. }
  41.  
  42. public void setIoServiceConfig(IoServiceConfig ioServiceConfig) {
  43. this.ioServiceConfig = ioServiceConfig;
  44. }
  45.  
  46. public IoServiceConfig getIoServiceConfig() {
  47. return ioServiceConfig;
  48. }
  49.  
  50. public void bind() throws IOException{
  51. socketAcceptor.bind(getSocketAddres(), getIoHandler(), getIoServiceConfig());
  52. }
  53.  
  54. public void unbind(){
  55. socketAcceptor.unbind(getSocketAddres());
  56. }
  57. }
  58.  
  59.  

Class ExtendedDemuxingProtocolCodecFactory extendeds class DemuxingProtocolCodecFactory and define methods that allow us to set encoders and decoders from list:

  1.  
  2. package pl.burningice.server.net.minaExtensions;
  3.  
  4. import java.util.List;
  5.  
  6. import org.apache.mina.filter.codec.demux.DemuxingProtocolCodecFactory;
  7. import org.apache.mina.filter.codec.demux.MessageDecoder;
  8. import org.apache.mina.filter.codec.demux.MessageEncoder;
  9.  
  10. public class ExtendedDemuxingProtocolCodecFactory extends DemuxingProtocolCodecFactory {
  11.  
  12. public void setEncoders(List<messageEncoder> encoders){
  13. for (MessageEncoder messageEncoder : encoders) {
  14. register(messageEncoder);
  15. }
  16. }
  17.  
  18. public void setDecoders(List<messageDecoder> decoders){
  19. for (MessageDecoder messageDecoder : decoders) {
  20. register(messageDecoder);
  21. }
  22. }
  23. }
  24.  

Similar situation with ExtendedDemuxingIoHandler class where I extended DemuxingIoHandler class add defined method to set message handlers from map:

  1.  
  2. package pl.burningice.server.net.minaExtensions;
  3.  
  4. import java.util.Map;
  5. import java.util.Map.Entry;
  6.  
  7. import org.apache.mina.handler.demux.DemuxingIoHandler;
  8. import org.apache.mina.handler.demux.MessageHandler;
  9.  
  10. public class ExtendedDemuxingIoHandler extends DemuxingIoHandler {
  11.  
  12. @SuppressWarnings("unchecked")
  13. public void setMessageHandlers(Map<class, MessageHandler> messageHandlers){
  14. for (Entry<class, MessageHandler> element : messageHandlers.entrySet()) {
  15. addMessageHandler(element.getKey(), element.getValue());
  16. }
  17. }
  18. }
  19.  

In protocol-context.xml file I stored handlersMapping, decodersList and encodersList beans:

  1.  
  2. ...
  3. <bean id="handlersMapping" class="java.util.HashMap">
  4. <constructor-arg>
  5. <map>
  6. <entry key="pl.burningice.server.net.protocol.request.LoginRequest">
  7. <bean class="pl.burningice.server.net.protocol.handler.LoginRequestHandler"></bean>
  8. </entry>
  9. </map>
  10. </constructor-arg>
  11. </bean>
  12.  
  13. <bean id="decodersList" class="java.util.ArrayList">
  14. <constructor-arg>
  15. <list>
  16. <bean class="pl.burningice.server.net.protocol.decoder.LoginRequestDecoder" />
  17. </list>
  18. </constructor-arg>
  19. </bean>
  20.  
  21. <bean id="encodersList" class="java.util.ArrayList">
  22. <constructor-arg>
  23. <list>
  24. <bean class="pl.burningice.server.net.protocol.encoder.LoginRequestEncoder" />
  25. </list>
  26. </constructor-arg>
  27. </bean>
  28.  

I used separate xml file, becouse only protocol-context.xml will be upadated - xml containing integration data will be const.
If there is better way to integrate both frameworks, please let me know.

Pimp my Grails Bootstrap

If you want to depend data loaded in bootstrap from environment that application is currently running in, try this solution:

  1.  
  2. import grails.util.GrailsUtil
  3. import org.codehaus.groovy.grails.commons.GrailsApplication
  4.  
  5. class BootStrap {
  6.  
  7. def init = { servletContext ->
  8. if(!envMapping[GrailsUtil.environment]){
  9. }
  10.  
  11. envMapping[GrailsUtil.environment]()
  12. }
  13.  
  14. def destroy = {
  15. }
  16.  
  17. def initTest = {
  18. ...
  19. }
  20.  
  21. def initDev = {
  22. ...
  23. }
  24.  
  25. def initProd = {
  26. ...
  27. }
  28.  
  29. def envMapping = [(GrailsApplication.ENV_TEST):initTest,
  30. (GrailsApplication.ENV_DEVELOPMENT):initDev,
  31. (GrailsApplication.ENV_PRODUCTION):initProd]
  32. }
  33.  

Variable envMapping is on the end BootStrap class becouse in other case values in map were set as null (???).

Grails upgrade from 1.0.4 to 1.1 problems – part 2

If after upgrade to version 1.1 you will be hit by error like this:

  1.  
  2. ...
  3. log4j:ERROR Could not read configuration file from URL [file:/C:/GrailsApp/web-app/W
  4. java.io.FileNotFoundException: C:\GrailsApp\web-app\WEB-INF\classes\log4j.properties
  5. ...
  6.  

go to web.xml template file in \src\templates\war\ directory of your project and delete lines:

  1.  
  2. ...
  3. <context-param>
  4. <param-name>log4jConfigLocation</param-name>
  5. <param-value>/WEB-INF/classes/log4j.properties</param-value>
  6. </context-param>
  7. ...
  8.  

Grails file upload service

In ours application we want to create service that will move uploaded file to specified directory. We want only to give name for the file, relative path to the directory where file should be stored, and of corse a file. This is simple example of sutch service:

  1.  
  2. import org.springframework.context.*
  3.  
  4. class FileUploadService implements ApplicationContextAware {
  5.  
  6. ApplicationContext applicationContext
  7.  
  8. boolean transactional = false
  9.  
  10. def moveFile(file, folderRelativePath, fileName) {
  11. try {
  12. file.transferTo(new File(getAbsolutePath(folderRelativePath, fileName)))
  13. }catch(Exception exception){
  14. log.error "File move error, ${exception}"
  15. }
  16. }
  17.  
  18. private String getAbsolutePath(folderPath, fileName){
  19. "${applicationContext.getResource(folderPath)).getFile()}${File.separatorChar}${fileName}"
  20. }
  21. }
  22.  
  23.  

We specify aboslute path for uploading file, to prevent problems with upload after application deploy on i.e. Tomcat server. To retrive absolute path we need application context, so we just implementing ApplicationContextAware interface.

Now we are ready to use service in ours controller:

  1.  
  2. ...
  3.  
  4. def logo= request.getFile('logo')
  5.  
  6. if(!logo.empty) {
  7. if (fileUploadService.moveFile(logo, 'relative/path/to/dir', 'myLogo.jpg')){
  8. render('file uploaded')
  9. }else{
  10. render('error while file upload')
  11. }
  12. }
  13.  
  14. ...
  15.  

Grails upgrade from 1.0.4 to 1.1 problems – part 1

Recently I have been upgrading Grails application from version 1.0.4 to version 1.1. After that my test fails with error:

  1.  
  2. No signature of method: roles.beans() is applicable for argument types: (roles$_run_closure1) values: [roles$_run_closure1@b7ad1a]
  3.  

I found that problem was with fixtures. In version 1.0.4 of Grails code like this:

  1.  
  2. beans
  3. {
  4. roleOne(Role)
  5. {
  6. name = ConfigurationHolder.config.security.role.user
  7. }
  8. }
  9.  

works correctly, but after upgrade instant beans{} we should use fixture{} statment:

  1.  
  2. fixture
  3. {
  4. roleOne(Role)
  5. {
  6. name = ConfigurationHolder.config.security.role.user
  7. }
  8. }
  9.  

Grails debugging

Grails application step-by-step debugging? Yes. With NetBeans 6.7M3. Just from command line lunch in directory of your application:

  1.  
  2. grails-debug run-app
  3.  

and in NetBeans attach debbuger on port 5005 (Debug->Attach Debugger). Now you can put the breakpoint.

Maven and FlexMojos problems

If you want to prepare automatic build of your flex application you could use maven nad flex-mojos. In my project I have two main problems while working over sutch configuration. First was problem with fonts embedding and second with flex-framework artifact for locale different than en_EN.

First problem could be eliminated by specifying font renderer in pom.xml:

  1.  
  2. ...
  3. <plugin>
  4. <groupId>org.sonatype.flexmojos</groupId>
  5. <artifactId>flexmojos-maven-plugin</artifactId>
  6. <version>3.0.0</version>
  7. <extensions>true</extensions>
  8. <configuration>
  9. <sourceFile>main.mxml</sourceFile>
  10. <compiledLocales>
  11. <locale>fr_FR</locale>
  12. </compiledLocales>
  13. <fonts>
  14. <managers>
  15. <manager>flash.fonts.AFEFontManager</manager>
  16. </managers>
  17. </fonts>
  18. </configuration>
  19. <dependencies>
  20. <dependency>
  21. <groupId>com.adobe.flex</groupId>
  22. <artifactId>flex-fontkit</artifactId>
  23. <version>${flex.sdk.version}</version>
  24. </dependency>
  25. <dependency>
  26. <groupId>com.adobe.flex</groupId>
  27. <artifactId>afe</artifactId>
  28. <version>${flex.sdk.version}</version>
  29. </dependency>
  30. <dependency>
  31. <groupId>com.adobe.flex</groupId>
  32. <artifactId>aglj32</artifactId>
  33. <version>${flex.sdk.version}</version>
  34. </dependency>
  35. <dependency>
  36. <groupId>com.adobe.flex</groupId>
  37. <artifactId>rideau</artifactId>
  38. <version>${flex.sdk.version}</version>
  39. </dependency>
  40. </dependencies>
  41. </plugin>
  42.  

...

You must install dependencies to maven repository manually. All files (flex-fontkit.jar, aglj32.jar, afe.jar, rideau.jar) you could find in lib directory of sdks used by your Flex Builder installation.

Second problem could by resolved by creating localized framework resources. Just use copylocale.exe application from bin directory of yours sdk:

  1.  
  2. bin\copylocale.exe en_US fr_FR
  3.  

and next install rpc_rb.swc and framework_rb.swc from frameworks\locale\fr_FR directory to maven repository.

O3D – the future is near

On one of my interviews I have had question "which programing language will be the most important in future". My answer was ActionScript, but at this moment, knowing what google have in they backyard I say: JavaScript. Why? My answer is O3D:

O3D is an open-source JavaScript API for creating interactive 3D graphics applications that run in a browser window: games, ads, 3D model viewers, product demos, virtual worlds.

Yes, they preparing engine that allow to create whole 3d realms. All you need, is to download plug-in and we could create 3d environment in pure JavaScript.

The O3D JavaScript application code is completely contained in an HTML document that is loaded into a web browser. To develop a O3D application, all you need is the O3D plug-in and a text editor for writing JavaScript code.

Sounds great, isn't it?

Griffon and table data binding

Recently i have been working on small application in Griffon framewrok. This is MVC framework for desktop applications writed in Groovy  - new cool kid in Java World. My first impression was - WOW. Swing builder is my favorite feature immediately after mvc group.

But nothing lasts forever and after few days of work I entered into world of pain. There is no documentation, best practices, or any thing like that. All java developers that were coddled by IDE's like Eclipse will suffer lots of pains because there is no rational support for Groovy. Of course you can hack Netbeans Grails (cousin of Griffon for web applications) plug-in, but after one hour of fight I stayed with my project in Eclipse.

But the hardest thing for me was to menage how to bind data to table. I thinked that there MUST be way to do that by bind statement, but after several hours of searching, I find that there is no such way.

So,  how to do it? Use Glazed list.

There is simple example how to use glazed list. This is View from MVC group where we have helper method that create table model. Next we use this method for table creation. In this example model.tableData is instance of ca.odell.glazedlists.BasicEventList.

  1. def createTableModel() {
  2. def columnNames = ['col 1', 'col 2', 'col 3', 'col 4', 'col 5']
  3. def variableNames = ['var1', 'var2', 'var3', 'var4', 'var5']
  4. new EventTableModel(model.tableData,
  5. [getColumnCount: { columnNames.size() },
  6. getColumnName: { index -> columnNames[index] },
  7. getColumnValue: {object, index -> object."${variableNames[index]}"}] as TableFormat)
  8. }
  9.  
  10. panel {
  11. borderLayout()
  12. scrollPane {
  13. table(id:'myTable',
  14. selectionMode: ListSelectionModel.SINGLE_SELECTION,
  15. autoCreateRowSorter:true,
  16. model: createTableModel()) {
  17. current.tableHeader.reorderingAllowed = false
  18. }
  19. }
  20. }

If you still looking for more info, check this example for more details.

Powered by WordPress with GimpStyle Theme design by Horacio Bella.
Entries and comments feeds. Valid XHTML and CSS.