venerdì 20 aprile 2012

String equals in Java

Some remarkable samples about String equals vs == comparator in Java.
You may have different output if you use == comparator instead equals for String test.
 See sample code:


public class StringTest {

   
    public static void main (String [] args){
        testA();
       
        testB();
    }

   
    static void testA(){
        System.out.println (" testA");
        // good memory usage!!  RECOMENDED constructor
        String s1 = "a";
        String s2 = "a";
        System.out.println (" s1 = \"a\"");
        System.out.println (" s2 = \"a\"");
        if (s1 == s2 ){
            System.out.println (" s1 == s2 is true");
        } else {
            System.out.println (" s1 == s2 is false");
        }
        if (s1.equals(s2)  ){
            System.out.println (" s1.equals(s2) is true ");
        } else {
            System.out.println (" s1.equals(s2) is false ");
        }
    }
   
    static void testB(){
        System.out.println (" testB");
        // waste memory !! NOT RECOMENDED CONSTRUCTOR FOR STRINGS
        String s1 = new String ("a");
        String s2 = new String("a");
        System.out.println (" s1 = new String(\"a\")");
        System.out.println (" s2 = new String(\"a\")");
        if (s1 == s2 ){
            System.out.println (" s1 == s2");
        } else {
            System.out.println (" s1 == s2 is false");
        }
        if (s1.equals(s2)  ){
            System.out.println (" s1.equals(s2) is true ");
        } else {
            System.out.println (" s1.equals(s2) is false ");
        }
    }




   
This is code output:

 testA
 s1 = "a"
 s2 = "a"
 s1 == s2 is true
 s1.equals(s2) is true
 testB
 s1 = new String("a")
 s2 = new String("a")
 s1 == s2 is false
 s1.equals(s2) is true

 
  /**
     * Comments :
     * String offeres many constructors for Strings:
     *   in testA
     *   String s1 = "a"; create a literal "a" in pool memory ans s1 refers to it
     *   String s2 = "a"; s2 refers to same previous literal in pool.
     *  
     *   otherwise in testB     
     *    String s1 = new String("a") ;  because we use new keyword a new String object is created in not  pool memory (s1 refers to it) and  in addiction literal "a" is placed  in pool memory;
     *    String s2 = new String("a") ;  because we use new keyword a new String object is created in not  pool memory and (different from previous) s2 refers to it
     */
   
   
}


venerdì 13 aprile 2012

Icefaces jsf dinamic data display

Some flexibility in showing data offered by JSF GUI technology.


Message resources
Solution for internazionalization and decoupling jspx code from shown label value
<
f:view xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ice="http://www.icesoft.com/icefaces/component">
<f:loadBundle basename="com.italtel.snodo.messageresource.MessageResources" var="msg" />



Rendered Attribute
Solution for conditional data visualization
Usage: rendered="boolean condition"
es:
rendered="#{!userDataBean.userLogged}"
<ice:outputText value="#{msg['root.logicalAggregation.logicalAggregationView.networkRepository']}" /> /

Ant Tips


1- Launching  Multiple Ant build
Commonly a complete software delivery is made of a set of jar/war files and each jar/war file may be produced by a distintinct ant .xml build file.
To make full release you wish to launch a building process that will call each  ant file in sequence.
This is a sample of a possible solution:
Assume that the whole software realease is the union of this 2 projects (named Project1 and Project2).
Assume that  and each project has it own directory structure and its own build.xml and build.properties file so directory structure is :
/root
     -> Project1
      ->Project2

You may define an upper level  ant file in the root directory:
 <target name="softwareRelease"  description="my full build ant task">
  <ant antfile="Project1/build.xml" target="Build_And__deploy_Jar" inheritAll="false">
   <property file="Project1/build.properties"/>
  </ant>
  <ant antfile="Project2/build.xml" target="Build_And__deploy_Jar" inheritAll="false">
   <property file="Project2/build.properties"/>
  </ant>
 </target>

inheritAll="false" means that each ant refers only to its build.properties file.


2- Ant parameters
Basically you have tree choices to pass parameters to ant build file

build.properties file
This is most used option. Good if your property are the same in all build environment (developers pc , code management environment) otherwise choose another option.
es: in build.properties  file define client.jar.name=file.jar
To use property defined in build.properties file put in build.xml file
<project name="myproject" basedir="." default="build">
 <property file="build.properties"/>
.........
${client.jar.name}


environment variables
This options loads all environment properties. This is a more flexible option than the previous one so you may define different variable values in different building environments.
To use env vars in ant build.xml file
<project name="myproject" basedir="." default="build">
<property environment="env"/>
 ......
env.property

-Dproperty_name=property_value
Also a good option. You may launch ant build with a -Dproperty_name=property_value (as many as you need). This way you may override property value defined in build.properties file (good to ovverride development property values with code management environment values).

martedì 10 aprile 2012

Tablespace full, error codes and autoexend mode in Oracle

Many times applications write on tablespaces util tablespace become full and application doesn't work anymore and blocks.
Probably you should define  some purge policy for your data (to avoid database growing more and more); anyway to fix quicly the problem you have to assign new datafile to full tablespace.
To find out what tablespace is  full you can see in many ways.

1- Check in your application logs for messages  like ORA-  (case hibernate usate as ORM engine here)
 Caused by: org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
        at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
        at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
        at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:92)
        at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:87)
        at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:222)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2229)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2665)
        at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:60)
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
        at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:296)
        ... 134 more
Caused by: java.sql.BatchUpdateException: ORA-01653: unable to extend table INEM_REP.STRUCT_VALUE_ATTRIBUTE by 512 in tablespace EMXDATA01

        at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
        at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10720)
        at org.jboss.resource.adapter.jdbc.WrappedStatement.executeBatch(WrappedStatement.java:774)
        at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
        at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)




2 -Otherwise you may check for ORA-1691 in database alert.log file

ORA-1691: unable to extend lobsegment IEMX_APP.SYS_LOB0000044004C00006$$ by 512 in tablespace              EMXDATA01
ORA-1691: unable to extend lobsegment IEMX_APP.SYS_LOB0000044004C00006$$ by 512 in tablespace              EMXDATA01
ORA-1691: unable to extend lobsegment IEMX_APP.SYS_LOB0000044004C00006$$ by 512 in tablespace              EMXDATA01
ORA-1691: unable to extend lobsegment IEMX_APP.SYS_LOB0000044004C00006$$ by 512 in tablespace              EMXDATA01
ORA-1691: unable to extend lobsegment IEMX_APP.SYS_LOB0000044004C00006$$ by 512 in tablespace              EMXDATA01
ORA-1691: unable to extend lobsegment IEMX_APP.SYS_LOB0000044004C00006$$ by 512 in tablespace              EMXDATA01
ORA-


Now you know what is the full tablespace (EMXDATA01 in my sample)

To find out datafile settings for your tablespace connect to database as sysdba:

# sqlplus  / as sysdba
# SQL>  select TABLESPACE_NAME, FILE_NAME,    AUTOEXTENSIBLE from dba_data_files where TABLESPACE_NAME like 'E%';

TABLESPACE_NAME              FILE_NAME                              AUT
EMXDATA01                        /oradata/iNEM/emxdata01.dbf      NO
This tablespace has no autoendend mode enabled, so now quickest solution is provide an extra datafile for tablespace
       
# SQL>ALTER TABLESPACE EMXDATA01 ADD DATAFILE  /oradata/iNEM/emxdata02.dbf    size 1000m


A SAMPLE SCRIPT TO ANALIZE TABLESPACE DATA CONTENT

Edit  a file named singletspace.sql as follows (this file has an input parameter which is tablespace name ):

CLEAR COLUMNS
CLEAR BREAKS
CLEAR COMPUTES
column "MAX (MB)"  format 9999990D99
column "USED (MB)" format 9999990D99
column "FREE (MB)" format 9999990D99
column "FREE (%)"  format 990D99
column "TABLESPACE_NAME" format A16
select a.tablespace_name, a.max_mb "MAX (MB)",
       (a.max_mb - b.free_mb) "USED (MB)",
       b.free_mb "FREE (MB)",b.free_mb/a.max_mb*100 "FREE (%)"
from
(select substr(tablespace_name,1,20) tablespace_name,
        sum(bytes)/(1024*1024) max_mb
from dba_data_files
group by tablespace_name
) a,
(select
substr(tablespace_name,1,20) tablespace_name,
sum(b.bytes)/(1024*1024) free_mb
from dba_free_space b
group by tablespace_name
) b
where a.tablespace_name=b.tablespace_name
order by 5 asc
/



Then 0pen a SQLPLUS connection to Oracle as sysdba

sqlplus / as sysdba
SQL>@singletspace



ANOTHER USEFULL SQL FILE

EDIT FILE NAMED tablesizebytablespace.sql

COLUMN MBYTES FORMAT 9999990D99
SELECT RPAD(SEGMENT_NAME,29,' ') OBJECT_NAME, RPAD(SEGMENT_TYPE,3,' ') TYPE, RPAD(OWNER,7,' ') OWNER, BYTES/1048576 MBYTES from DBA_SEGMENTS WHERE TABLESPACE_NAME=upper('&1') ORDER BY SEGMENT_NAME;

Run this file as follow:

sqlplus / as sysdba
   spool 06_06_2012_tables.txt
 
   @tablesizebytablespace.sql 'EMXDATA01'
   spool off
  

giovedì 5 aprile 2012

Application Deploy Order Jboss 4.2.x

Applications deployed under jboss often are not independent but with classes in some jars wich refers to other classes in other jars. To avoid messages like "Class Not Found Exceptions"  during jar/war loading at jboss startup you may define jar/war loading order at startup.
Basic  configuration is located in  org.jboss.deployment.MainDeployer-xmbean.xml file under $jboss_home/server/default/conf/xmdesc.
You may define .jar/war loading order at jboss startup in descriptor section as follows from this sample where may define every single file name with a integer for loading priority  :

   <descriptors>
  <value value="250:.rar,300:-ds.xml,400:iEMX-common.jar,410:iEMX-APP.jar,420:iEMX-CCME.jar,430:iNEM-Repository.jar,440:ApplicationConstants.jar,448:iEMX-INV.jar,450:iEMX-core.jar,460:SBCEngine.jar,470:iEMX-wf.jar,475:Backup.jar,480:iemx-if.jar,485:iemx-spml-if.jar,490:OmuFollower.jar,495:StmService.jar,510:FtgpResponder.jar,520:SoftwareDownloadService.jar,530:iNDIM-REPOSITORY.jar,535:Scheduler.jar,540:.jar,550:.war,560:.jse,650:.ear,800:.bsh"/>
 </descriptors>

In this sample I set first  my own jars loading order and later generic statements for jar and war loading (540:.jar,550:.war) . 

martedì 3 aprile 2012

Integration with AMQ and application blocks

AMQ is a messaging middleware commonly used in enterprise applications.
Often,  incorrect use of the AMQ broker because of complete blocks of the system that often lead to failure starting the application server (application server hangs without completing start procedure).
In this section some common problems and possible solutions emerged for persistent topic:1 - Clients subscribe to persistent topic and don't consume messages
If a client subscribes to a queue/topic  and never consumes meggases the broker will retain the messages on file. With defauklt AMQ settings when persistence storage exeeds 1 GB  AMQ stops to store messages and sends to client  flooding messages.
To find if this is your problem check data directory size under $ AMQ_HOME/brokers/data.
es. du -ksh $ AMQ_HOME/brokers/data

 
Then you may proceed as follows:a) Set client connection mode with failover option enabled (prevents system block).connectionFactory.createConnection connection = ();connection.setClientID ("mclientid");connection.createSession session = (false, Session.AUTO_ACKNOWLEDGE);where  

ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_BROKER_URL);

 public static final java.lang.String DEFAULT_BROKER_URL = 'failover :/ / tcp :/ / localhost: 61616

b) Clear the persistence of the queue.After turning off AMQ type this command to clear the datafind $ AMQ_HOME / brokers/data   -name "*"-type f-print-exec rm-f {} \;2 - Block AMQ broker because of persistence of corrupt fsLook at the log file when it appears AMQ error message like below demonstrates the problem is related to corruption of data on AMQ file suystem, this is a problem that sometimes happens in virtual machines.The solution is always to empty the AMQ persistence before rebooting:[Main] ERROR BrokerService - Failed to start ActiveMQ JMS Message Broker. Reason: org.apache.activemq.kaha.impl.index.BadMagicExceptionorg.apache.activemq.kaha.impl.index.BadMagicException
        
at org.apache.activemq.kaha.impl.index.IndexItem.read (IndexItem.java: 141)
        
at org.apache.activemq.kaha.impl.index.StoreIndexReader.readItem (StoreIndexReader.java: 50)
        
at org.apache.activemq.kaha.impl.index.IndexManager.initialize (IndexManager.java: 207)
        
at org.apache.activemq.kaha.impl.index.IndexManager. <init> (IndexManager.java: 60)
        
at org.apache.activemq.kaha.impl.KahaStore.getIndexManager (KahaStore.java: 366)
        
at org.apache.activemq.kaha.impl.KahaStore.getMapContainer (KahaStore.java: 219)
   
        at org.apache.activemq.broker.region.AbstractRegion.createDestination (AbstractRegion.java: 464)
        
at org.apache.activemq.broker.jmx.ManagedQueueRegion.createDestination (ManagedQueueRegion.java: 56)
        
at org.apache.activemq.broker.region.AbstractRegion.addDestination (AbstractRegion.java: 120)
        
at org.apache.activemq.broker.region.RegionBroker.addDestination (RegionBroker.java: 268)
        
at org.apache.activemq.broker.BrokerFilter.addDestination (BrokerFilter.java: 142)
        
at org.apache.activemq.broker.BrokerFilter.addDestination (BrokerFilter.java: 142)
        
at org.apache.activemq.advisory.AdvisoryBroker.addDestination (AdvisoryBroker.java: 153)
        
at org.apache.activemq.broker.BrokerFilter.addDestination (BrokerFilter.java: 142)
        
at org.apache.activemq.broker.MutableBrokerFilter.addDestination (MutableBrokerFilter.java: 149)
        
at org.apache.activemq.broker.region.AbstractRegion.start (AbstractRegion.java: 94)
        
at org.apache.activemq.broker.region.RegionBroker.start (RegionBroker.java: 180)
        
at org.apache.activemq.broker.jmx.ManagedRegionBroker.start (ManagedRegionBroker.java: 100)
        
at org.apache.activemq.broker.TransactionBroker.start (TransactionBroker.java: 112)



C) other best praticse tips:
- use explicit message acknowledge because otherwise ( code example:session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);)  message acknowledge occurs only at the end of onMessage() method ( could affect performance). 
- set message expiration time .
-  use PERSISTENT delivery mode only if you really need it !! ( producer.setDeliveryMode(DeliveryMode.PERSISTENT);
- do not create  ActiveMQConnectionFactory for each new message sent (reuse it).
- use message selector on client side to avoid unwanted messages.


D) others usefull commands to amq status inspection
Topic/Queue information;
activemq-admin query --jmxurl service:jmx:rmi:///jndi/rmi://localhost:3099/jmxrmi -QTopic=*
activemq-admin query --jmxurl service:jmx:rmi:///jndi/rmi://localhost:3099/jmxrmi  -QQueue=*
( QueueSize >> 0  Wrong)(DequeueCount, EnqueueCount, QueueSize, DispatchCount are usefull kpi)


EnqueueCount: The number of messages that have been written to the queue
over the lifetime of the queue.

DequeueCount: The number of messages that have been successfully (i.e.,
they’ve been acknowledged from the consumer) read off the queue over the
lifetime of the queue.

DispatchCount: The number of messages that have been dispatched (sent) to
the consumer over the lifetime of the queue. Note that dispatched messages
may not have all been acknowledged.

InFlightCount: The number of messages that have been dispatched and are
currently awaiting acknowledgment from the consumer. So as this number
decreases, the DequeueCount increases.

QueueSize: The number of messages that currently reside in the queue.

AverageEnqueueTime: On average, the amount of time (ms) that messages
remained enqueued. Or average time it is taking the consumers to
successfully process messages.

MaxEnqueueTime: The maximum amount of time that messages remained enqueued.

MinEnqueueTime: The minimum amount of time that messages remained enqueued.


 activemq-admin browse --amqurl tcp://localhost:61616 SYSTEM.TRAP.NOTIFICATION.JMSTOPIC


Open Connections from/to AMQ (suppose 61616 amq listening port) netstat -tuplan | grep 61616 | wc -l  lsof -i:61616|wc -l

domenica 1 aprile 2012

True ssl web service on jboss 4.2.x

Do you think that your web service responde really  over https port?
Setting https connector on jboss ( https jboss configuration )  is not really enougth , this is only the first configuration step.
Infact you may check if your web service endpoint  is exposed in http or in https from jboss ws console.
You may see a tipical web service miss-configuration in picture below which refers to jboss with https connector enabled but without any specific configuration over web service iteself (web service was created by @wsdl annotation).




You may notice that jboss exposes  wsdl file over an  https url,  but wsdl endpoint is an http path .
To fix this miss configuration issue you have to do two extra operations:
1-          Provide a web.xml file containing security constraints as follows:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> 

  <servlet>
    <servlet-name>ResiIFWSImpl</servlet-name>
    <servlet-class>resiIf.impl.ResiIFWSImpl</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>ResiIFWSImpl</servlet-name>
    <url-pattern>/ResiIFWSImpl</url-pattern>
  </servlet-mapping>

  <security-constraint>
    <web-resource-collection>
      <web-resource-name>All resources</web-resource-name>
      <url-pattern>/ResiIFWSImpl</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
  </security-constraint>
</web-app>

2-          Modify  jboss-beans.xml file under $jboss_home\server\default\deploy\jbossws.sar\jbossws.beans\META-INF           
As follows:
  <!-- An abstraction of server configuration aspects. --> 
  <bean name="WSServerConfig" class="org.jboss.wsf.stack.jbws.NativeServerConfig">
    <property name="mbeanServer"><inject bean="WSMBeanServerLocator" property="mbeanServer"/></property>
   
    <property name="webServiceHost">${jboss.bind.address}</property>
    <property name="modifySOAPAddress">true</property>
                <property name="webServiceSecurePort">8443</property>
    <property name="webServicePort">8080</property>