Wednesday, March 30, 2011

BigDecimal rounding issue

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result


do this:


RoundingMode DEFAULT_ROUNDING_MODE = RoundingMode.HALF_UP;
int DIVIDE_SCALE = 10;
BigDecimal op1, op2
...
BigDecimal result = op1.divide(op2, DIVIDE_SCALE, DEFAULT_ROUNDING_MODE);


and you will be happy.

Tuesday, March 29, 2011

Struts Royally Sucks

I have heard that 100s of times, and I have vague memories of myself struggling, some 7 years ago, against Struts quirks and all those HORRIBLE tag libraries (writing code in XML? Noooooo way.).

I have even hoped to be able to mock Struts, instead of having to deploy in container,
using this http://strutstestcase.sourceforge.net/ framework...

I use MockStrutsTestCase in a very basic setup and I get this:


java.lang.UnsupportedOperationException: getPathTranslated operation is not supported!
at servletunit.HttpServletRequestSimulator.getPathTranslated(HttpServletRequestSimulator.java:635)



no matter what I try...

So I am switching to MockRunner which so far seems to work.

There are also plugins for JUnit and Maven:
http://struts.apache.org/2.2.1/docs/struts-2-junit-plugin-tutorial.html
http://struts.apache.org/2.0.14/docs/testng-plugin.html


This framework is THE BLACK WIDOW MAKER of Front End Developers.


My advice: just throw Struts in the toilet and flush, you will immediately feel an intense relief. Then implement your Front End in Spring MVC or Vaadin.





Here more reasons why Struts sucks.

Poor man's guide to HTML layout

I am absolutely NULL at layouts... no artistic and spacial sense I guess.

So this is an easy and cartesian way of laying out your widgets on a HTML form..; use tables!


this:

A B
C D

E F
G H
I
L


would be rendered as:


A B
C D

E F
G H
I
L


which is good enough for my purposes...


HTML is a total pain in the ass, it's a classic example of a city build on top of weak foundations, like Venice or Ciudad de Mexico... they become soon extremely expensive to maintain, and they should be completely transfered to a better location.

Sunday, March 27, 2011

Developer Driven Development

Very provocative presentation about Leaner Programmer Anarchy

in a word: only the Customer and the Developers stand after we eliminate everything else. Developers negotiate and discuss directly with the Customer.

Having been a freelance developer in Italy for some 8 years, that's the way I was operating, with a much much higher productivity than normal management/analyst-mediated development model.

Who need an analyst anyway, ideas in the head of an analyst have to be transferred to a developer, and this takes time and commitment (the second is much more difficult to find).

Who needs also those unnatural "user stories", and the dissecting of an application into minute subtasks... most of the times, you conceive and implement an application in its entirety, not as small subtasts. Things are much more interrelated than can be captured in a Microsoft Plan.

Thursday, March 24, 2011

Restarting your remote Application Server from Windows, with WinSCP

"c:\Program Files\WinSCP\WinSCP.com" /script=restart.script

and restart.script is:

option confirm off
open username:password@hostname
cd /pathToYourStartStopScripts
call ./stop.sh
call ./start.sh




easy does it!

No more need to putty to your remote AppServer host to recycle the server

MDB message selector with @ActivationConfigProperty annotation

for the MDB:

@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName="messagingType", propertyValue="javax.jms.MessageListener"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/YOURQUEUENAME"),
@ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "MESSAGE_TYPE = 'MESSAGE_TYPE_IMPORT_BLA'")
},
mappedName = "YOURMDBNAME")




and in your code when you produce the Message:

TextMessage message = session.createTextMessage();
message.setText(messageText);
message.setStringProperty("MESSAGE_TYPE", "MESSAGE_TYPE_IMPORT_BLA");


(you can use an enum for message types...)

Automate those tedious remote copy tasks with WINSCP

Install WinSCP

create a batch file containing:

"c:\Program Files\WinSCP\WinSCP.com" /script=copyall.script
pause

in copyall.script write:

option confirm off
open username:password@remotehost
lcd localPathWhereYourFilesAreStored
cd remotePathWhereYouWantToPutYourFiles
put file1
put file2
put file3
exit

Wednesday, March 23, 2011

Efferent Coupling and Cyclomatic Complexity

http://en.wikipedia.org/wiki/Efferent_coupling

"Efferent Coupling is a metric in software development. It measures the number of data types a class knows about.

This includes inheritance, interface implementation, parameter types, variable types, and exceptions.

A large efferent coupling can indicate that a class is unfocused. It may also indicate brittleness, since it depends on the stability of all the types to which it is coupled."



(my idea of a too much "Efferent Coupled" class is the typical implementation of a Service which does everything on it own, like sending JMS messages, querying the DB, applying all sort of Business Rule referring lot of Domain Objects)


http://en.wikipedia.org/wiki/Cyclomatic_complexity

"It directly measures the number of linearly independent paths through a program's source code"


(the way I see it, a method with a lot of if/then/else, exception handling etc... The great danger is that your unit tests might not address all the possible branches of the code. I find fascinating the idea that you can generate a graph and devise a way to generate tests which exercise each node of the graph)


This "cyclomatic" reminds me of the Cyclops Polyphemus (one cyclops, 2 cyclopes... complex, uh?)



Tuesday, March 22, 2011

JBoss and WebSphere MQ

Let's see if this is easier than with WebLogic

http://www.ibm.com/developerworks/websphere/library/techarticles/0710_ritchie/0710_ritchie.html


- you need the file wmq.jmsra.rar, which is in C:\Program Files\IBM\WebSphere MQ\java\lib\jca
(of course you mush install WebSphere MQ to get it :o) )


- copy wmq.jmsra.rar to /server/default/deploy


- create wmq.jmsra-ds.xml in C:\Post\app-rep\itl-v000100-ld-node1\deploy
copy it from here create the wmq.jmsra-ds.xml in

- and copy also wmq.jmsra.ivt.ear to the same folder.

- open http://localhost:8080/WMQ_IVT/


(still having trouble making it work....in the meantime I am posting this)

When netstat is not enough...

http://technet.microsoft.com/en-us/sysinternals/bb897437


TCPView is a nice little tool which helps you a lot to identify who is using a given port number and similar stuff...

Monday, March 21, 2011

UOM classified by type

For those dealing with UOM conversion, this can be useful:

http://www.tripcom.org/ontologies/EDI/EDIFACT/CodeSets/UnitOfMeasureCodes.wsml


length:

"CMT" Centimeter
"KMT" Kilometer (EDIFICE code)
"MMT" Millimeter
"MTR" Meter
"FOT" Foot-UnitOfMeasure
"INH" inch
"YRD" Yard-UnitOfDistance


volume
"001" Barrel (205 litres, 45 gallons) (EAN Code)
"CLT" Centiliter
"CMQ" CubicCentimeter
"DMQ" Cubic decimetre
"FTQ" CubicFoot
"GLI" Gallon-Imperial
"INQ" CubicInch
"MLT" Millilitre
"MMQ" Cubic millimetre
"LTR" Liter
"MTQ" CubicMeter


Surface
"MTK" SquareMeter

weight
"GRM" Gram
"KGM" Kilogram
"LBR" Pound-UnitOfForce
"MGM" Milligram
"PND" Pound-UnitOfForce (EAN Code)

Sunday, March 20, 2011

JAX-RS, RestEasy, Restful WS

A great tutorial from Luciano:
http://blog.aestasit.com/develop-restful-services-like-a-ninja-part-1/
http://blog.aestasit.com/develop-restful-services-like-a-ninja-%E2%80%93-part-2/


JAX-RS = Java API for RESTful Web Services

here http://www.ibm.com/developerworks/webservices/library/wa-jaxrs/index.html general presentation of JAX-RS

The Resteasy doc is here (don't expect complete examples, only code snippets are provided)
http://docs.jboss.org/resteasy/docs/1.0.1.GA/userguide/html/

the annotations are in javax.ws.rs package

Path(value="/contacts")
@GET
@Consumes
@Produces
@Provider
@QueryParam
@HeaderParam
@MatrixParam
@CookieParam

(see the rest on the javadoc...)


Here a decent example (better than the official doc anyway)

Saturday, March 19, 2011

Generating a GUI to edit XML, starting from XSD

When you give your customer a XML-based interface, you better help him produce the XML, at least for testers to play with your service.... not everybody is comfortable with XMLSpy (besides, its licence is VERY expensive).

I have tried Excel as a XML editor, but it flattens a complex graph to a single row,
so every repetead dependent object occupies a new row and forces you to repeat the master object data (sucks).
Besides when you try to export XML it keeps saying:

Cannot save or export XML data. The XML maps in this workbook are not exportable

I have tried adding ID to help Excel track dependent objects:

at the end of your complex type, add:

xs:attribute name="id" type="xs:ID" use="required"

and the ancestor should have:

xs:attribute name="idref" type="xs:IDREF" use="required"

here some examples (really cool musing over Schema Design):
http://www.xfront.com/GlobalVersusLocal.html




here how to define an id

P1 is a good ID
1 is NOT a good ID

IDs must be unique in the document, otherwise you get a validation error

Still Excel gets confused and gives unhelpful error messages when exporting.

Looking for some better way to visually edit I found JAXFront

Here an excellent demo of JaxFront XUIeditor

here the FAQs; My first question was : does it generate Java code, And the answer is: no, it generates a XUI file which is then run my the JaxFront engine.


I have tested on my XSD and the result was quite satisfactory.

Friday, March 18, 2011

Hibernate Cascading on flushing




this snapshot (taken with YourKit profiler) shows the tremendous performance impact of cascading the flush to dependent objects - even if nothing has to be written to the DB.

Basically if you have
Employee {
String name;
Company company;
}

and you update/flush Employee, the blessed hibernate will try to flush also Company; And if Company contains other dependent objects, the process will go on forever and eat all your CPU.

CascadeType should be NONE by default.

As you can see here
http://www.docjar.com/docs/api/org/hibernate/event/def/AbstractFlushingEventListener.html

there are quite a lot of operations involved when persisting stuff.


So the message is: avoid as much as you can doing "find" operation in a transaction where you do updates (this will autoflush at every find). Also avoid cascading operations on dependent objects.

JAXB, retrieving the Namespace of an element

I hate hardcoding namespaces in my code, so here is how to retrieve it from the JAXB annotated beans:


ObjectFactory oj = new ObjectFactory();
String NAMESPACE = oj.createMyObject(oj.createMyObject()).getName().getNamespaceURI();


Copy/Paste JAR names in Eclipse - screenshot OCR

Something REALLY annoying in Eclipse is that most of the times it doesn't let you copy/paste the name of the JAR files, for instance in the "find type" dialog.

You can install screenocr, it works like a charm (it's only a 21 days licence though)

MDB RunAs

If you get a
"No valid security context for the caller identity"


when your MDB is run, you can either annotate it with:

http://download.oracle.com/javaee/5/api/javax/annotation/security/RunAs.html


or, on JBoss, with

http://docs.jboss.org/ejb3/embedded/api/org/jboss/annotation/security/RunAsPrincipal.html

otherwise you can:

InitialContext ic = new InitialContext();
SessionContext sc = (SessionContext) ic.lookup("java:comp/EJBContext");
Principal p = sc.getCallerPrincipal();


(you can also use @Resource and have the container inject the EJBContext)

but this will not allow you to change principal on the go...

here the Principal javadoc

Thursday, March 17, 2011

hibernate DefaultAutoFlushEventListener.onAutoFlush


this explains very well

http://blog.xebia.com/2008/07/18/configuring-hibernate-and-spring-for-jta/

and

"The Session is sometimes flushed before query execution in order to ensure that queries never return stale state. This is the default flush mode. "


using FlushModeType.COMMIT
http://download.oracle.com/javaee/5/api/javax/persistence/EntityManager.html#setFlushMode%28javax.persistence.FlushModeType%29

improves a LOT performance, because flushing is an expensive operation.
But the result can be undetermined, and in fact my application now breaks because "find" queries don't find non-flushed entities:

see here

"If FlushModeType.COMMIT is set, the effect of updates made to entities in the persistence context upon queries is unspecified. "

:o))) I love working with unspecified products! Such a thrill!
These APIs were designed by lawyers.


Here it says explicitely:

Set flushes to occur at commit or before query execution. If
the flush mode is set to FlushModeType.COMMIT, changes
made during the transaction might not be visible in the
query execution results.


Wednesday, March 16, 2011

Minimalistic MDB on JBoss

http://docs.jboss.org/ejb3/docs/tutorial/1.0.7/html/Message_Driven_Beans.html


import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

import org.apache.log4j.Logger;

@MessageDriven(activationConfig = { 
       @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
       @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/testQueue")
     }, 
     mappedName = "ejb/MyMDB")
     
public class MyMDB implements MessageListener {
 final static Logger logger = Logger.getLogger(MyMDB.class);
 
 public void onMessage(Message paramMessage) {
  TextMessage tm = (TextMessage)paramMessage;
        try {
   String text = tm.getText();
   logger.info("received JMS message" + text);
  } catch (JMSException e) {
   logger.error("unable to read jms message", e);
   
  }
        
  
 }

}


JBoss Tattletale

http://www.jboss.org/tattletale

run it like this:

cd C:\downloads\tattletale-1.1.1.Final
java -Xmx512m -jar tattletale.jar C:/Projects/acme c:/temp/bla

It's really impressive the amount of information that this tool manages to gather...

jar versions, dependencies, classes.... you name it, you find it in the report.

java.net.MalformedURLException: no protocol: Files/eviware/soapUI-3.6.1/hermesJMS/lib/hermes-imq.jar

java.net.MalformedURLException: no protocol: Files/eviware/soapUI-3.6.1/hermesJMS/lib/hermes-imq.jar


if you get this error, most likely you have installed SoapUI in "C:/Program Files/eviware"....

the problem is the space between Program and Files.
Just reinstall it in "C:/Programs",
and I personally think that the idiot that has invented a system folder name with a space in it should be castrated, hoping he has not already made children.



Ok I am a bad mood today, the Planet is sinking because some idiot wanted to save some money on security measures on a nuclear plant in Fukushima... either you do your job properly, or stay at home watching TV.

Me, JMS, HermesJMS and JBoss

http://www.hermesjms.com/


excellent movie here on how to use HermesJMS to connect to JBossMQ:
http://www.hermesjms.com/demos/jboss_config.html

in practice:
configuration
providers
add group name
call it "JBoss 4.0.1"

add jars:

jboss-client, jbossall-client, jbossmq-client, jmx-invoker-adaptor-client, jnp-client (they are in C:\acme\dev\jboss\jboss-4.0.3SP1\client)
concurrent, jboss-jmx
(they are in C:\acme\dev\jboss\jboss-4.0.3SP1\lib)

create initial context

loader=JBoss 4.0.1
providerURL=jnp://localhost:1099
initialContextfactory=org.jnp.interfaces.NamingContextFactory
urlPackagePrefixes=org.jnp.interfaces:org.jboss.naming
securityCredentials=admin
securityAuthentication=admin


here more info on which parameters to use to create a connection:

http://oatv.com/pub/a/onjava/2006/02/22/asynchronous-messaging-with-spring-jms.html?page=3


and at page 5 some Java code on how to send messages to JBossMQ


For convenience, here is the working code:

 private void sendJMS() {
  try {
   String JNDINAME = "queue/testQueue";
      String queueName = "queue/testQueue";
      System.out.println("Queue name is " + queueName);

      InitialContext jndiContext = null;
   /*
       * Create JNDI Initial Context
       */
      try {
          Hashtable env = new Hashtable();
          env.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
          env.put("java.naming.provider.url","localhost");
          env.put("java.naming.factory.url.pkgs",
              "org.jnp.interfaces:org.jboss.naming");

          jndiContext = new InitialContext(env);
      } catch (NamingException e) {
          System.out.println("Could not create JNDI API " +
              "context: " + e.toString());
      }

      QueueConnectionFactory queueConnectionFactory = null;
   Queue queue = null;
   /*
       * Get queue connection factory and queue objects from JNDI context.
       */
      try {
          queueConnectionFactory = (QueueConnectionFactory)
          jndiContext.lookup("UIL2ConnectionFactory");

          queue = (Queue) jndiContext.lookup(queueName);
      } catch (NamingException e) {
          System.out.println("JNDI API lookup failed: " + e.toString());
      }

      QueueConnection queueConnection = null;
   /*
       * Create connection, session, sender objects.
       * Send the message.
       * Cleanup JMS connection.
       */
      try {
          queueConnection =
              queueConnectionFactory.createQueueConnection();
          QueueSession queueSession = queueConnection.createQueueSession(false,
                  Session.AUTO_ACKNOWLEDGE);
          QueueSender queueSender = queueSession.createSender(queue);
          TextMessage message = queueSession.createTextMessage();
          message.setText("This is a sample JMS message.");
          System.out.println("Sending message: " + message.getText());
          queueSender.send(message);

      } catch (JMSException e) {
       logger.error("Exception occurred: ", e);
          
      } finally {
          if (queueConnection != null) {
              try {
                  queueConnection.close();
              } catch (JMSException e) {
               logger.error("unable to close queueConnection", e);
              }
          }
      }
  }
  catch (Exception e) {
   logger.error("unable to send JMS", e);
  }

 }



EntityManager must be access within a transaction

The error means of course
"EntityManager must be accessED within a transaction"

annotating your EJB method with:
@TransactionAttribute(TransactionAttributeType.REQUIRED)

(which is the default), ensures that
"If the client is not associated with a transaction, the container starts a new transaction before running the method."

(see here)
( see also discussion here)

Using the
em.joinTransaction();


you can annotate your method with
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
to make sure you join a brand new transaction

Transaction Timeout in JBoss

as explained here (it doesn't go in too much detail though...)

in conf/jboss-service.xml you will find either:

mbean code="org.jboss.tm.TransactionManagerService"
attribute name="TransactionTimeout" 300


or
mbean code="com.arjuna.ats.jbossatx.jta.TransactionManagerService"
attribute name="TransactionTimeout" 300

(JBoss can be configured with either TM)

otherwise you can annotate your EJB method with

org.jboss.annotation.ejb.TransactionTimeout
(value is in SECONDS I suppose)

but apparently this annotation works only with the jboss TM

http://community.jboss.org/thread/147020


Here the also complain about this.


Anyway you can still grab the transaction and set timeout in your code...ONLY IF YOU DO BMT!

don't use EntityManager.getTransaction(), this is a EntityTransaction and will not expose you the UserTransaction timeout...

you have the SessionContext (=EJBContext) injected this way:

@Resource
private SessionContext sctx;
...

sctx.getUserTransaction().setTransactionTimeout(1500);


if you do this on a CMT, you get this:

java.lang.IllegalStateException: Container bla: it is illegal to inject UserTransaction into a CMT bean
at org.jboss.ejb3.BaseSessionContext.getUserTransaction(BaseSessionContext.java:248)






/:o{=

Luciano about Abstraction

Luciano says:

The problems related to technologies such as (some commercial Integration product) and the like can be traced to a single defect in form: abstraction.
Abstraction is a powerful tool in the bag of a software engineer, but only if applied to specific domains, not to entire areas of competence, as a generic "Enterprise World".
It would be nice to be so, but the "State of the Art" of software engineering has not yet allowed to imagine the implementation of such fine products.

Add to that the commercial appetite of companies like (some Integration Company), which base their Engineering on mantra slogan. Add the substantial technical unpreparedness of most of the middle-management world who has the burden of having to choose products that will define the IT strategy of a company X between now and 5 / 7 years in the future. Here you have a recipe - not so sophisticated - for the preparation of enterprise IT systems who are stillborn, or at least seriously handicapped.




There are other direct consequences. First of all, the attractiveness of certain companies for hackers. For "hackers" I mean professionals who can bring about a high level of integrity and also creativity and passion. The more a company is throwing herself in implementing solutions based on bunches of XML configuration, the less there are conditions for which a "hacker" has an interest in working for that company. The implication of this simple equation means that companies who choose products with a high level of abstraction (and very low level of flexibility) creates a paradox: products that should save money - the very abused ROI - become blacks holes of budget and frustration.

The road leading to the creation of technological abstract suite goes through AI. It 's interesting to see how Google, for example, is investing significant resources in the field of artificial intelligence in related fields. Unfortunately, the current Enterprise product offering is only based on false promises and tons of bad user interfaces.

Tuesday, March 15, 2011

em.getTransaction().commit();

if you "manually" commit a transaction, you might get:

javax.ejb.EJBTransactionRolledbackException: Illegal to call this method from injected, managed EntityManager

in this case you should annotate the method:
@TransactionManagement(TransactionManagementType.BEAN)

to make the transaction management "manual".

You can't have both worlds: either you let the container manage the "begin/end/rollback" lifecycle, or you manage it in its entirety.

Monday, March 14, 2011

YourKit Java Profiling

it's really neat and very easy to install and use:

http://www.yourkit.com

how to add an agent to your application:

http://www.yourkit.com/docs/95/help/running_with_profiler.jsp

To profile an application running in JBoss is very easy:

do Tools/Integrate with JEE server and provide location of your run.bat file,
it will create a run_with_yjp.bat for you.

To profile Java 5, you must use the old version (8).

TPTP, Java Profiling in Eclipse

http://eclipse.org/tptp/home/downloads/

Choose "Install new software":
Test and Performance Tools Platform Project (TPTP) - http://download.eclipse.org/tptp/updates/

choose the latest (4.1.7)


After a couple of hours waiting, I get this error:

An error occurred while installing the items
session context was:(profile=epp.package.jee, phase=org.eclipse.equinox.internal.p2.engine.phases.Install, operand=null --> [R]org.eclipse.tptp.platform.jvmti.runtime 4.6.3.v201102041710, action=org.eclipse.equinox.internal.p2.touchpoint.eclipse.actions.ChmodAction).
The action chmod failed - file C:\eclipse\plugins\org.eclipse.tptp.platform.jvmti.runtime_4.6.3.v201102041710\agent_files\linux_ia32\libACCollector.so does not exist.



(and I am running on Windows XP 32!)


So, desperate, I try to install another profiler, JVM Monitor,
and I get:

Cannot complete the install because one or more required items could not be found.
Software currently installed: Groovy-Eclipse Feature 2.1.1.xx-20101215-2100-e36 (org.codehaus.groovy.eclipse.feature.feature.group 2.1.1.xx-20101215-2100-e36)
Missing requirement: JDT Core patch for Groovy-Eclipse plugin 2.1.1.xx-20101215-2100-e36 (org.codehaus.groovy.jdt.patch.feature.group 2.1.1.xx-20101215-2100-e36) requires 'org.eclipse.jdt.core [3.6.1.xx-20101215-2100-e36]' but it could not be found
Cannot satisfy dependency:
From: Groovy-Eclipse Feature 2.1.1.xx-20101215-2100-e36 (org.codehaus.groovy.eclipse.feature.feature.group 2.1.1.xx-20101215-2100-e36)
To: org.codehaus.groovy.jdt.patch.feature.group [2.1.1.xx-20101215-2100-e36]



(this apparently must be a bug)...

Welcome to Eclipse World /:o(

ManyToOne, OneToMany, ManyToMany

http://download.oracle.com/javaee/6/api/javax/persistence/ManyToOne.html

@ManyToOne(optional=false)
@JoinColumn(name="CUST_ID", nullable=false, updatable=false)
public Customer getCustomer() { return customer; }



http://download.oracle.com/javaee/6/api/javax/persistence/OneToMany.html

@OneToMany(cascade=ALL, mappedBy="customer")
public Set getOrders() { return orders; }



the first is always "me", the second is "the other"

ManyToOne means "there are many of me for one of them" -> hence I have only 1 of them, and he has a Set of me

OneToMany means "there is one of me for many of them" -> hence I have a Set of them


http://download.oracle.com/javaee/6/api/javax/persistence/ManyToMany.html

@ManyToMany
@JoinTable(name="CUST_PHONES")
public Set getPhones() { return phones; }


I have a Set of them, and they have a Set of me

com.arjuna.ats.internal.jta.transaction.arjunacore.inactive

Arjuna is the JBoss transaction manager

http://management-platform.blogspot.com/2008/11/transaction-timeouts-and-ejb3jpa.html


the entire stacktrace is:

11:13:43,774 WARN [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.BasicActio
n_58] - Abort of action id a647bde:4e9:4d7de8ef:30 invoked while multiple threads active within it.
11:13:43,790 WARN [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.CheckedAct
ion_2] - CheckedAction::check - atomic action a647bde:4e9:4d7de8ef:30 aborting with 1 threads active!
11:13:44,274 WARN [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.BasicActio
n_40] - Abort called on already aborted atomic action a647bde:4e9:4d7de8ef:30
11:13:44,337 FATAL [TechnicalExceptionHandler] Technical exception [7b2b91d6-ab3
f-4cb6-9bc1-3ae8302d44c5] occured:
java.lang.IllegalStateException: [com.arjuna.ats.internal.jta.transaction.arjuna
core.inactive] [com.arjuna.ats.internal.jta.transaction.arjunacore.inactive] The
transaction is not active!

at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.c
ommitAndDisassociate(TransactionImple.java:1379)
at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.co
mmit(BaseTransaction.java:135)
at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTra
nsactionManagerDelegate.java:87)
at org.jboss.aspects.tx.TxPolicy.endTransaction(TxPolicy.java:175)
at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:87)
at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java
:191)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
java:101)
at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInt
erceptor.java:95)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
java:101)
at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(Stateles
sInstanceInterceptor.java:62)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
java:101)
at org.jboss.aspects.security.AuthenticationInterceptor.invoke(Authentic
ationInterceptor.java:77)
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3Auth
enticationInterceptor.java:110)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
java:101)
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterce
ptor.java:46)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
java:101)
at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(Asynchrono
usInterceptor.java:106)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.
java:101)
at org.jboss.ejb3.stateless.StatelessContainer.localInvoke(StatelessCont
ainer.java:240)
at org.jboss.ejb3.stateless.StatelessContainer.localInvoke(StatelessCont
ainer.java:210)
at org.jboss.ejb3.stateless.StatelessLocalProxy.invoke(StatelessLocalPro
xy.java:84)

Beyond Compare

Let me say a word of praise for this little gem.

http://www.scootersoftware.com/


you can compare recursively into EARs, JArs, ZIP files, folders...

Brilliant, can't live without.

Sunday, March 13, 2011

Solidarity with the people of Japan



The nuclear centrals which have failed in Japan were supposed to be "retired" last year. The nuclear lobby made pressures to keep they going for another 10 years.

MAYBE nuclear is safe. But not in the hands of people who privilege money over human lives.

SAVARA

http://www.jboss.org/savara

"aims to ensure that any artifacts defined during the development lifecycle can be validated against other artifacts in preceding and subsequent phases."

http://www.infoq.com/presentations/Savara

http://pi4tech.blogspot.com/ Steve Ross-Talbot blog



http://en.wikipedia.org/wiki/WS-CDL

I am planning to dig more into Savara - I am deeply unhappy about how requirements, design documents and functional tests are totally uncorrelated these days....
we are information technologists and Word and Visio is all the technology we still use to design our solutions...

Saturday, March 12, 2011

Spring MVC

This is the official doc.

here a nice getting started guide http://www.giantflyingsaucer.com/blog/?p=2373.

And here a "Spring MVC + Hibernate" template application to get started in 2 minutes.

this presentation is quite impressive:

http://www.infoq.com/presentations/Mastering-Spring-MVC-3

although Web programming is really not my cup of tea, so I fell asleep after 40 minutes.


some notes here:

DispatcherServlet is the "universal handler"
defined in web.xml

the ContextLoaderServlet bootstraps Spring and make it available in the web context

the controller runs a scan in the classpath to automatically instantiate all beans

@Controller defines a controller
@RequestMapping defines a request handler


data binding and unmarshalling can be done automatically with annotations - and supports many technologies (REST, JSON...)

RooJavaBean generates getters and setters

Many standard arguments are supported and injected by Spring, resolved based on their type.

Friday, March 11, 2011

ERROR: JDWP unable to get necessary JVMTI capabilities. ["debugInit.c",L279]

When you run twice JBOSS from the same command prompt, in debug mode,
the second time you get this error:

ERROR: JDWP unable to get necessary JVMTI capabilities. ["debugInit.c",L279]


The only workaround I found is to close the command window and open a new one. Mysterious.

GraphML and yEd

yEd is here:

http://www.yworks.com/en/products_yed_about.html

graphml is here:

http://graphml.graphdrawing.org/

cool way to generate graphs in XML (I know, I hate XML)

Thursday, March 10, 2011

Struts File Upload

http://wiki.apache.org/struts/StrutsFileUpload

in a nutshell:


in the JSP:


in the Action:

ProductUploadForm myForm = (ProductUploadForm) form;
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");



// Process the FormFile
FormFile myFile = myForm.getTheFile();
String contentType = myFile.getContentType();
String fileNameAbsolutePath    = myFile.getFileName();
int fileSize       = myFile.getFileSize();

logger.debug("uploading File Name: " + fileNameAbsolutePath + ", File Size: " + fileSize + ", contentType: " + contentType);
String fileName = new File(fileNameAbsolutePath).getName();
String newFileName = STAGING_DIR + fileName + sdf.format(new Date());

try {
 // copy the stream content to a File in a staging directory, adding timestamp to the file name
 File f2 = new File(newFileName);
 OutputStream out = new FileOutputStream(f2);
 InputStream in = myFile.getInputStream();
 byte[] buf = new byte[1024];

 int len;

 while ((len = in.read(buf)) > 0){
  out.write(buf, 0, len);
 }
 in.close();
 out.close();
 logger.debug("finished copying File Name: " + fileNameAbsolutePath);
} catch (Exception e) {
 logger.error("problem uploading file name : " + fileNameAbsolutePath, e);
}




and the Form contains an attribute
private org.apache.struts.upload.FormFile theFile;

with getter and setter

Wednesday, March 9, 2011

UOM Units Of Measure and Conversions in Java

some interesting facts on MAJOR disasters happened because of UOM / Conversion issues:

http://www.slideshare.net/keilw/eclipse-uomo

Here the Project's homepage

Here http://jscience.org/api/index.html?javax/measure/units/package-summary.html the javax.measure.units package

In doubt, I think I will implement a poor man's version of the framework:

enum UOM { KGM, CMT };

UOMValue {
  UOM uom;
  BigDecimal value;
  UOMValue convertTo(UOM targetUOM);
}

and do a switch with hardcoded conversion values.

Some cases which don't fit:

Size is composed by 3 values (len, wid, hei), which have the same UOM.

@EJB mappedName or name? The java:comp/env story

name refers to java:comp/env
mappedName refers to JNDI tree

here a good tutorial on the java:comp/env story

ejbLink: duplicated

this funny error was occurring only because in the tmp directory of JBoss there were some old jars....probably because I have deployed a Web Application in the unpacked format

As with WebLogic, the same rule applies to JBoss: when you see something weird, just empty cache and tmp directories



10:38:04,677 WARN [ServiceController] Problem starting service jboss.j2ee:ear=acme-web.ear,jar=acme-domain.jar,name=BlaRepositoryBean,service=EJB3
java.lang.RuntimeException: could not resolve global JNDI name for @EJB for container BlaRepositoryBean: reference class: acme.domain.repository.VelocityProcessor ejbLink: duplicated in acme-domain.jar
at org.jboss.injection.EjbEncInjector.inject(EjbEncInjector.java:88)
at org.jboss.ejb3.EJBContainer.start(EJBContainer.java:566)
at org.jboss.ejb3.SessionContainer.start(SessionContainer.java:154)
at org.jboss.ejb3.stateless.StatelessContainer.start(StatelessContainer.
java:102)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)




Tuesday, March 8, 2011

Funny trends in pageviews stats



it's interesting to notice how page view start climbing on Monday (e.g. 14th Feb), but reach their peak only on  Thursdays and then are dead on the weekend.

It makes me think that people on Mondays still take it easy, and work on earnest only in the middle of the week.... Fridays are definitely easy...

And, of course, only sad lonely geeks google for IT technology on weekends.

Naming conventions for Oracle DDL

Every application should have a 3 letter SYNONYM. eg:

application ORDERPROCESSING has synonym ODP


Every table should have a 3 letter SYNONYM
eg:
table EMPLOYEE has synonym EMP


A technical PK ID should be called EMP_ID

and it should be declared PK as follows:
CONSTRAINT ODP_EMP_PK PRIMARY KEY (EMP_ID) ENABLE

that is: {$applicationSynonym}_{$tableSynonym}_PK



all the VARCHAR2 columns should be declared with the "CHAR" size:
VARCHAR2(30 CHAR)

all the TIME information should be represented as TIMESTAMP(6)

The foreign keys go like this:

alter table EMPLOYEE add constraint
ODP_EMP_LAN_FK
FOREIGN KEY (LAN_ID)
REFERENCES LANGUAGE(LAN_ID);

where LANGUAGE is the FK table and LAN its synonym.

and always explicitly create the index associated to the FK
CREATE INDEX ODP_EMP_LAN_FK_I ON EMPLOYEE(LAN_ID);

Unique constraints UK should be declared this way, and can be attached to an index:

CONSTRAINT
ODP_EMP_UK
UNIQUE (EMP_CODE, EMP_LAN)
USING INDEX
(
create unique index
ODP_EMP_UK_I
on EMPLOYEE(EMP_CODE, EMP_LAN)
)

Eclipse Resource bundle editor

If you find BORING to have to maintain several application-resources.properties file with messages in several languages, then you might find this ResourceBundleEditor useful

http://sourceforge.net/projects/eclipse-rbe/files/Eclipse%203.x/0.7.7/ResourceBundleEditor_v0.7.7.zip/download

Thursday, March 3, 2011

Using gmail as a SMTP server

SMTP Server: smtp.gmail.com
Use Authentication: Yes
Use Secure Connection: Yes (this can be TLS or SSL depending on your mail client)
Username: your GMail account
Password: your GMail password
Port: 465 or 587

(see http://kb.siteground.com/article/How_to_use_Googles_free_SMTP_server.html from which I have copied this info)


Remember to add activation.jar and mail.jar to your CP.

If you get
java.net.UnknownHostException: smtp.gmail.com

try 66.249.93.109 instead

if you are behind a Proxy; you are screwed
http://www.oracle.com/technetwork/java/faq-135477.html#proxy

see also here for more on JavaMail API

and here for a working example.

Create an account in gmail, say "hellopippo@gmail.com" with password "hello"

This code should definitely work - unless you are behind a proxy:

package com.pierre.email;

import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;

/**
 * A simple email sender class.
 */
public class SimpleSender
{
    /**
     * Main method to send a message given on the command line.
     */
    public static void main(String args[])
    {
       
        try
        {
            String to="vernetto@yahoo.com";
            String from="hellopippo@gmail.com";
            String subject="fanculo";
            String body="sei scemissimo";
            send(to, from, subject, body);
        }
        catch (Exception ex)
        {
            System.out.println("Usage: java com.pierre.email.SimpleSender"
                    + "toAddress fromAddress subjectText bodyText");
        }
        System.exit(0);
    }

    /**
     * "send" method to send the message.
     */
    public static void send(String to, String from
            , String subject, String body)
    {
     String smtpServer = "smtp.gmail.com"; // or 74.125.91.109
        String username = "hellopippo@gmail.com";
        String password = "hello";
        try
        {
            Properties props = System.getProperties();
            // -- Attaching to default Session, or we could start a new one --
           
            props.put("mail.smtp.host", smtpServer); 
            props.put("mail.smtp.port", "587"); // 587 465
     
   props.put("mail.smtp.user", username);
   props.put("mail.smtp.password", password);
            props.put("mail.smtp.starttls.enable","true");
            props.put("mail.smtp.auth", "true");           
           
            Session session = Session.getDefaultInstance(props, null);
            // -- Create a new message --
            Message message = new MimeMessage(session);
           
            message.setFrom(new InternetAddress(from));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false));
           
            message.setSubject(subject);
            message.setText(body);
            // -- Set some other header information --
            message.setHeader("X-Mailer", "ThisIsPierre");
            message.setSentDate(new Date());
            // -- Send the message --
       
            Transport transport = session.getTransport("smtp");
            transport.connect(smtpServer, username, password);
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();
       
            System.out.println("Message sent OK.");
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }
}



Download JavaMail here

Eclemma - Emma code coverage for Eclipse

http://www.eclemma.org/

I have installed it.... it could not be easier to use.
Priceless!


Remember: your code is not ready for delivery unless it's 100% covered by tests :o) !

At least in an ideal world...

org.hibernate.TransientObjectException

object references an unsaved transient instance - save the transient instance before flushing

classa.product -> Product


just add
@ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST})

to classa.product attribute


This could happen by mistake, for instance if the product has id = 0...

Validate outside the Transaction

Some debate today over whether validation should be done outside or inside a transaction.
For me it's a no-brainer that you should start the transaction only when you need it. And you don't need it to validate your data.


So, I shall create a validate() method with TransactionAttributeType SUPPORTS and a persist() method with REQUIRED.

See also
http://download.oracle.com/javaee/6/api/javax/ejb/TransactionAttribute.html

Of course we use CMT.

See also tips here.


@TransactionManagement(TransactionManagementType.CONTAINER)

@TransactionAttribute(TransactionAttributeType.REQUIRED)

Wednesday, March 2, 2011

Death by Powerpoint


I have just survived 3 days of Powerpoint-based training. I am sure that Jews in concentration camps have endured a worse destiny, but it was really tough.

Trainees would gaze in silence to the screen, while the teacher would talk for hours without interacting with the audience, flipping through hundreds of slides. Nobody would ask any question. No debate. Horrible.

When I attended University, from 1981 to 1986, teachers would simply draw sketches and formulas on a blackboard. It never took me more that 5 days to prepare an exam, because during the lessons I had already assimilated the concepts.

Then in 1985 teachers started using slides - transparent films projected on a screen by a lamp. Those exams were MUCH harder to prepare - it took me more and my marks were lower.

When you can see a concept grow, move, evolve through signs on a blackboard, you understand.
When you see a static diagram where all the information is already arranged, you don't grasp why on earth we ended up there.

Motion, drama, accompanying the development of an idea... this is the key to learning.

Powerpoint is the death of participation, of communication.

detached entity passed to persist

well, if your entity has already an ID, and you invoke
entitymanager.persist(bla)

Hibernate will think you are trying to persist an already existing entity, and he will react giving this stern and cryptic error message.

Just set the ID to null and you will smile again.

When mapping an entity to another, NEVER map the ID!

Generating a FlatXmlDataSet for dbunit

If you use Unitils, you can simplify the sample code provided by DBUnit

(see http://www.dbunit.org/faq.html "How to extract a flat XML dataset from my database? ")


Unitils unitilsInstance = Unitils.getInstance();
unitilsInstance.init();

Properties properties = unitilsInstance.getConfiguration();

// database connection
Class driverClass = Class.forName(properties.getProperty("database.driverClassName")); 
Connection jdbcConnection = DriverManager.getConnection(properties.getProperty("database.url"), properties.getProperty("database.userName"), properties.getProperty("database.password"));
IDatabaseConnection connection = new DatabaseConnection(jdbcConnection);

// partial database export
QueryDataSet partialDataSet = new QueryDataSet(connection);
partialDataSet.addTable("PRODUCT", "SELECT * FROM MYTABLE");

FlatXmlDataSet.write(partialDataSet, new FileOutputStream("c:/MYTABLE.xml"));



It works like a charm... never ever again shall I manually produce those boring dataset XML files...

Generating clone/mapping code

If you find yourself typing manually boring mapping code, there is something wrong.

Either install an Eclipse plugin to generate the code for you,
or use Dozer,
or write a script to generate the code for you.

Here is a simple example of such a script (it's Groovy but it's basically Java)

package com.pierre

import java.lang.reflect.Method

class CloneGenerator {

 static main(args) {
  Class clazz = Class.forName("com.acme.mypackage.MyClass")
  for (Method m : clazz.getMethods()) {
   if (m.getName().startsWith("get")) {
    String attribute = m.getName().substring(3); 
    println("objectDestination.set" + attribute + "(objectSource.get" + attribute + "());")
   }
  }
 }

}



Tuesday, March 1, 2011

Mexican Army

Today I have heard an funny expression "Mexican Army" to describe projects where most of the people on board phylosophize theorize criticize and give orders, while a tiny minority of people actually provide services and solutions.
Allegedly in Mexico for every soldier there are 3 officers.... that's probably why Mexico lost half of his territory to USA... it's a case of "inverted pyramid management", where many give orders and pretend to organize, and few actually work

In fact, also Zorro was always able to make a fool out of Sergeant Garcia