Friday, October 21, 2016

Class Loading in Java - Concept, Class Loader Types, and Related Exceptions

The other day one of my colleagues asked me whether I could explain to him about Java class loading. Then I thought "I know basics about Java Class Loading, but is it complete and accurate?". So I decided to do some search about the topic and it ended with writing this post.

When you launch a Java application using "java" command, one of major operation that happens behind it is the loading of required classes. There are 3 types of classes normally needed for running a Java application.
  1. Classes that defines the implementation of Java platform. These classes are necessary for running basic Java Runtime Environment (JRE).
  2. Classes that implements the functionalities for Java Extension mechanism.
  3. Classes that implements the functionality of your application and the 3rd party libraries required for running your application code.
Process of finding the byte code for a given class name and then converting that byte code to a JVM internal representation of a class, is known as class loading. JVM has 3 separate class loaders for loading each of above mentioned sets of classes. In addition to those, developers can create their own class loaders.
  1. Bootstrap class loader
  2. Extension class loader
  3. System classpath class loader
More details about these class loaders are explained in below sections. Few important things to remember is, 
  • Each of those class loaders has different set of classpaths (directories and jar files to find the classes) to check when it tries to find/load a class. (e.g.: Bootstrap class loader loads class located in "sun.boot.class.path" system property which normally point to a set of jar files in jre/lib folder.)
  • JVM does not load all classes at the start-up, it only loads the required set of classes, and then load the classes dynamically as needed. 
  • The same class loaded by two separate class loaders are not equal. Therefore you cannot cast one of those class to other class, although those were loaded from same class byte code. A loaded class is internally identified by [the package name, class name, the name of the class loader which it loaded]. (Two different class loaders mentioned here does not have parent-child relationship. if that is the case, the class is loaded by same parent.)
The classes loaded by Class Loaders are stored in method area in PermGen area of JVM. Method Area stores the per-class information such as 
  • Class Loader Reference
  • Runtime Constant Pool
  • Field Data
  • Method Data
  • Method Code (Byte code + other information)
All threads share the same Method Area.

Java has following class loader types in addition to user built class loaders.

Class Loader Types

Bootstrap Class Loader (aka Primordial or Null Class Loader)

    Bootstrap Class Loader is the parent class loader of all other class loaders. It is responsible for loading the key classes (from java.* packages etc.) at the beginning of the class loading. It loads the pre-requisite classes needed for supporting a basic Java Runtime Environment. It has access to a set of trusted classes which can be run by JVM without "verification". Bootstrap Class Loader is implemented using native code (mostly in C), not using Java code. But all other Class Loaders are implemented using Java code.
    So when you execute a java program with -verbose:class JVM argument, You can see that first few lines in the output that starts with "[Loaded" are related to the class loading done by Bootstrap Class Loader from jre\lib\rt.jar file and other important jar files the jre\lib directory in your Java installation. This location is known as bootstrap classpath and you can read it from sun.boot.class.path system property.
    You can use -Xbootclasspath non-standard command line option to change the directories of bootstrap class path, but it is not recommended and it violates JRE binary code license. There are two more variation of this command line option; -Xbootclasspath/a  to append to existing bootclasspath, and -Xbootclasspath/p to prepend to existing bootclasspath.

Extension Class Loader

Extension Class Loader is immediate child of the Bootstrap Class Loader. Extension Class Loader is responsible for loading classes from Java extensions directories (value of java.ext.dirs system property including "jre\lib\ext"). These locations has the jar files which implements the Java extension APIs.
Extension Class Loader in JVM is implemented by sun.misc.Launcher$ExtClassLoader. When Extension Class Loader get a call to load a class, it first tries to delegate the loading to the Bootstrap class loader (because it is the parent class loader). If Bootstrap class loader cannot load the class, then Extension Class Loader tries to load the class from "jre\lib\ext" directory or other directories listed in "java.ext.dirs" system property.

System Class Loader (System Classpath Class Loader)

System Class Loader is the immediate child of the Extension Class Loader. This class loader loads the classes from classes and jar files in CLASSPATH environment variable or given in -classpath command line option.
Some important points about Classpath of the System Class Loader,
  • Default classpath is "." aka current directory.
  • You can use CLASSPATH environment variable to define the classpath.
  • You can use -cp or -classpath command line option to define the classpath, this will override the value defined in CLASSPATH environment variable.
  • When you use -jar command line option, it will ignore the values in -cp and -classpath command line options, and also the value of CLASSPATH environment variable. It will only consider the Class-Path attribute defined in the META-INF/mainfest.mf file of the jar file.
  • If two classes with the same name exists in the classpaths, the class loader will load the first found class.
  • Current value of the classpath being used by a java program can be retrieved from java.class.path system property.
System Class Loader is implemented by sun.misc.Launcher$AppClassLoader class and it is a child of Extension Class Loader. You can change the System Classpath Class Loader to use your own class loader implementation instead of sun.misc.Launcher$AppClassLoader, by using -Djava.system.class.loader command line option.

User Defined Class Loaders

Developers can create their own class loaders to support specific requirements of their application. Possible examples for implementing user defined class loaders,
  • to load classes through network.
  • to load classes which are auto generated at runtime.
  • to load classes from encrypted files.
  • to separate class loading of different applications which runs in same JVM.
  • etc.

Class Loading Algorithm

Class loaders (at least JVM class loaders) follow following algorithm when it wants to load a class. (This algorithm is based on delegating the task to parent first.)
  1. Check whether class is already available in the local cache of the current class loader.
  2. If the class was not found in the cache, ask (delegate) the parent class loader to load the class. (Please remember that Bootstrap Class Loader does not have a parent.)
  3. Parent class loader also does above steps recursively until the class found in its cache or no parent class loader found. (Ask parent's parent class loader to load, if parent class loader did not find the class in its cache.).
  4. If the parent class loader can find and load the class, it store it in its cache and return it to its child class loader.
  5. If parent class loader cannot load the class, the class loader tries to load the class from its classpaths (aka code sources).
  6. If the class loader cannot find the class in its local cache and cannot get the class from parent class loaders and cannot load the class from its local code sources, it throws ClassNotFoundException.
Example: When system classpath class loader wants to load javax.imageio.ImageIO class (a class belong to Java Extensions),
  1. System Classpath Class Loader check whether it has javax.imageio.ImageIO class loaded in its local cache.
  2. It does not find it in local cache, so it ask its parent class loader (which is Extensions Class Loader) to load the javax.imageio.ImageIO class.
  3. Extension Class Loader checks its local cache whether it has javax.imageio.ImageIO class.
  4. If it found the javax.imageio.ImageIO class in its local cache, it returns it to the System Classpath Class Loader.
  5. If it did not find the javax.imageio.ImageIO class in its local cache, it ask its parent class loader (which is Bootstrap Class Loader) to load the javax.imageio.ImageIO class.
  6. Bootstrap Class Loader checks whether it has javax.imageio.ImageIO in its local cache. If it has the class in local cache, it returns it to Extension Class Loader method call. (But in our example, Bootstrap class loader should not find the class in its local cache, because the class is in extension classpath).
  7. If Bootstrap Class Loader did not find it in its local cache, and because it does not have any parent class loader, it tries to load the javax.imageio.ImageIO class from its classpath aka its local code sources (bootstrap classpath).
  8. Because the class is belong to Java Extensions, Bootstrap Class Loader does not find it in bootstrap classpath. Then it return the method call to its child class loader (Extension Class Loader) without any class loaded.
  9. Then Extension Class Loader tries to find the javax.imageio.ImageIO class in its classpath aka its local code sources.
  10. Because the class belongs to Java Extensions, Extension Class Loader finds the class in its classpath and loads it. Then put the class in its local cache. Then it returns the class to its child class loader which is System Classpath Class Loader.
    So when a class loader wants to load a class, it first check whether class is already loaded in its local cache, then delegates the loading to the parent class loader if it is not in the current class loader's cache. The class loader will try to load the class itself, only if the parent class loader cannot load the class.
    Therefore the classes loaded by parent class loaders are visible to the children class loaders of that parent class loader. But the classes loaded by a child class loader are not visible to any of parent class loader of the child. Due to this algorithm, a class loaded by parent class loader will not be reloaded by a child class loader of it.


Stages in Class Loading

There are 3 main stages in loading a class from byte code to proper JVM internal representation.
  1. Loading - Class Loader search for the class file (byte code) in the classpath and the byte code is loaded to memory (as a ClassFile structure). This step creates a basic structure for the class, but it does not have all the important data filled yet.
  2. Linking - This step tries to convert byte code data to proper runtime information. This step is sub divided into 3 more sub steps.
    1. Byte Code Verification - the byte code is checked for the correct format and other checks. This step ensures that loaded class is structurally correct.
    2. Class Preparation - This step prepare the data structures to represent methods, fields, and implemented interfaces etc. from the byte code. This step create static fields and initialize those to their default values.
    3. Resolving - This step do the resolving of other classes referenced by this class. (e.g.: Super classes, field types, method param types, method local variable types)
  3. Initializing - This step executes the static initializer blocks.

Class Data Sharing (CDS) feature

 Class Data Sharing (CDS) is a feature introduced in JavaSE 5.0 (in Oracle/Sun hotspot JVM) in order to reduce the java application start-up time by improving class loading time. When the JRE is installed in your machine, JRE loads the classes from system jar files into internal representations and then dump those loaded internal representations to a file known as "shared archive" (which is located in jre/lib/[arch]/client/classes.jsa in UNIX and in jre/bin/client/classes.jsa in Windows). During subsequent JVM invocations, the "shared archive" is used by those JVM processes by memory mapping to it, so reducing the loading time of classes loaded by Bootstrap class loader (which also means this memory mapped file is shared among multiple JVM processes).

If this feature is enabled, you will see many lines with "[Loaded className from shared objects file]" when you run a java application with "-verbose:class" command line argument. The list of classes in the "shared archive" can be found in "jre/lib/classlist" file.

You can use "-XShare" command line option to either enable or disable class data sharing for your java application. 

In JDK 8U40, Oracle has introduced an experimental feature named Application Class Data Sharing (AppCDS) by extending CDS, to allow developers to place classes from Standard Extensions directories and from Application classpath in the "shared archive".

Common Errors/Exceptions related to class loading

ClassNotFoundException

java.lang.ClassNotFoundException is thrown when your program dynamically tries to load the class at runtime and the class loader did not find the requested class. Main reason is, the class is not available in the CLASSPATH.
This is normally thrown by methods like Class.forName(), ClassLoader.loadClass(), ClassLoader.findSystemClass() when the java program tries to load a class dynamically, using its string name. Due to this reason, the compiler does not detect the unavailability of the class at the compile time.

NoClassDefFoundError

java.lang.NoClassDefFoundError happens when JVM or a class loader instance trying to load a class definition, but this class definition cannot be found or loaded due to some reason.
Most of the time, the class was available in the classpath during the compile time, but it is no longer available during the runtime. Another possible reason is, the class is still available in the classpath, but the class has static initialization blocks which fails during the loading of the class.

References:

Saturday, October 15, 2016

Oracle WebLogic Server - Part 1 - Main components and their relationship

In this post series, I am planning to write about the important things I learned about the WebLogic server during past few years (specially about version 10.3.6). Main purpose of these posts is to keep it as a future reference.

The WebLogic Server is an "application server" developed by the Oracle Corporation, and it supports many powerful features such as high availability, scalability, high performance, reliability, etc.

 The WebLogic Server has following main components.

Domain

A WebLogic domain is a logically related group of WebLogic server resources. A WebLogic domain has a special server instance known as “Admin Server”, and zero or more server instances known as “managed servers”.

All WebLogic server instances in a WebLogic domain must have same WebLogic major and minor version. The server instances in a WebLogic domain can be distributed through out several machines.

Admin Server

This is the component which helps the configuration, management, and monitoring of the servers and resources in the whole WebLogic Server domain. You can access the Admin Server through,
  • The "WebLogic Admin Console" web application Or
  • An UNIX shell like command line interface known as "WLST" Or
  • Through JMX API
 All the configurations settings related to the Admin Server, managed servers, clusters, and machines are stored and managed in the Admin Server, mainly in a file named config.xml.

Using Admin Server, You can
  • Start/stop managed servers,
  • Deploy/update/delete applications,
  • Update settings of managed servers/admin server/cluster/etc.,
  • Create/edit/delete more managed servers/clusters/machines etc.
  • Monitor health of the servers.

Managed Servers

In a WebLogic domain, you can have zero or more servers known as "managed servers".  These are separate JVM processes.

A "managed server" is the server process where usually you deploy your application. Although it is possible to deploy an application in Admin Server, it is not the intended usage of the Admin Server.

A “managed server” can be a part of WebLogic cluster, but it is not mandatory.

Clusters

A cluster is a set of managed servers grouped to achieve Scalability (Horizontal scalability) and High Availability. A cluster appears to the client as a single WebLogic server instance (when client access the cluster through a load balancer or use the cluster address to connect to the EJBs in the cluster). All managed server instances in a cluster must belong to the same WebLogic domain. You can create a WebLogic cluster distributed in one or more server machines.

WebLogic cluster has following capabilities in order to achieve the Scalability and High Availability.
  • Application Fail Over Protection
  • Load Balancing
  • Supporting automatic and manual migration of resources between servers in the cluster.

Machines

A “machine” in WebLogic is a logical representation of a physical machine or a virtual machine, which contains one or more WebLogic server instances (Admin Server or managed servers).

In each machine, there is a special process known as “Node Manager” in order for Admin Console to start/stop “managed server” instances in the respective machine, without actually login to that machine. “Machine” configuration includes the listen address and the port of the Node Manager of the respective “machine”.

Machine Types:

  • Unix
  • Virtual
  • Other

Node Manager

In WebLogic Server environment, the Admin Server does not connect to the managed servers directly. In each machine, a separate process named "node manager" should be running for helping this purpose.

A "node manager" process is necessary for managing server instances through Admin Server or similar remote client and to support restarting of failed server instances.

But it is not mandatory to have a node manager process if you do not want above features.

Purpose of Node Manager Process:

  • Allow to stop/start/restart WebLogic server instances in the machine which has the Node Manager process from a remote/local machine (mainly, but not necessarily from the Admin Server)
    • If a server instance started using a node manager fails and AutoRestart attribute of the server set to true, the node manager automatically restart that server instance.
  • Allow monitoring of the health status of WebLogic servers from a remote machine. (mainly, but not necessarily from the Admin Server)
  • Retrieve server logs and node manager logs.

(In the above diagram, Admin Server can be at only one location depicted above in a given domain, not in the both places at once).

Please see my next blog post "Oracle WebLogic Server - Part 2 - Node Manager and its interaction with WebLogic Server instances" for more information about the node manager and its interaction with other components.

References:

Thursday, September 15, 2016

Easiest way to simulate disk full error and out of memory error in a program in Linux

What is /dev/full?

 /dev/full (aka Always Full device) is a special file in Linux, which always returns "No space left on device"  error when a program or a person tries to write to this file. It also provides infinite number of NULL characters when a program tries to read from this file.

The main purpose of this file is for testing programs against "Disk Full" error.

Disk Full Error

The easiest way to demonstrate the "Disk Full" error is by using "echo" command to write something to "/dev/full" file. For testing the "Disk Full" condition in your program, you can try to write the data to "/dev/full" file like you do for writing to a normal file.



Out of Memory Error:

 When you read the /dev/full file, it provides infinite number of NULL characters. Therefore if you use a function which read until the new line (\n) character, it will read the characters to memory until it gets an Out of Memory error. For example, I have created following Java program which uses java.io.BufferedReader.readLine() method. Because this readLine() method read the null characters from the /dev/full without finding any new line characters, the heap space becomes full and it throws java.lang.OutOfMemoryError.


Output:





Wednesday, August 24, 2016

Check DB connection to an Oracle DBMS from a remote machine

Using SQLPLUS:

Execute following command in a command line:
sqlplus "<DB_USERNAME>/<DB_PASSWORD>@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=<HOST_NAME>)(Port=1521))(CONNECT_DATA=(SID=<SID>)))"


You will be able to login to the database in the remote machine, if connection is successful.

Using Weblogic DBPing utility

Execute following command in a command line:
java -classpath <WL_HOME>/<WL_SERVER>/server/lib/weblogic.jar utils.dbping ORACLE_THIN <DB_USERNAME> <DB_PASSWORD> <HOST_NAME>:<DB_PORT>:<SID>

You will get following message if connection is successful.
**** Success!!! ****

You can connect to the database in your app using:

  java.util.Properties props = new java.util.Properties();
  props.put("user", "<DB_USERNAME>");
  props.put("password", "<DB_PASSWORD>");
  java.sql.Driver d =
    Class.forName("oracle.jdbc.OracleDriver").newInstance();
  java.sql.Connection conn =
    Driver.connect("jdbc:oracle:thin:@<HOST_NAME>:<DB_PORT>:<SID>", props);




References:

  •  https://docs.oracle.com/cd/E13222_01/wls/docs/techstart/dbping.html
  • http://javaeesupportpatterns.blogspot.sg/2011/03/network-adapter-could-not-establish.html
  • http://dba.stackexchange.com/questions/13075/how-to-use-sqlplus-to-connect-to-an-oracle-database-located-on-another-host-with

Saturday, April 2, 2016

Using Tkprof tool for Analysing Oracle trace files

What is TkProf?

TkProf is an Oracle tool which helps to convert Oracle trace files to human readable format.

Where to find the tool?

TkProf tool is located in %ORACLE_HOME%/bin folder.

How to use it?

0. login to SQLPlus.
1. First find the trace file dump folder using following sql command.
select value from v$parameter where name = 'user_dump_dest';
The output:
/<PATH TO YOUR DB>/<YOUR_SID>/trace
2. Then enable the sqltrace (This can affect to performance).
alter session set sql_trace=true;

3. Run your sql.
4. Check the trace file by doing a "ls -ltr | grep _ora_". You can run a shell command within SQLPlus by prepending "!" to the command.
SQL> !ls -ltr /<PATH TO YOUR DB>/trace | grep _ora_
-rw-rw---- 1 oracleuser dbagroup     1386 Sep 28 14:30 YOUR_SID_ora_27758.trm
-rw-rw---- 1 oracleuser dbagroup     3628 Sep 28 14:30 YOUR_SID_ora_27758.trc
-rw-rw---- 1 oracleuser dbagroup     1359 Sep 28 14:55 YOUR_SID_ora_29733.trm
-rw-rw---- 1 oracleuser dbagroup     3779 Sep 28 14:55 YOUR_SID_ora_29733.trc
-rw-rw---- 1 oracleuser dbagroup     1355 Oct 21 16:07 YOUR_SID_ora_32487.trm
-rw-rw---- 1 oracleuser dbagroup     3613 Oct 21 16:07 YOUR_SID_ora_32487.trc
-rw-rw---- 1 oracleuser dbagroup     122 Oct 25 14:38 YOUR_SID_ora_6253.trm
-rw-rw---- 1 oracleuser dbagroup     3506 Oct 25 14:38 YOUR_SID_ora_6253.trc
5. The last updated ".trc" file of above output is the one related to our SQL query analysis.
6. Run the tkprof command to get the formatted result. The tkprof tool is located at bin folder of %ORACLE_HOME% folder.
/home/oracleuser[YOUR_SID]:tkprof  /<PATH TO YOUR DB>/YOUR_SID/trace/YOUR_SID_ora_6253.trc  tkprof_out.txt
TKPROF: Release 11.2.0.3.0 - Development on Sun Oct 25 14:41:58 2015
Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.
/home/oracleuser[YOUR_SID]:less tkprof_out_3.txt

More Details:

Please see following websites for more detailed information about how to use TkProf tool and analysing the output.

Example output of TkProf:

TKPROF: Release 11.2.0.3.0 - Development on Sun Oct 25 14:41:58 2015

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

Trace file: /<PATH TO YOUR DB>/YOUR_SID/trace/<YOUR_SID>_ora_6253.trc
Sort options: default

********************************************************************************
count    = number of times OCI procedure was executed
cpu      = cpu time in seconds executing
elapsed  = elapsed time in seconds executing
disk     = number of physical reads of buffers from disk
query    = number of buffers gotten for consistent read
current  = number of buffers gotten in current mode (usually for update)
rows     = number of rows processed by the fetch or execute call
********************************************************************************

SQL ID: 4tk6t8tfsfqbf Plan Hash: 0

alter session set sql_trace=true


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        0      0.00       0.00          0          0          0           0
Execute      1      0.00       0.03          0          0          0           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        1      0.00       0.03          0          0          0           0

Misses in library cache during parse: 0
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS
********************************************************************************

<YOUR_SQL_QUERY>

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        1      0.01       0.01          0         53          1           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      0.01       0.01          0         53          1           0

Misses in library cache during parse: 1
Optimizer mode: CHOOSE
Parsing user id: SYS
Number of plan statistics captured: 1

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         0          0          0  NESTED LOOPS  (cr=53 pr=0 pw=0 time=14025 us)
         0          0          0   NESTED LOOPS  (cr=53 pr=0 pw=0 time=14018 us cost=12 size=162 card=1)
      2502       2502       2502    PARTITION HASH SINGLE PARTITION: 1 1 (cr=53 pr=0 pw=0 time=10393 us cost=12 size=170136 card=2502)
      2502       2502       2502     TABLE ACCESS FULL <YOUR_TABLE_1> PARTITION: 1 1 (cr=53 pr=0 pw=0 time=5007 us cost=12 size=170136 card=2502)
         0          0          0    PARTITION HASH SINGLE PARTITION: KEY KEY (cr=0 pr=0 pw=0 time=6275 us cost=0 size=0 card=1)
         0          0          0     INDEX UNIQUE SCAN <A_PK_INDEX> PARTITION: KEY KEY (cr=0 pr=0 pw=0 time=0 us cost=0 size=0 card=1)(object id 15488)
         0          0          0   TABLE ACCESS BY LOCAL INDEX ROWID <ANOTHER_TABLE_2> PARTITION: 1 1 (cr=0 pr=0 pw=0 time=0 us cost=0 size=94 card=1)




********************************************************************************

********************************************************************************

OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      2      0.00       0.03          0          0          0           0
Fetch        1      0.01       0.01          0         53          1           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.01       0.05          0         53          1           0

Misses in library cache during parse: 1
Misses in library cache during execute: 1


OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        0      0.00       0.00          0          0          0           0
Execute      0      0.00       0.00          0          0          0           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        0      0.00       0.00          0          0          0           0

Misses in library cache during parse: 0

    2  user  SQL statements in session.
    0  internal SQL statements in session.
    2  SQL statements in session.
********************************************************************************
Trace file: /<PATH TO YOUR DB>/YOUR_SID/trace/<YOUR_SID>_ora_6253.trc
Trace file compatibility: 11.1.0.7
Sort options: default

       1  session in tracefile.
       2  user  SQL statements in trace file.
       0  internal SQL statements in trace file.
       2  SQL statements in trace file.
       2  unique SQL statements in trace file.
      59  lines in trace file.
      78  elapsed seconds in trace file.

 

Wednesday, March 23, 2016

JPA ISSUE - Execution of Double (or Multiple) UPDATE SQL Statements for the Updates done on the same Entity Object

Issue:


In a JPA transaction, Updating of the same entity is split into two separate UPDATE SQL statement execution.

Reason:


  1. Some properties of an entity is updated in a transaction.
  2. Then there is a db query to retrieve some data.
  3. This query execution cause the above entity modification to flush to the db. (Due to the JPA implementation).
    •  This cause the execution of the first UPDATE SQL statement.
  4. Update another set of properties of the same entity.
  5. At the next flush event (at the end of TX or execution of another query), The execution of the second UPDATE SQL statement on the same record executed for the last change..
E.g:
// Start modifying bankAccount entity
bankAccount.setName(name);
// Execute a Query which causes flush
List<PaymentOrganization>  paymentOrganizations = paymentOrganizationFacade.getAllOrganizations();
// modify another attribute of same entity
bankAccount.setPaymentOrganizations(paymentOrganizations);

Solution:

Do not put any query execution in between the modifications of different attributes of the same entity object.

E.g:
Move the query before starting the modification of the entity.
List<PaymentOrganization>  paymentOrganizations = paymentOrganizationFacade.getAllOrganizations();
bankAccount.setName(name);
bankAccount.setPaymentOrganizations(paymentOrganizations);

Monday, March 7, 2016

Remote debugging in Weblogic server using Eclipse

In Weblogic server,
Select relevant managed server and go to "Server Start" tab/ Then in the "Arguments:" text box, append following parameters
   -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n

Then, in Eclipse,
  1. Add a new "Remote Java Application" in the Debug Configurations (via the menu: Run -> Debug Configurations).
  2. Make sure the correct project is selected (Browse button) and fill in server name in "Host" and 8000 in "Port".
  3. To avoid Eclipse stopping debug at "Daemon Thread [Timer-xxx] (Suspended (exception RuntimeException)) TimerThread.run()",
    • Go to Preferences -> Java -> Debug
    • Uncheck "Suspend execution on uncaught exceptions" 
Note: It is not necessary to wait until managed server finish startup for the debugging. You can start the debugging after you initiate the managed server startup. This means you can debug post start/activate actions of the managed server also.