Tuesday, June 29, 2010

The difference between #import, #include and @class in Objective C

If you are an Apple iPhone/ iPad/ Safari developer wondering whats the difference between the Objective C constructs #include#import and @class, read on :

#import and #include

C has the #include preprocessor for including libraries. Objective C supports both #import and #include preprocessors. Apple's recommended way of loading headers in Objective C is to use #import. If you use #include, your header files would need header guards to check if a related header file is already included or not. The #import preprocessor automatically keeps track of headers that have been included and ignores if a header is imported more than once. GNU Objective C compiler supports #import however, it would emit a warning discouraging the use of #import as its strictly not "C" compatible. You can turn off the warning by using the -Wno-import option in the GNU Objective C compiler.

TIP :

If your code is strictly in Objective C and you are looking at strictly supporting Apple SDKs, use #import as the pre-processor. You can turn off the warning by using the -Wno-import option in the GNU Objective C compiler.


#import and @class

As discussed before, #import is a preprocessor that requires the compiler to include the header file. But what if, the class itself is not available to be included or there is a circular reference between class A and class B?

Thats when the construct @class is useful. @class is a "forward declaration" and whenever the compiler encounters an @class forward declaration, the compiler just notes that the actual declaration of the class is coming forward and hence doesnt worry about anything about that class, other than to reserve the memory allocation for a pointer whenever an instance of such forward declared classes are referred to.

For example, in the code

@class A
@interface B :NSObject {
A * instance;  
}

Here, since class A is a forward declaration, the compiler just reserves the memory for a pointer and ignores further validation.

Forward declaration not only reduces the pre-processing overheads and makes compilation & linking faster, but also helps better development as the implementation of class A can be "defered" without impacting the development of class B.

TIP : 


In general use this as a rule of thumb, whenever you are in doubt about #import vs @class :

  1. Always import the header files and framework classes by using #import.
  2. Whenever you need to "send messages" to any class in your implementation, import the relevant headers using #import.
  3. For all other scenarios, use forward declarations with @class.

Tuesday, June 1, 2010

Enabling Automatic Content ID Generation or Increment in Oracle UCM

The Content ID field needs to be specified manually while checking in content in Oracle Universal Content Management (UCM) Content Server, hitherto known as Stellent. The Content ID for any checked in document in the UCM Content Server needs to be unique and is one of the mandatory metadata required during checkin.

This Content ID can be generated automatically as a number or as a sequence with a fixed String literal as prefix.

Any of the following simple steps can be executed to achieve the same :

  1. Through the GUI : Start the Content Server. This can be done either by running the Admin Service in Microsoft Windows or by running IdcAdmin.exe under /admin/bin. Then go to the Content Server Page in a bowser window; follow the navigation path - Administration > Admin Server > [ServerName] > General Configuration. In this form, select the checkbox "Automatically assign a content ID on check in" and enter the prefix text in the field "Auto Number Prefix"
  2. Through the System Properties: In Microsoft Windows, goto Start menu -> Oracle Content Server  -> [ServerName] ->Utilities -> System Properties. In the Options tab, enable the checkbox "Automatically assign a content ID on check in" and enter the prefix text in the field "Auto Number Prefix"
  3. Through the Config : In the config.cfg file under /server/bin; under the section General Option Variables. Add the following two entries -
         IsAutoNumber=true
         AutoNumberPrefix=[ContentIDPrefix]

Now, Restart the Content Server and login to the Content Server page and check in any document. Once the checkin is through; you can see that the Content ID. During checkin, there is still a provision to override with a different Content ID if the user wishes to; as the field would now be optional instead of a mandatory field.

Thursday, May 27, 2010

Steps to alter the maximum number of simultaenous user logins in Oracle XE.

I found it rather strange that to increase the maximum number of connections; you need to increase the processes and not through the web GUI. The steps to alter the maximum number of processes in Oracle XE is similar to Oracle full edition.

Login to the SQL Command Line as sysdba.

SQL> show parameter processes
NAME TYPE VALUE
------------------------------------------------------------------------
processes integer *40*



Then increase the processes.

SQL > alter system set processes=100 scope=spfile.

Restart the database server; Check the processes parameter for confirmation.

This shall increase the number of connections.

Saturday, March 21, 2009

HTTP Session Management in Weblogic

Weblogic offers the following five mechanisms to track and store the state of user requests tracked as HttpSessions -
  1. In Memory Server [Single Server Not Replicated]
  2. JDBC Based
  3. File Based
  4. In Memory Replication
  5. Cookie Based
Weblogic supports declarative programming support for configuring the session persistence in the vendor specific deployment descriptor, WEB-INF/weblogic.xml.

In the first four session management schemes, the user state is stored in the server side and in the fifth , it is stored in the client side. However, in the first four schemes, the Weblogic server may respond with a cookie to the client side, so that subsequent requests from the client indicate the sessionid to the server. This is usually the JSESSIONID cookie stored in the format sessionID!h where h is the hashcode of the server. By default; the cookie name is JSESSIONID and the length of the session id is 52 bytes.

In certain cases like WAP browsers, it may not be possible to store the session cookie in the client side. In such cases, the server must be configured to support session id encoded in the request URL itself. For this, the parameters url-rewriting-enabled as well as encode-session-id-in-query-params must be set to true. In such cases, the response from web application must have only encoded URLs as in - response.encodeURL( "catalog.jsp" ) & response.encodeRedirectUrl( "error.jsp" )

The following is snippet from weblogic.xml with modified configuration supporting URL Rewriting -

<cookie-name>MYSESSIONCOOKIE</cookie-name>
<id-length>12</id-length>
<encode-session-id-in-query-params>true</encode-session-id-in-query-params>
<url-rewriting-enabled>true
</url-rewriting-enabled>


1. In Memory
The default session management scheme is in memory session management; The user data cached in HttpSession is stored in memory.

The limiting factor for the number of sessions that can be stored in the server is governed either by the maximum number of sessions configured as max-in-memory-sessions in the weblogic.xml or by the maximum available memory for the server. When either of this is breached, the Weblogic server responds with a RuntimeException, weblogic.servlet.SessionCreationException indicating that the limit for in memory session management is exhausted. Sessions have a life as configured in timeout-secs. Sessions which have expired are cleaned up periodically releaseing memory and this interval is configured as invalidation-interval-secs. However, the in memory session data is lost when the server shuts down or crashes. Sample weblogic.xml for in memory session management -

<persistent-store-type>memory</persistent-store-type>
<max-in-memory-sessions>1000</max-in-memory-sessions>
<timeout-secs>3600</timeout-secs>
<invalidation-interval-secs>60</invalidation-interval-secs>

2. File Based Session Persistence

The sessions can be persisted into a native file within the server filesystem. File based session management; though costly is useful when there is need to achieve persisted session management beyond the life of the servers.

<persistent-store-type>file</persistent-store-type>
<persistent-store-dir>/opt/sessions</persistent-store-dir>

3. JDBC Based Session Persistence
In JDBC based persistence, the sessions are stored in a database table. The database needs to be configured as a Non-XA JDBC datasource and the table [default WL_SERVLET_SESSIONS] needs to be configured similar to

create table wl_servlet_sessions (
wl_id VARCHAR2(100) NOT NULL,
wl_context_path VARCHAR2(100) NOT NULL,
wl_is_new CHAR(1),
wl_create_time NUMBER(20),
wl_is_valid CHAR(1),
wl_session_values LONG RAW,
wl_access_time NUMBER(20),
wl_max_inactive_interval INTEGER,
PRIMARY KEY (wl_id, wl_context_path)
);

JDBC based session persistence is resilient to server shutdowns / crashes. Weblogic server also caches a few sessions in memory even though they are persisted in memory for improved performance. The session data is stored in binary format in the wl_session_values column. The wl_access_time column of each is updated during any read-only session operation; where as the session writes result in updating both wl_access_time and wl_session_values.

<persistent-store-type>jdbc</persistent-store-type>
<persistent-store-pool>jdbc/SessionDS</persistent-store-pool>
<cache-size>2048</cache-size>
<persistent-store-table>WL_SERVLET_SESSIONS</persistent-store-table>
<jdbc-column-name-max-inactive-interval>jdbc</jdbc-column-name-max-inactive-interval>
<jdbc-connection-timeout-secs>60</jdbc-connection-timeout-secs>

4. In Memory Session Replication
In Memory replication is used in clustered deployments. When a user accesses a shopping cart application deployed in the cluster, and the server (server1), which was handling user requests, goes down; the load balancer or the proxy server may failover the subsequent requests to next server (server2) in the cluster as per the fail over algorithm. However, by default the session is not replicated and the user may be prompted to a fresh login / error page as the session for that user is null in server2. In order to prevent this, web logic provides out of box session replication mechanisms. The replication could happen in memory; or using JDBC / File based persistence. When all the members in the cluster have the same JDBC / File persistence for session management; it is equivalent to having a session replication. In memory replication copies the session information of the user across different servers in the cluster.

<persistent-store-type>replicated</persistent-store-type>
or
<persistent-store-type>replicated_if_clustered</persistent-store-type>
The latter ensures that replication is done only if it is deployed in a cluster; else it uses plain in memory session management.

Weblogic In Memory Session Replication

For instance, in above case if the requests are processed by server1, the session information is also copied into a secondary server (server3) as configured using session replication groups in Weblogic. The server1 then responds with a response header with JSESSIONID as sessionid1!h1!h3; where h1 & h3 are the hash ids for server1 & server3 respectively. Now, when the primary server (server1) goes down and the requests are failed over to another server (server2), the server2 inspects the JSESSIONID; fetches the session information from the backup server (server3) and this is now stored in the current primary server server2. If the secondary replication group is configured for server2, the server may store this information in its secondary server (server4) and hence, the response header contains JSESSIONID cookie in the format sessionid2!h2!h4.


For in memory session replication, the replication groups need to be configured in Weblogic. This is done by two configurations a) The replication group to which a server belongs b) The preferred secondary replication group as shown below.



However, the life of in memory replicated sessions end when all the cluster members go down. For retaining session replications beyond the life of cluster, it is common to use an external caching mechanism which implements the JSR 107 for JCache. Coherence is an Oracle implementation of JSR107. Coherence*Web provides scalable and reliable session replication across Weblogic servers.

5. Cookie

Weblogic can store the client state as cookie [with name WLCOOKIE or as specified in persistent-store-cookie-name]. Cookie persistence is applicable only if the client supports cookies. Hence it may not useful in secure communication or in clients which cant support cookies. Also, this can be used to store only small amounts of data. Cookies support only String persistence. Hence the cookie based persistence has only limited use.

<persistent-store-type>cookie</persistent-store-type>
<persistent-store-cookie-name>WLCOOKIE</persistent-store-cookie-name>

Performance of Various Session Management Schemes
Of the above configurations, File based session persistence has the maximum overhead; while in memory session management is the most optimal while JDBC based session persistence mechanism is inferior to in memory session management.

Asynchronous Session Management Schemes
From Weblogic 10.3, sessions can be configured to be managed asynchronously. Also, it is possible to persist/replicate session data in batches by configuring the throttle size. This is applicable for In Memory, In Memory replication as well as for JDBC based session persistence. The asynchronous session management can hence be configured by specifying persistent-store-type as async-replicated, async-replicated-if-clustered or async-jdbc respectively.


Session Management Best Practices
  1. Use HttpSession as temporary storage for your application state data; not a replacment for database. As much as possible limit the session usage only to state cannot be cached using alternate mechanisms.
  2. Use only Serializable objects in HttpSession.
  3. Use only getAttribute() / setAttribute() to put & fetch session data.
  4. Use In Memory state management as much as possible.
  5. Collate multiple session attributes which are read/updated together into a single Entity before persisting in the session. For example, instead of storing item and quantity as separate attributes; group them into an OrderVO and store.
  6. Similalry; instead of having the overhead of serializing and deserializing big VOs; split the VO into 'read-only' and 'read-write' attributes. For instance, it makes sense to split OrderState and OrderAddress into two separate value objects before storing in the session.

Friday, March 13, 2009

My First Post

Its my first post; thought would start the same way as a Java class. The magic number for a .class file is 0xCAFEBABE. As Patrick Naughton says, the magic number was fixed even before the programming language was christened as Java, probably as a tribute to the cute barristas at the Peet's coffee. Java as a language has matured; its omnipresent from browser applets to swing applications to complex server side components to its miniature form J2ME. Now with the introduction of JavaFx, its bound to give other programming languages a run for their money.

On a spiritual note, this tempts me to compare Java with that of the omnipresent brahman which has been described as vast as the entire universe in Purusha Sukta and as small and pervasive as that miniature particle, which forms the basis of any object living & non living as described in Narayana Sukta.

yaccha kinchit jagat sarvam drishyate shruyatepiva
antar bahischatat sarvam vyapya narayana stitaha

Whatever all this universe is, seen or heard of, pervading all this
from inside and outside alike, stands supreme the
Eternal Divine Being.

Apply this to the enterprise domain, you can safely replace narayana with Java :-)

The primary motivation behind this blog is to write some interesting articles which I can refer back at a later stage; as well as share the same with the rest of the folks in the developer community. Expect to continue the tempo, even after the initial post....