tag:blogger.com,1999:blog-62738186848314543062024-03-18T11:48:25.542+02:00cat **/*Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.comBlogger17125tag:blogger.com,1999:blog-6273818684831454306.post-15875062175857453672009-08-18T19:19:00.005+03:002009-08-18T20:11:39.225+03:00Richfaces & JSF 1.2The problem with Richfaces 3.3.1 and Sun JSF RI is that an exception thrown in action listener is suppressed by Richfaces. I will show why this happens. The following stacktrace shows an order of invocations that takes place when an action listener is called:<pre><br />((1)) at blah.blah.blah.ActionListenerTest.test(ActionListenerTest.java:122)<br />at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)<br />at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)<br />at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)<br />at java.lang.reflect.Method.invoke(Method.java:597)<br />at org.apache.el.parser.AstValue.invoke(AstValue.java:170)<br />at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)<br />at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:68)<br />((2)) at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:99)<br />at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)<br />at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:771)<br />at javax.faces.component.UICommand.broadcast(UICommand.java:372)<br />at javax.faces.component.UIData.broadcast(UIData.java:938)<br />((3)) at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:321)<br />at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:296)<br />at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:253)<br />at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:466)<br />at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)<br /></pre><br />I've marked interesting places with ((1)), ((2)) and ((3)). The first interesting method is ((1)) - that is where we throw an unchecked exception. The exception will be catched somewhere between ((1)) and ((2)) and wrapped into the ELException class. Then this exception will be caught in ((2)) as it can be seen here (sources are taken from Sun JSF RI 1.2.12):<pre><br /> public void processAction(ActionEvent actionEvent) throws AbortProcessingException {<br /> if (actionEvent == null) {<br /> throw new NullPointerException();<br /> }<br /><br /> try {<br /> FacesContext context = FacesContext.getCurrentInstance();<br /> ELContext elContext = context.getELContext();<br /> methodExpression.invoke(elContext, new Object[] {actionEvent});<br /> } catch (ELException ee) {<br /> Throwable eeCause = ee.getCause();<br /> if (LOGGER.isLoggable(Level.SEVERE)) {<br /> LOGGER.log(Level.SEVERE,<br /> "severe.event.exception_invoking_processaction"<br /> new Object[]{<br /> eeCause == null ? ee.getClass().getName() : eeCause.getClass().getName(),<br /> methodExpression.getExpressionString(),<br /> actionEvent.getComponent().getId()<br /> });<br /> StringWriter writer = new StringWriter(1024);<br /> if (eeCause == null) {<br /> ee.printStackTrace(new PrintWriter(writer));<br /> } else {<br /> eeCause.printStackTrace(new PrintWriter(writer));<br /> }<br /> LOGGER.severe(writer.toString());<br /> }<br /><br /> throw eeCause == null ? new AbortProcessingException(ee.getMessage(), ee) : new AbortProcessingException(ee.getMessage(), eeCause);<br /> }<br /> }<br /></pre><ad></ad>When the processActio methods catches exception it logs it and wraps exception cause into the AbortProcessingException. Here we come to place ((3)) which catches AbortProcessingException. The following is the source code from RichFaces 3.3.1.GA:<pre><br /> public void processEvents(FacesContext context,<br /> EventsQueue phaseEventsQueue, boolean havePhaseEvents) {<br /> FacesEvent event;<br /> while (havePhaseEvents) {<br /> try {<br /> event = (FacesEvent) phaseEventsQueue.remove();<br /> UIComponent source = event.getComponent();<br /> try {<br /> source.broadcast(event);<br /> } catch (AbortProcessingException e) {<br /> if (_log.isErrorEnabled()) {<br /> UIComponent component = event.getComponent();<br /> String id = null != component ? component<br /> .getClientId(context) : "";<br /> _log.error(<br /> "Error processing faces event for the component "<br /> + id, e);<br /> }<br /> }<br /> } catch (NoSuchElementException e) {<br /> havePhaseEvents = false;<br /> }<br /> }<br /> }<br /></pre> As you can see processEvents catches AbortProcessingException, logs it and does nothing! That is it!<br /><br />I've tried a lot of solutions to solve this, I've tried to solve it with servlets/filters/phase-listeners/action-listeners and so on with no luck! Then I've solved it with last resort - AspectJ. The following aspect does the job perfectly:<pre><br />@Aspect<br />public class RichfacesErrorIntercepterAspect {<br /> @Around("call(* javax.faces.component.UIComponent.broadcast(..)) && within (org.ajax4jsf.component.AjaxViewRoot)")<br /><br /> public void callToBroadcast (final ProceedingJoinPoint thisJoinPoint) throws Throwable<br /> {<br /> try {<br /> thisJoinPoint.proceed ();<br /> } catch (final AbortProcessingException e) {<br /> throw new RuntimeException ("Exception in action listener: " + e.getMessage (), e.getCause ());<br /> }<br /> }<br />}<br /></pre>To weave Richfaces's jar I've used the maven (I use it to build the project anyway):<pre><br /><plugin><br /> <groupId>org.codehaus.mojo</groupId><br /><br /> <artifactId>aspectj-maven-plugin</artifactId><br /><br /> <configuration><br /> <complianceLevel>1.5</complianceLevel><br /> <weaveDependencies><br /> <weaveDependency><br /> <groupId>org.richfaces.framework</groupId><br /> <artifactId>richfaces-impl</artifactId><br /> </weaveDependency><br /> </weaveDependencies><br /> </configuration><br /><br /> <executions><br /> <execution><br /> <goals><br /> <goal>compile</goal><br /> </goals><br /> </execution><br /> </executions><br /></plugin><br /></pre><ad></ad>Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com3tag:blogger.com,1999:blog-6273818684831454306.post-68280852958524114352009-08-02T13:24:00.005+03:002009-08-02T14:06:01.600+03:00Richfaces or Trinidad with FaceletsI upgraded existing project from Java 1.4 to Java 1.5, JSF 1.1 to JSF 1.2, myfaces to sun ri... and decided to leverage a framework providing AJAX for JSF. The first I tried was richfaces. But it worked unstable and I spent 2 days trying to find a reason for it. Then I tried to use trinidad. It was the same. The framework worked but very unstable. For example. I opened a jsf page, if I clicked on a ajaxfied button just immediately after page appeared, then button worked OK. But if I clicked on the button after a while, then the button didn't work, the relevant page part was not updated! It looked like a magick in work. Then I noticed a very strange message which I noticed long time ago but didn't pay any attention to it. The message was "INFO: Facelet[/page/blah.xhtml] was modified @ 14:23:24 AM, flushing component applied...". A quick investigation revealed a root of my problem! It turned out that time in a virtual machine I used as a place for application server was 3 hours less then current time! And so file creation time of files in WAR-file was greater than time in the virtual machine. It looked like facelets framework had some strange algorithm based on current time to reload modified files (and flush components tree). Having set facelets.REFRESH_PERIOD context parameter in web.xml I solved the problem. Both richfaces and trinidad worked fine after that.<ad></ad>Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0tag:blogger.com,1999:blog-6273818684831454306.post-87549804396774016222009-07-06T11:31:00.003+03:002009-07-06T12:55:33.675+03:00Simple DSL in ScalaRecently I started to use Scala for my hobby-project.I had heard that Scala made it possible to write a code in a way that it looked like a DSL embedded inthe Scala language itself. So I decided to try this feature myself. I needed some concise and convenient API to schedule messages for actors. The following is what I ended up with:<pre><br />final class TimeSpec[T] (number : Long, action : Long => T) {<br /> def nanoseconds = action (number)<br /> def microseconds = action (number * 1000L)<br /> def miliseconds = action (number * 1000L * 1000L)<br /> def seconds = action (number * 1000L * 1000L * 1000L)<br /> def minutes = action (number * 1000L * 1000L * 1000L * 60L)<br /> def hours = action (number * 1000L * 1000L * 1000L * 60L * 60L)<br /> def days = action (number * 1000L * 1000L * 1000L * 60L * 60L * 24L)<br />}<br /><br />final class Trigger (actor : MyActor, payload : Any) {<br /> def in (number : Long) = new TimeSpec[Unit] (number, scheduleIn)<br /> def every (number : Long) = new TimeSpec[Unit] (number, scheduleEvery)<br /><br /> private def scheduleIn (nanos : Long) = Scheduler.inNano (actor, payload, nanos)<br /> private def scheduleEvery (nanos : Long) = Scheduler.everyNano (actor, payload, nanos)<br />}<br /><br />final class ActorSchedule (actor : MyActor) {<br /> def payload (payload : Any) = new Trigger (actor, payload)<br />}<br /><br />trait MyActor ..... {<br /> protected val schedule = new ActorSchedule (this)<br /> ....<br />}</pre><ad></ad><br /><br />This code made it possible to schedule messages in a natural way, like:<pre><br />object TestActor extends MyActor {<br /> schedule payload `Hi in 10 nanoseconds<br /><br /> schedule payload `HowAreYou every 5 seconds<br /><br /> schedule payload `Bye in 5 days<br /><br /> def act () = {<br /> case `Hi => println ("Hello!")<br /> case `HowAreYou => println ("I am fine")<br /> case `Bye => println ("Bye-bye")<br /> }<br />}</pre><br />The idea is that schedule is an object of class ActorSchedule. This class has method payload which takes a payload object as its argument. So "schedule payload `Hi" is actually an invocation "schedule.payload(`Hi)". This invocation will create an object of class Trigger. Trigger class has two public methods - in(Long) and every(Long). Because we cannot do anything until a time unit is given, we create an object of TimeSpec class passing to it a method (scheduleIn or scheduleEvery) that is to be run with number of nanoseconds when one of TimeSpec's methods is called. I think this API is concise enough with only small efforts taken to implement it.<ad2></ad2>Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0tag:blogger.com,1999:blog-6273818684831454306.post-61080666013712884122009-02-17T15:51:00.004+02:002009-02-22T17:45:27.911+02:00text & jdbc & sybaseIf you see the following error: "A wrong datastream has been sent to the server. The server was expecting token 236 but got the token 33. This is an internal error."<br /><br />Then it means that you haven't sepcified the correct jdbc type for a column. If you use iBatis, the proper insert statement should look something like:<pre><br /><insert><br />INSERT INTO users (login_name, description)<br /> VALUES (#loginName#, #description:<b>LONGVARCHAR</b>#)<br /></insert></pre><ad2></ad2>Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com1tag:blogger.com,1999:blog-6273818684831454306.post-50296846490904596432008-04-28T14:04:00.006+03:002009-02-22T17:43:06.897+02:00Java's Thread Priorities in LinuxAs I told yesterday, Sun Java 5/6 has a "broken" priority policy for linux. There is <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4813310">a related bug</a> in java's bugtracking system. So if to mention it briefly, there are two thread priority policies for linux. The first one, with code 0, specifies to ignore all thread priorities at all making all threads equal for linux scheduler. The second policy model, with code 1, maps java priorities to calls to the system setpriority function. By default java uses thread priority policy 0. You can say java to use policy 1 by invoking it with -XX:ThreadPriorityPolicy=1 command line argument. Unfortunately, this will work only if you start java with root privileges because the setpriority function sets nice level for processes and a process can't lower a nice level. <ad2></ad2>This is a bad news. The good news is that Sun's java has another bug (I hope this bug will not be fixed). Look at the following code from the java 6 update 3 (build 105) sources (os_linux.cpp):<br /><pre> if (ThreadPriorityPolicy == 1) {<br /> // Only root can raise thread priority. Don't allow ThreadPriorityPolicy=1<br /> // if effective uid is not root. Perhaps, a more elegant way of doing<br /> // this is to test CAP_SYS_NICE capability, but that will require libcap.so<br /> if (geteuid() != 0) {<br /> if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy)) {<br /> warning("-XX:ThreadPriorityPolicy requires root privilege on Linux");<br /> }<br /> ThreadPriorityPolicy = 0;<br /> }<br /> }<br /></pre><br />It is meant to reset command line argument from 1 to 0 if the effective user is not root.<br /><br />Look here:<br /><pre>OSReturn os::set_native_priority(Thread* thread, int newpri) {<br /> if ( !UseThreadPriorities || <b>ThreadPriorityPolicy == 0</b> ) return OS_OK;<br /><br /> int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri);<br /> return (ret == 0) ? OS_OK : OS_ERR;<br />}<br /><br />OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {<br /> if ( !UseThreadPriorities || <b>ThreadPriorityPolicy == 0</b> ) {<br /> *priority_ptr = java_to_os_priority[NormPriority];<br /> return OS_OK;<br /> }<br />...<br />}</pre><br />I've highlighted the interesting code. Do you see how it checks for policy? It means that if we set ThreadPriorityPolicy to ... say to 666, java will still work like the policy is set to 1. And the check that resets ThreadPriorityPolicy from 1 to 0 for non-root users will not be triggered. Whee! So in fact we can use the policy 1 for non-root users running java with the command line argument -XX:ThreadPriorityPolicy=666. But stop would say you, what will it give us if the system's setpriority function fails for non-root user? It gives us enough if we can run our lovely java initially with nice level -5. A level -5 is the nice level used for HIGHEST priority threads in java as you can see from the following code snippet:<br /><pre>int os::java_to_os_priority[MaxPriority + 1] = {<br /> 19, // 0 Entry should never be used<br /><br /> 4, // 1 MinPriority<br /> 3, // 2<br /> 2, // 3<br /><br /> 1, // 4<br /> 0, // 5 NormPriority<br /> -1, // 6<br /><br /> -2, // 7<br /> -3, // 8<br /> -4, // 9 NearMaxPriority<br /><br /> -5 // 10 MaxPriority<br />};</pre><br />Though this looks not fair and totally unholy, I think it is still better then running java with priorities ignored or under root. Thus you can run your java safely and well-scheduled with the command like this:<br /><pre>nice -n -5 su -c 'java -XX:ThreadPriorityPolicy=666 ThreadTester' akshaal</pre><br />There is other way if you have no access to root user.<br /><pre>java -XX:ThreadPriorityPolicy=666 \<br /> -XX:JavaPriority10_To_OSPriority=0 \<br /> -XX:JavaPriority9_To_OSPriority=1 \<br /> -XX:JavaPriority8_To_OSPriority=2 \<br /> -XX:JavaPriority7_To_OSPriority=3 \<br /> -XX:JavaPriority6_To_OSPriority=4 \<br /> -XX:JavaPriority5_To_OSPriority=5 \<br /> -XX:JavaPriority4_To_OSPriority=6 \<br /> -XX:JavaPriority3_To_OSPriority=7 \<br /> -XX:JavaPriority2_To_OSPriority=8 \<br /> -XX:JavaPriority1_To_OSPriority=9 \<br /> ThreadTester</pre><ad></ad>The drawbacks of this method is that your normal priority threads will run with nice level 5 (although threads with the highest level will run with nice level 0 and lowest priority thread with nice level 9). That is it. Enjoy while these bugs (or features) are not fixed yet :).Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com2tag:blogger.com,1999:blog-6273818684831454306.post-90896268933890971912008-04-06T20:36:00.001+03:002009-02-22T17:42:05.429+02:00JRobin 1.5.8 SpeedupOne month ago I created a patch for JRobin. And today I've submitted it to project's page on sourceforge. For graphs with CDEFs this patch speeds up graph creation by the factor of 10 and at least by the factor of 1.5 for graphs without CDEFs. In addition it makes possible to draw arbitrary graphic on top of created graph and use full-featured java code instead of CDEFs (extends Plottable class).<br /><br /><a href="http://toril.ru/soft/jrobin-1.5.8-speedup.patch.gz">The patch</a><ad></ad>Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0tag:blogger.com,1999:blog-6273818684831454306.post-33002354842887773872008-02-10T14:45:00.001+02:002009-02-22T17:41:46.132+02:00Java 6 & AMD64I've noticed that Java 6 update 4 for amd64 always crashes in arbitrary places (for instance, eclipse crashes compiling a class). Whenever you need to use Java 6 Update 4 on amd64 but it keeps crashing, use -Djava.compiler=none - to disable Java6's buggy JIT. In a case your requirements are not Java 6 you can use Java 5 update 14 on amd 64 for it looks stable.<pre><br />Current thread (0x00002aab2d10e800): JavaThread "CompilerThread1" daemon [_thread_in_native, id=20462, stack(0x00000000406b2000,0x00000000407b3000)]<br /><br />siginfo:si_signo=SIGSEGV: si_errno=0, si_code=1 (SEGV_MAPERR), si_addr=0x0000000000000000<br /><br />Registers:<br />RAX=0x0000000000000000, RBX=0x00002aab311cc4d8, RCX=0x00002aab3137e9b0, RDX=0x0000000000000046<br />RSP=0x00000000407aee70, RBP=0x00000000407aeee0, RSI=0x00002aab3137e9b0, RDI=0x00002aab311cc4d8<br />R8 =0x00002aab3137ea08, R9 =0x00002aab3137e9b0, R10=0x00002aab3137e9b0, R11=0x0000000000000000<br />R12=0x00002aab311cc4a0, R13=0x0000000000000000, R14=0x00002aab2cd3b870, R15=0x0000000000000001<br />RIP=0x00002b5f70ae122a, EFL=0x0000000000010246, CSGSFS=0x0000000000000033, ERR=0x0000000000000004<br /> TRAPNO=0x000000000000000e<br /><br />Top of Stack: (sp=0x00000000407aee70)<br />0x00000000407aee70: 00002aab30548b88 00000001ffffffff<br />0x00000000407aee80: 00002aab3137e9b0 0000000270a85331<br />0x00000000407aee90: 00002aab30548b80 00000007407afaa0<br />0x00000000407aeea0: 00000000407afb68 01000000000004a7<br />0x00000000407aeeb0: 00000000407afaa0 00002b5f7112a4f0<br />0x00000000407aeec0: 00000000407afaa0 00000000407af030<br />0x00000000407aeed0: 00000000407aeff0 00000000407aefc0<br />0x00000000407aeee0: 00000000407af100 00002b5f70ae076c<br />0x00000000407aeef0: 00000000407afb68 00000000407af0b0<br />0x00000000407aef00: 00002aab330b0fb0 00002aab30000020<br />0x00000000407aef10: 00000000407aef80 00002b5f711438d0<br />0x00000000407aef20: 00002aab307d8a20 0000000000000151<br />0x00000000407aef30: 00000000407afbc0 00002b5f70608bbc<br />0x00000000407aef40: 00000000407b2950 00000000407aef80<br />0x00000000407aef50: 00002b5f71146040 00002aab3100b990<br />0x00000000407aef60: 0000000000000151 00002b5f70f1a9d2<br />0x00000000407aef70: 0000000040110b90 00002b5f70f1aaa1<br />0x00000000407aef80: 00000000407b2950 00000000407aefc0<br />0x00000000407aef90: 00002b5f71146040 0000000000007fe8<br />0x00000000407aefa0: 00002aab307f5d10 00002b5f70f1a9d2<br />0x00000000407aefb0: 0000000040110b90 00002b5f70f1aaa1<br />0x00000000407aefc0: 00002b5f7112a4f0 00002b5f0000000e<br />0x00000000407aefd0: 00000000407b1450 00000000407afaa0<br />0x00000000407aefe0: 00000000000008c8 00002aab2d10ec70<br />0x00000000407aeff0: 000000000000000d 00000000407b1450<br />0x00000000407af000: 00002aab32c78490 00002b5f70a84d00<br />0x00000000407af010: 00002aab311bd4b0 00000000000004a8<br />0x00000000407af020: 00000000407af0b0 00002aab332443e0<br />0x00000000407af030: 000000000000000c 00000000407b1450<br />0x00000000407af040: 00002aab3178f090 00002aab31ce1aa0<br />0x00000000407af050: 00002aab3184eb70 00002aab3184f6b0<br />0x00000000407af060: 00002aab330c8c60 00000000407afbc0<br /><br />Instructions: (pc=0x00002b5f70ae122a)<br />0x00002b5f70ae121a: 48 89 cf 41 ff 95 80 00 00 00 48 89 df 49 89 c5<br />0x00002b5f70ae122a: 8b 00 41 21 44 24 38 41 8b 45 04 21 43 04 41 8b<br />Stack: [0x00000000406b2000,0x00000000407b3000], sp=0x00000000407aee70, free space=1011k<br />Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)<br />V [libjvm.so+0x1f122a]<br />V [libjvm.so+0x1f076c]<br />V [libjvm.so+0x244525]<br />V [libjvm.so+0x241035]<br />V [libjvm.so+0x1e05c7]<br />V [libjvm.so+0x248ec8]<br />V [libjvm.so+0x248866]<br />V [libjvm.so+0x62a3f9]<br />V [libjvm.so+0x6246a1]<br />V [libjvm.so+0x505eea]<br /><br /><br />Current CompileTask:<br />C2:581 org.eclipse.core.internal.dtree.DataTreeNode.forwardDeltaWith([Lorg/eclipse/core/internal/dtree/AbstractDataTreeNode;[Lorg/eclipse/core/internal/dtree/AbstractDataTreeNode;Lorg/eclipse/core/internal/dtree/IComparator;)[Lorg/eclipse/core/internal/dtree/AbstractDataTreeNode; (469 bytes)<br /></pre><br /><ad></ad>Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0tag:blogger.com,1999:blog-6273818684831454306.post-30989457564038922862007-10-08T10:46:00.002+03:002009-02-22T17:41:15.686+02:00Interesting Design Principle<a href="http://www.velocityreviews.com/forums/t149404-design-for-extension.html">Design for extension</a>. I think it's rare case when you need to override methods without being afraid to break something.<br /><br />P.S. Eclipse project leverages this principle all over the sources.<ad2></ad2>Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0tag:blogger.com,1999:blog-6273818684831454306.post-7021316228230082792007-08-20T13:08:00.002+03:002009-02-22T17:40:33.420+02:00Portlets and AJAX: ZK, GWT, DOJOI've tried to leverage ZK in a portal environment. Yes, it's possible, but there can be only one ZK portlet within portal's page becouse ZK uses global javascript variables. So it's sux. Anyway, don't try to use DhtmlPortlet otherwise you will end up with exception from tomcat telling about SRV spec violations. Instead, just include zk page from your custom portlet class.<br /><br />The same is about GWT. It's pain to build a GWT project with maven. GWT plugin for maven looks immature and abandoned. The idea behind GWT is very hackish.<br /><ad></ad><br />DOJO is a lowlevel set of javascript functions. That makes possible to implement custom widgets suitable for portal environment. Besides, there is DIJIT widgets collection built on top of DOJO. Injection of dijit css styles to portat theme is required to start using DIJIT widgets. Lack of real documentation for DOJO/DIJIT is the only thing really disappointing.Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0tag:blogger.com,1999:blog-6273818684831454306.post-48237310745438671572007-08-05T20:37:00.002+03:002009-02-22T17:39:53.987+02:00SpringMeasure 1.0I don't understand how I've ever been without Spring framework. It is so tasty. I will use it whenever I can. Do you think a step from EJB 2.1 to EJB 3.0 is a revolution? Then step from EJB 3.0 to Spring 2.0 is a revolution no less: flexible IoC, nasty testing out of box, standalone or web or whatever execution, annotations, if you prefer your app knows nothing about spring (no direct dependencies on spring classes) and so on. But that is not an issue of this post. As an example of spring ideas I am going to show you how spring can be easily extended for your needs. In my case I wanted to use measured values right in a bean property definition. I.e. instead of using a value 120013 calculated behind the scene (60*2*1000 + 13) I wanted a human suitable representation like a "2min 13ms". And to achive it I've created a small project.<br /><ad></ad><br />Download <a href="http://toril.ru/soft/springmeasure-1.0.tar.gz">the archive</a>.<br />Uncompress it.<br />Do <b>mvn install</b> from command line inside the archive's folder.<br /><br />Now you can use springmeasure as the dependency in your own project (artifactId: springmeasure, groupId: ru.toril.springmeasure, verision: 1.0).<br /><br />In your application context xml add the following line:<br /><pre><bean class="ru.toril.springmeasure.MeasureConfigurer" /></pre><br />From now you can write following (as an example):<pre><br /> <bean class="some class you want"<br /> p:value1="{${test.length}}m"<br /> p:value2="{4GiB 200MiB}MiB"<br /> p:value3="{400ms}s." /></pre><br />The property value1 is configured with PropertyPlaceholderConfigurer in addition to MeasureConfigurer, whereas test.length property is set to "8km".<br /><br />As you already noticed springmeasure is written to support symbols of Si. A format of value is as following:<pre><br />{sequence of space-separated values with symbol suffix joined to value}outputSymbol</pre><br />An output symbol may be followed by the dot marking that an output value is not to be rounded.<br />You may find out more about format looking at the following test lines:<pre><br /> // IT symbols (bits, bytes)<br /> assertEquals ("2048", convert ("{2KiB}B"));<br /> assertEquals ("16384", convert ("{2KiB}b"));<br /> assertEquals ("11", convert ("{1B 3b}b"));<br /> assertEquals ("10000000", convert ("{ 10MB }B"));<br /> assertEquals ("500", convert ("{ 0.5kB }B"));<br /> assertEquals ("2", convert (" { 2048B 100B 3b }KiB "));<br /> assertEquals ("2.098", convert (" { 2048B 100B 3b }KiB. ").substring (0, 5));<br /><br /> // Time (minutes, seconds, hours, days)<br /> assertEquals ("600", convert ("{10min}s"));<br /> assertEquals ("615", convert ("{10min 15s}s"));<br /> assertEquals ("615000", convert ("{10min 15s}ms"));<br /> assertEquals ("615001000000003", convert ("{10min 15s 1ms 3ps}ps"));<br /> assertEquals ("70", convert ("{1h 10min}min"));<br /><br /> // Length (meters)<br /> assertEquals ("0.5", convert ("{5mm}cm."));<br /> assertEquals ("2", convert ("{2000mm}m"));<br /><br /> // Any other Si value<br /> assertEquals ("0.5", convert ("{5m*}c*."));<br /> assertEquals ("2", convert ("{2000m*}*"));<br /></pre><ad></ad><br />Here is a real life usage examples:<pre><br /> <bean id="monitorTask" class="org.springframework.scheduling.timer.ScheduledTimerTask"<br /> p:period="{30s}ms" ... /><br /><br /> <bean id="monitor"<br /> class="ru.toril.....model.Monitor"<br /> p:maxAllowedIdle="{2h}ms"<br /> p:maxAllowedSize="{2MiB}B"<br /> p:minFreeSize="{2GiB}B"<br /> p:maxSleepTime="{1min}ms" ... /><br /></pre>Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0tag:blogger.com,1999:blog-6273818684831454306.post-53356986642780722852007-08-04T21:55:00.001+03:002009-02-22T17:39:12.171+02:00WowJBoss 4.2.1 uses 120M of memory running on Java 5, while only 91M on Java 6. Only what I can guess is that Java 6 leverages some new memory page allocation strategy or may be I just wrong and there is something completely different :).<br /><br />Also it means I've replaced Sun Application Server 9 (based on glassfish) with jboss, becouse Sun AS has been eating twice as more memory than JBOSS 4.2.1 and I've read that Sun Portal requires 2 GB of memory to run and a lot of dependencies!<ad2></ad2>Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0tag:blogger.com,1999:blog-6273818684831454306.post-74464330021701515492007-08-04T15:44:00.001+03:002009-02-22T17:25:32.752+02:00IDEEclipse 3.3 has won my heart. I just enjoy programming in it as I've never been enjoing in any other (jdeveloper, idea 7, eclipse 3.2).<ad2></ad2>Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0tag:blogger.com,1999:blog-6273818684831454306.post-18898223714575722652007-03-13T17:44:00.004+02:002009-02-22T17:29:53.558+02:00wtf<b>The code snippet from former coworker of mine. There are about dozen things like that:</b><br /><pre>if (System.getProperty("time.to.sleep").equals("null")) {<br /> timeToThreadSleep = prefs.getLong(TAG_SLEEP, timeToThreadSleep);<br /> System.out.println("....p: " + timeToThreadSleep + " millis" + " \t");<br /> } else {<br /> timeToThreadSleep = new Integer(System.getProperty("time.to.sleep")).intValue();<br /> System.out.println("...p: " + timeToThreadSleep + " millis" + " \t");<br />}</pre><ad2></ad2>Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0tag:blogger.com,1999:blog-6273818684831454306.post-15761889421085795362007-03-09T14:23:00.002+02:002009-02-22T17:31:12.437+02:00LPTRAAnd for EE fanatics I've implemented the resource adapter (JCA 1.5 with CCI), a right-way to access parallel port from inside EE applications. To use it, you need <a href="http://www.akshaal.info/2007/03/uparport.html">UParPort</a> library installed. Then, simply deploy <a href="http://toril.ru/soft/LPTRA.rar">this RAR</a> (resource adapter archive) into your application server. When you have done it, create a datasource for the LPTRA. You will have to specify pin names, while you are creating the datasource, like this: 1PinName=eye1, 2PinName=eye2 and so on. That's all. You may download <a href="http://toril.ru/soft/LPTRA.tar.gz">the sources of the LPTRA</a> as well.<br /><br /><b>Example:</b><ad></ad><br /><pre><br />@Resource (name = "eis/ParPort")<br />private ConnectionFactory connFactory;<br /><br />Connection conn = null;<br />try {<br /> conn = connFactory.getConnection();<br /> Interaction interaction = conn.createInteraction ();<br /> MappedRecord r =<br /> connFactory.getRecordFactory ().createMappedRecord ("");<br /><br /> r.put ("eye1", true); // turn eye1 pin into the on state<br /> r.put ("eye2", false); // turn eye2 off<br /> interaction.execute (null, r);<br />} catch (ResourceException e) {<br /> e.printStackTrace (); // Not sexy<br />} finally {<br /> if (conn != null) {<br /> try {<br /> conn.close();<br /> } catch (ResourceException e) {<br /> e.printStackTrace (); // Not sexy<br /> }<br /> }<br />}<br /></pre>Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com1tag:blogger.com,1999:blog-6273818684831454306.post-36246158012526274942007-03-09T13:29:00.002+02:002009-02-22T17:31:24.461+02:00UParPortIt had been a long time since I planned to publish this piece of software. Now here it is. UParPort - is the java library for accessing the parallel port (printer port) from inside a Java program. But unlike <a href="http://www.geocities.com/Juanga69/parport/">parport</a>, it doesn't require root privileges. There is the main class UParPort in package ru.toril.uparport. It takes a device name as the constructor's agruments. And the device name should look similar to "/dev/par0" or "lpt1". When an instance of the UParPort class has been created, the following methods can be called on it: getData, getStatus setData, close. isClosed, toString. There are <a href="http://toril.ru/soft/uparport.zip">the binaries</a> and <a href="http://toril.ru/soft/uparport.tar.gz">the sources</a> of the UParPort.<ad2></ad2>Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0tag:blogger.com,1999:blog-6273818684831454306.post-79677550530151045902006-12-20T05:11:00.001+02:002009-02-22T17:36:41.605+02:00ActiveMQ... Exceptions HandlingIt is strange to see such code in a mature project like ActiveMQ:<br /><pre><br /> public void onException(JMSException e) {<br /> if(exceptionListener!=null && managedConnection!=null) {<br /> try {<br /> exceptionListener.onException(e);<br /> } catch (Throwable ignore) {<br /> // We can never trust user code so ignore any exceptions.<br /> }<br /> }<br /> }<br /></pre><ad></ad><br />(that was source code from ActiveMQ project)Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0tag:blogger.com,1999:blog-6273818684831454306.post-28579778818550987312006-10-17T01:24:00.001+03:002009-02-22T17:38:47.014+02:00JCAAssume that we write an JCA RA supporting outbound connections to an EIS. We have written everything. It has been verificated and deployed into GlassFish. Everything is ok. Now we have deployed some application to test connection to the EIS. We execute it and see how it fails with: "Exception in NamingManagerImpl copyMutableObject() ... java.io.NotSerializableException".<ad2></ad2><br /><br />After digging, we find out, that the exception throws on copying of implementation of the java.resource.cci.ConnectionFactory interface. And exactly, there is a non-serializable field in the ConnectionFactoryImpl, (the field is) ManagedConnectionFactory for example. After N hours have bean spended/killed for search in the google, we find out, that the GlassFish puts an object copy in JNDI - not the object itself! And again, after we have blamed and decided that JNDI implementators know more, we mark the disagreeable field in the ConnectionFactoryImpl as transient. Suppose this object will be used just to invoke getReference method? No: after we have bothered with it a bit more, it turns out, that dependency injection mechanism gives us the copy of the object from the JNDI with transient fields set to NULL or zero.<br /><br />Lets give GlassFish a last chance. We read its sources, and find out that not every object goes through JNDI serialized. For example, Connectors should be thrown in not serialized! Hm, but how does it find that object is a Connector? In this way:<br /><pre><br />private boolean isConnector(String logicalJndiName){<br /> return (logicalJndiName.indexOf(EIS_STRING)!=-1);<br />}<br />where EIS_STRING = "/eis/".<br /></pre><br /><br />In short, remember it to eliminate extra troubles: ConnectionFactory instances must be placed in subcontext /eis/ !!<br /><br />In general, this problem appears in a form of NPE (null pointer exception) when method is invoked on a transient field. I think, it is a good idea to have the following code in connectionFactoryImpl:<br /><pre><br />/**<br /> * Ensure that managedConnectionFactory is not null.<br /> * @throws ResourceException if managedConnectionFactory is null.<br /> */<br />protected void ensureManagedConnectionFactory () throws ResourceException {<br /> if (this.managedConnectionFactory == null) {<br /> throw new ResourceException (<br /> "No reference to managed connection factory exists."<br /> + " Either it is a bug of the RA or your JNDI resource"<br /> + " is not in the /eis/ subcontext");<br /> }<br /></pre><br />Always invoke this method before use of this.managedConnectionFactory.<ad></ad>Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0