Java Performance Notes
JVM Overview
Collecting performance statistics
JVM Tuning
1) JVM Overview
1.1) JDK vs JRE
JRE = JVM + Class libraries
JDK = JRE + developer tools (javac, jconsole etc)
Server JRE (above Jre 7u21, no autoupdate )
1.2) Install the JDK
-Windows
-Linux64 : server JRE 64 bit
-Solaris : in to steps first 32 and on top of that 64 bit version
1.3) Major Components of JVM
Hotspot Vm Runtime :
-command line option parsing
-JVM livecycle
-exception handling
-fatal exception handling
-class loading
-interpreter
-java native interface
-thread management and synchronization
Garbage Collector – Memory manager
Influence the performance of a java application
Hotspot JVM has 4 GC’s:
Two are know as ‘stop the world moment’ (STW GC) garbage collectors,the other two are a
combination of STW and concurrent GC
STW GC==> stops all java application threads.
Mostly concurrent GC ==> concurrenlty executes while java application is running
Young gen. vs Old gen.
Perm Gen (Java 6&7) class metadata , class data structures
PermGen does not exist in Java 8 , just metaspace
GC in hotspot:
-Serial GC , single threaded STW young generation collector + single threaded STW old gen collector
(small footprint)
-Throughput GC , multithreaded STW young + old gen collector
-CMS concurrent garbage collector , STW young and , mostly concurrent old generation
-G1 garbage collector (>jdk7u4) multithreaded STW region based young GC + combination of STW and mostly
concurrent old generation GC
G1vs CMS ==> G1 compact old gen without requiring a Full GC
JIT compiler
-takes bytecode ==> native code for the undelying platform.
Understanding the runtime system
java -XX:+PrintFlagsFinal -version ==> to see the runtime params of JVM
Visual GC plugin on VisualVM
Memory Pools plugin
Code Cache – the amount of code that is JIT compiled
For large enterprise application, code cache space might be exhausted so the application slows down because
it disables the JIT compilation
Metrics to monitor
-OS level
-JVM
-Application
OS Level
-CPU usage : user CPU, system CPU and idle time
User CPU : time spent outside OS kernel by a program
Kernel (System) SPU – % spent executing kernel code
Idle CPU – % of CPU not being utilized.
Goal is to execute more User CPU
-Virtual Memory Usage
Attention to swapping !!!
-Process behaviour : context switching,CPU scheduling and thread migrations
Two kidns of context switching :
-voluntary : applicatio threads voluntarily takes itself off the CPU as a result of locks or wating on IO
High values of this ==> indication of lock contention
-involuntary:==> there are a large number of application threads more then the CPU cores available
CPU scheduling queue —> large number of app. threads vs low number of CPU cores ==> system slugish
Disk I/O
Network I/O
Monitor Metrics on Windows
PerfMon – Visual tool
Privileged time – kernel time
https://technet.microsoft.com/en-us/library/bb490960.aspx
typeperf-cpu.txt
ex typeperf -si 5 -cf typeperf-cpu.txt
Monitoring CPU scheduling
Monitorign Virtual Memory Usage
Monitoring Avalable memory and paging activity
If paging is too often ==> swapping http://en.wikipedia.org/wiki/Paging
TBC
SSH (Secure Shell) ,VNC – Dummy network stuff (old article I wrote long time ago)
Despite I’m a developer for many years I never really had to deal with
SSH.Even when I used it ,someone told me to do this and that and since it worked I did not payed attention to it.Nowdays the same happened but this time I was curious to know more.
So with this occasions I wrote a tutorial based on a VTC video tutorial I had but never watched before.So if you plan to nicely watch a video instead of reading then go an buy that tutorial :).
So what is SSH (Secure Shell) ?
SSH is a way to connect remotely to another computer .After you connect you may do administration tasks,or you can share files.All of this in a secure manner.
SSH is a suite of applications : ssh,scp,sftp etc.I will get back on them later in this tutorial.
SSH works on a variety of operating system like unix,linux,windows,mac os,bsd. Some of the platforms come SSH built-in like linux,unix,mac os. Windows require SSH to be installed as separate package. There are some versions on the market , but we will use one of the most common OpenSSH .
SSH operates by default on port 22 .The default port can be changed.
SSH may be used from command line ,but also there some SSH clients that are GUI based.
Note. For those not very familiar ,using SSH implies a client and a server.As i already mentioned unix and linux systems already have bundled everything necessary to use ssh as server or as client.In order to install SSH server on Vista please take a look on this:http://lmgtfy.com/?q=ssh+server+vista. For installing a client go to Putty,a very popular SSH client and not only.
Well in order to configure the service edit the /etc/ssh/sshd_config file and to configure the client edit the /etc/ssh/ssh_config file.Notice that in normal case you will not want to edit these files.I just show you where to look in case you need for example to change the default port of the service.
You can see config files with: cat /etc/ssh/sshd_config or cat /etc/ssh/ssh_config.
How to connect to a remote host that already runs ssh server (daemon,service) ?
How to copy files from remote computer to your computer ?
scp sergiu@cristi:/cygdrive/c/*.* /cygdrive/c/temp
To translate I copy all the files from c: directory located on remote computer called cristi to my localhost’s c:/temp directory.(you can practice this with any path that fits your local directory structure). drive c in cygwing is mapped to /cygdrive/c. I cover more windows like situations using cygwing since on linux this is already covered very very well and windows users are more likely to not know this stuff.
How to use sftp to transfer data ?
I tried the following scenario: On my ubuntu I activated the remote desktop.
So in order to connect on ubuntu desktop I started from another machine on which I have windows and I connect to the default VNC port 5900 without any problem.BUT the connection was not secure ! So here is the SSH comes into schema.
In order to have a secure connection with the remote desktop I did the following from windows cygwin console:
ssh -L 4444:localhost:5900 ubuntubox
This is translated start ssh connection on ubuntubox and alos listen on my localhost 4444 port and redirect any trafic to that port to ubuntubox 5900 port.
Multiple versions of Java on OS X Mavericks
Of course after OS X Mountain Lion it was the time to update my java on OS X Mavericks.
Let’s see how to use multiple versions of java on OS X Mavericks.
I plan to use Java7 and Java 8 from Oracle and to have an easy way of changing the default version.
As you probably know there is a difference between JRE and JDK.If not a very nice response you can find here.
Regarding JRE we should keep in mind that
1) “Only one JRE can be installed at a time. The system will not install a JRE that has a lower version than the current version. If you wish to install a lower version of the JRE, first uninstall the current version.”
2)”Installing a JRE from Oracle will not update java -version symlinks or add java to your path. To be able to do this, you need to install the JDK.”
I installed JdK 7 and Jdk 8
Right after I installed Jdk8 it seems that the simlinks were updated and java -version returned
MacCris:~ cristianchiovari$ java -version java version "1.8.0_20-ea" Java(TM) SE Runtime Environment (build 1.8.0_20-ea-b05) Java HotSpot(TM) 64-Bit Server VM (build 25.20-b05, mixed mode) MacCris:~ cristianchiovari$
as well java_home was set to Jdk 8
MacCris:~ cristianchiovari$ /usr/libexec/java_home /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home
In my .profile i have as well defined
export JAVA_HOME=$(/usr/libexec/java_home)
As well i found very practical this command which is used to choose the default java_home. (it seems it iterates all java installations and the latest version is tool)
MacCris:~ cristianchiovari$ /usr/libexec/java_home -verbose Matching Java Virtual Machines (7): 1.8.0_20, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home 1.7.0_45, x86_64: "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home 1.7.0_11, x86_64: "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_11.jdk/Contents/Home 1.7.0_10, x86_64: "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_10.jdk/Contents/Home 1.7.0_05, x86_64: "Java SE 7" /Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home 1.6.0_65-b14-462, x86_64: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home 1.6.0_65-b14-462, i386: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
Now in order to have latest Jdk7 installed on my computer as default java I had to change in my .profile file
#export JAVA_HOME=$(/usr/libexec/java_home) export JAVA_HOME="`/usr/libexec/java_home -v '1.7*'`"
After opening a new terminal
MacCris:~ cristianchiovari$ java -version java version "1.7.0_45" Java(TM) SE Runtime Environment (build 1.7.0_45-b18) Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
Still
</pre> MacCris:~ cristianchiovari$ /usr/libexec/java_home /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home
That however is not affecting the default java version as described above.
In order to change that you might need to uninstall the Jdk that points to or to use some kind of hacked
as in http://stackoverflow.com/questions/17885494/how-can-i-change-mac-oss-default-java-vm-returned-from-usr-libexec-java-home
Inspired from :
http://docs.oracle.com/javase/7/docs/webnotes/install/index.html
https://developer.apple.com/library/mac/qa/qa1170/_index.html
http://stackoverflow.com/questions/15826202/where-is-java-7-installed-on-mac-os-x
http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html
Java – Interpreted or Compiled ?
Well the answer is not so simple, but we will have one by the end of this short article 🙂
We all know that the source code of a Java file is ‘compiled’ into a .class file.
I put compiled in quotes because the .class file that results is not actually the machine code executed by the machine
The .class (JVM byte code) file might be seen as an intermediary language that might be even modified before is interpreted , compiled and executed.
This happens very often in an JEE environment and it is called weaving.Weaving is a technique of manipulating the byte-code of compiled Java classes.
After we have the final version (might be directly and not necessarily weaved),the byte-code is interpreted and the code is executed .
So where the code is then actually compiled !?
Well an interpreter can generate machine code to get a job done faster if this is important.
A modern VM will use all kind of techniques to do it faster and efficient. For example, for each instruction in the intermediate language the VM could ask which is going to be quicker: to call a routine or to generate machine code to get the job done. This approach is often called Just-In-Time or JIT compilation. It is usually explained as the VM compiling the intermediate language just before it is run, but this isn’t really a good way to think of it.
So the JIT is a sort of mixture of interpreting the code and compiling the code according to what makes best use of the real machine.
To respond to the initial question : it is both !
A diagram that describe the above:
java.net.UnknownHostException on MAC OS X
While trying to start an Apache Derby server on Mac I got:
java.net.UnknownHostException: MacCris: MacCris: nodename nor servname provided, or not known
To solve this:
Step 1 – Open the Terminal
Step 2 – Go to the host file
$ sudo nano /private/etc/hosts
Type your user password when prompted.
Step 3 – Edit the hosts file
127.0.0.1 localhost
127.0.0.1 MacCris
Of course you will replace MacCris with your hostname.
Step 4 – Save the hosts file
When done editing the hosts file, press Control+x to save the file.
Have fun !
Debug problem with weblogic
]] Root cause of ServletException.
java.lang.AssertionError: the tube must call the add(…) method to register itself before start copying other pipes, but weblogic.wsee.jaxws.tubeline.FlowControlTube$FlowControlAwareTube@d10de7 hasn’t done so
at com.sun.xml.ws.api.pipe.TubeCloner.copy(TubeCloner.java:104)
at weblogic.wsee.jaxws.tubeline.FlowControlTube.<init>(FlowControlTube.java:31)
at weblogic.wsee.jaxws.tubeline.FlowControlTube.copy(FlowControlTube.java:50)
at weblogic.wsee.jaxws.tubeline.FlowControlTube.copy(FlowControlTube.java:13)
at com.sun.xml.ws.api.pipe.TubeCloner.copy(TubeCloner.java:102)
at com.sun.xml.ws.api.pipe.TubeCloner.clone(TubeCloner.java:74)
at com.sun.xml.ws.util.Pool$TubePool.create(Pool.java:170)
at com.sun.xml.ws.util.Pool$TubePool.create(Pool.java:161)
at com.sun.xml.ws.util.Pool.take(Pool.java:78)
at com.sun.xml.ws.client.Stub.process(Stub.java:245)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:135)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:109)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:89)
at com.sun.xml.ws.client.sei.SEIStub.in`voke(SEIStub.java:118)
Problem was solved by
modifying the setDomainEnv.cmd by adding -da:com.sun.xml.ws.api.pipe.TubeCloner
set JAVA_DEBUG=
set JAVA_DEBUG= if "%debugFlag%"=="true" ( set JAVA_DEBUG=-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=%DEBUG_PORT%,server=y,suspend=n -Djava.compiler=NONE set JAVA_OPTIONS=%JAVA_OPTIONS% %enableHotswapFlag% -ea -da:com.bea... -da:com.sun.xml.ws.api.pipe.TubeCloner -da:javelin... -da:weblogic... -ea:com.bea.wli... -ea:com.bea.broker... -ea:com.bea.sbconsole... ) else ( set JAVA_OPTIONS=%JAVA_OPTIONS% %enableHotswapFlag% -da )
Just to remember in case it happens again.
Enterprise Service Bus Notes
A thing to know about ESB is that there is not perfect definition for it. The scope and role may vary depending on the needs.
One of the most important things that you can do via ESB is to decouple the client from the service providers
ESB helps to have:
- a service location transparency
- sharing of services accross the enterprise
- separate the business service from service implementation
Esb Capabilities
Routing
The ability to redirect a client request to a particular service provider based on deterministic or variable routing criteria.
Types of routing to consider:
- static or deterministic routing
- content based routing
- policy based routing
- complex rules based routing
Message transformation
The ability to transform the client request to the format the service provider expects it. Most used transformations are:
- Xml -> Xml
- Xml -> Cobol
- Object -> Xml Xml -> Json etc.
Message enforcement
The ability to enrich,enhance the message that comes as request as the service provide requires.Types of message enforcement:
- Date format conversion
- Data conversion (ex: transform spaces to 0)
- Rule based enhancements. (ex: if message is from x add some information to the request)etc.
Protocol transformation
The ability to accept from the consumer one type of protocol as input (ex SOAP/JMS) and communicate to the service provider other protocol (ex: IIOP)
Service Mapping
The ability to translate a business service into the corresponding service implementation and provide binding and location information
Message processing
The ability to manage state and perform request management by accepting an input request and ensuring delivery back to the client via message synchronization.
Process choreography
The ability to manage complex business processes that require the coordination of multiple business services to fulfill a single business request.
Service Orchestration
The ability to manage the coordination of multiple implementation services.
Transaction management
The ability to provide a single unit of work for a business service request by providing a framework for the coordination of multiple resources across multiple disparate services
(see more WS – Coordination)
Security
The ability to protect enterprise services from unauthorized access
ESB should provide 4A’s of security :
- Authentication
- Authorization
- Auditing
- Administration
Multiple versions of Java on OS X Mountain Lion
@This article is deprecated and might be used only for MounatinLion 10.8.1
Before Mountain Lion, Java was bundled inside OS X. It seems that during the upgrade, the Java 6 version I had on my machine was removed.
Apparently the reason for uninstalling Java during the upgrade process was caused by a security issue that the Java runtime had.In this way you are forced to install the latest version which fixed this security problem.
So I went to /Applications/Utilities/ open a Terminal and executed the following command:
java -version ==> “No Java runtime present …”
A window prompted asking to install Java.Click “Install” and get the latest version.I installed it but right after I downloaded and installed the JDK SE 7 from Oracle.
After installation, open the Java Preferences (Launchapad/Others ) and you will see :
Now I knew I had two versions of Java but which one I am using it ?
$ java -version java version "1.6.0_35" Java(TM) SE Runtime Environment (build 1.6.0_35-b10-428-11M3811) Java HotSpot(TM) 64-Bit Server VM (build 20.10-b01-428, mixed mode)
So what if i want to use JDK SE 7 from Oracle ?
Then I had just to drag Java SE 7 in the Java Preferences window to the first position in the list.
This time :
$ java -version java version "1.7.0_05" Java(TM) SE Runtime Environment (build 1.7.0_05-b06) Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)
I said to myself let’s find out more out how Java is installed on OS X so I dug for more.
There are some very useful commands : whereis and which and ls -l.
whereis java ==> /usr/bin/java ls -l /usr/bin/java ==> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java
When I saw this I was a little bit curious so I went to list the Versions directory:
cd /System/Library/Frameworks/JavaVM.framework/Versions ls ==> 1.4 1.5 1.6 A CurrentJDK 1.4.2 1.5.0 1.6.0 Current
Now why do I have this old versions of Java on my machine ? So I asked on Ask Different
http://apple.stackexchange.com/questions/57986/multiple-java-versions-support-on-os-x-and-java-home-location
$ sw_vers ProductName: Mac OS X ProductVersion: 10.8.1 BuildVersion: 12B19 $ ls -l /System/Library/Frameworks/JavaVM.framework/Versions total 64 lrwxr-xr-x 1 root wheel 10 Sep 16 15:55 1.4 -> CurrentJDK lrwxr-xr-x 1 root wheel 10 Sep 16 15:55 1.4.2 -> CurrentJDK lrwxr-xr-x 1 root wheel 10 Sep 16 15:55 1.5 -> CurrentJDK lrwxr-xr-x 1 root wheel 10 Sep 16 15:55 1.5.0 -> CurrentJDK lrwxr-xr-x 1 root wheel 10 Sep 16 15:55 1.6 -> CurrentJDK lrwxr-xr-x 1 root wheel 10 Sep 16 15:55 1.6.0 -> CurrentJDK drwxr-xr-x 7 root wheel 238 Sep 16 16:08 A lrwxr-xr-x 1 root wheel 1 Sep 16 15:55 Current -> A lrwxr-xr-x 1 root wheel 59 Sep 16 15:55 CurrentJDK -> /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents
It seems all the old versions are links to the CurrentJDK version , which is the Apple version, except A and Current which is linked to A.I read something about this on this question.For me A acts like a temp variable. If in Java Preferences you set the in the first position Java 6 from Apple A will have Java 6 from Apple if you put on the first position Java SE 7 from Oracle A will point to this version.Current points to A.
/java -version java version "1.6.0_35" Java(TM) SE Runtime Environment (build 1.6.0_35-b10-428-11M3811) Java HotSpot(TM) 64-Bit Server VM (build 20.10-b01-428, mixed mode)
./java -version java version "1.7.0_05" Java(TM) SE Runtime Environment (build 1.7.0_05-b06) Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)
So it means that in this Current directory will point to the first Java Version found in the Java Preferences.
A very interesting thing is the following information
lrwxr-xr-x 1 root wheel 59 Sep 16 15:55 CurrentJDK -> /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents
This means Java from Apple is actually installed here :”/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/”
What about Java SE 7 ? I could search the filesystem to see but I found an easier way:
If in Java Preferences on the first position is Java SE 7 ==>
$ /usr/libexec/java_home /Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home
If in Java Preferences on the first position is Java SE 6 (System) ==>
$ /usr/libexec/java_home /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
So Java on Mountain Lion (OSX) is more likely to be installed in one of this locations :
- /System/Library/Java/JavaVirtualMachines
- /Library/Java/JavaVirtualMachines
- ~/Library/Java/JavaVirtualMachines
What about /System/Library/Frameworks/JavaVM.framework/Versions ?
It seems that is linked to the so called “Java bridge“.Here it seems is the native part of the Java on OSX installation.
Understanding the concept behind ThreadLocal
Intro
I was aware of thread local but never had the occasion of really using it until recently.
So I start digging a little bit on the subject because I needed an easy way of propagating some user information
via the different layers of my web application without changing the signature of each method called.
Small prerequisite info
A thread is an individual process that has its own call stack.In Java, there is one thread per call stack or one call stack per thread.Even if you don’t create any new threads in your program, threads are there running without your knowledge.Best example is whenyou just start a simple Java program via main method,then you do not implicitly call new Thread().start(), but the JVM creates a main thread for you in order to run the main method.
The main thread is quite special because it is the thread from which all the other thread will spawn and when this
thread is finished, the application ends it’s lifecycle.
In a web application server normally there is a pool of of threads ,because a Thread is class quite heavyweight to create.All JEE servers (Weblogic,Glassfish,JBoss etc) have a self tuning thread pool, meaning that the thread pool increase and decrease when is needed so there is not thread created on each request, and existing ones are reused.
Understanding thread local
In order to understand better thread local I will show very simplistic implementation of one custom thread local.
package ccs.progest.javacodesamples.threadlocal.ex1; import java.util.HashMap; import java.util.Map; public class CustomThreadLocal { private static Map threadMap = new HashMap(); public static void add(Object object) { threadMap.put(Thread.currentThread(), object); } public static void remove(Object object) { threadMap.remove(Thread.currentThread()); } public static Object get() { return threadMap.get(Thread.currentThread()); } }
So you can call anytime in your application the add method on CustomThreadLocal and what it will do is to put in a map the current thread as key and as value the object you want to associate with this thread. This object might be an object that you want to have access to from anywhere within the current executed thread, or it might be an expensive object you want to keep associated with the thread and reuse as many times you want.
You define a class ThreadContext where you have all information you want to propagate within the thread.
package ccs.progest.javacodesamples.threadlocal.ex1; public class ThreadContext { private String userId; private Long transactionId; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public Long getTransactionId() { return transactionId; } public void setTransactionId(Long transactionId) { this.transactionId = transactionId; } public String toString() { return "userId:" + userId + ",transactionId:" + transactionId; } }
Now is the time to use the ThreadContext.
I will start two threads and in each thread I will add a new ThreadContext instance that will hold information I want to propagate for each thread.
package ccs.progest.javacodesamples.threadlocal.ex1; public class ThreadLocalMainSampleEx1 { public static void main(String[] args) { new Thread(new Runnable() { public void run() { ThreadContext threadContext = new ThreadContext(); threadContext.setTransactionId(1l); threadContext.setUserId("User 1"); CustomThreadLocal.add(threadContext); //here we call a method where the thread context is not passed as parameter PrintThreadContextValues.printThreadContextValues(); } }).start(); new Thread(new Runnable() { public void run() { ThreadContext threadContext = new ThreadContext(); threadContext.setTransactionId(2l); threadContext.setUserId("User 2"); CustomThreadLocal.add(threadContext); //here we call a method where the thread context is not passed as parameter PrintThreadContextValues.printThreadContextValues(); } }).start(); } }
Notice:
CustomThreadLocal.add(threadContext) is the line of code where the current thread is associated with the ThreadContext instance
As you will see executing this code the result will be:
userId:User 1,transactionId:1 userId:User 2,transactionId:2
How this is possible because we did not passed as parameter ThreadContext ,userId or trasactionId to printThreadContextValues ?
package ccs.progest.javacodesamples.threadlocal.ex1; public class PrintThreadContextValues { public static void printThreadContextValues(){ System.out.println(CustomThreadLocal.get()); } }
Simple enough 🙂
When CustomThreadLocal.get() is called from the internal map of CustomThreadLocal it is retrived the object associated with the current thread.
Now let’s see the samples when is used a real ThreadLocal class. (the above CustomThreadLocal class is just to understand the principles behind ThreadLocal class which is very fast and uses memory in an optimal way)
package ccs.progest.javacodesamples.threadlocal.ex2; public class ThreadContext { private String userId; private Long transactionId; private static ThreadLocal threadLocal = new ThreadLocal(){ @Override protected ThreadContext initialValue() { return new ThreadContext(); } }; public static ThreadContext get() { return threadLocal.get(); } public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public Long getTransactionId() { return transactionId; } public void setTransactionId(Long transactionId) { this.transactionId = transactionId; } public String toString() { return "userId:" + userId + ",transactionId:" + transactionId; } }
As javadoc describes : ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread
package ccs.progest.javacodesamples.threadlocal.ex2; public class ThreadLocalMainSampleEx2 { public static void main(String[] args) { new Thread(new Runnable() { public void run() { ThreadContext threadContext = ThreadContext.get(); threadContext.setTransactionId(1l); threadContext.setUserId("User 1"); //here we call a method where the thread context is not passed as parameter PrintThreadContextValues.printThreadContextValues(); } }).start(); new Thread(new Runnable() { public void run() { ThreadContext threadContext = ThreadContext.get(); threadContext.setTransactionId(2l); threadContext.setUserId("User 2"); //here we call a method where the thread context is not passed as parameter PrintThreadContextValues.printThreadContextValues(); } }).start(); } }
When get is called , a new ThreadContext instance is associated with the current thread,then the desired values are set the ThreadContext instance.
As you see the result is the same as for the first set of samples.
userId:User 1,transactionId:1 userId:User 2,transactionId:2
(it might be the reverse order ,so don’t worry if you see ‘User 2’ first)
package ccs.progest.javacodesamples.threadlocal.ex2; public class PrintThreadContextValues { public static void printThreadContextValues(){ System.out.println(ThreadContext.get()); } }
Another very usefull usage of ThreadLocal is the situation when you have a non threadsafe instance of an quite expensive object.Most poular sample I found was with SimpleDateFormat (but soon I’ll come with another example when webservices ports will be used)
package ccs.progest.javacodesamples.threadlocal.ex4; import java.text.SimpleDateFormat; import java.util.Date; public class ThreadLocalDateFormat { // SimpleDateFormat is not thread-safe, so each thread will have one private static final ThreadLocal formatter = new ThreadLocal() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("MM/dd/yyyy"); } }; public String formatIt(Date date) { return formatter.get().format(date); } }
Conclusion:
There are many uses for thread locals.Here I describe only two: (I think most used ones)
- Genuine per-thread context, such as user id or transaction id.
- Per-thread instances for performance.
Installing Weblogic on MacOS short notes (reminder for later …)
I had some problems that when I tried to launch the installer from Weblogic the installer UI did not detected the JAVA_HOME.
Despite I installed RcEnvironment http://www.rubicode.com/Software/RCEnvironment/ ,
which is after installation accessible from bottom system preferences on Other ==> Env. Variables., it still did not worked !? 😦
I asked on fault server.com :
http://serverfault.com/questions/377510/path-variables-on-mac-os
http://serverfault.com/questions/67594/where-should-i-modify-the-path-var-on-os-x
However the above link solved some Path and Environment variable on my Mac but did not solved the real problem.
Update : The above is not valid for Mountain Lion 😦
http://apple.stackexchange.com/questions/57385/where-are-system-environment-variables-set-in-mountain-lion
For setting JAVA_HOME and other environment variables :
http://stackoverflow.com/questions/135688/setting-environment-variables-in-os-x
The problem was solved following a link that concern instalation of JDeveloper.
Here is the link :
https://blogs.oracle.com/shay/entry/installing_jdeveloper_on_mac_os
So i run the command :
chmod +x jdev_on_lion.sh
then ./jdev_on_lion.sh
#!/bin/bash mkdir /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/jdk6 mkdir /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/jdk6/bin ln -s /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/bin/java /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/jdk6/bin/java ln -s /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/bin/javac /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/jdk6/bin/javac ln -s /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/bin/javap /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/jdk6/bin/javap ln -s /System/Library/Java/Support/Deploy.bundle/Contents/Home/bin/javaws /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/jdk6/bin/javaws ln -s /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/bin/jar /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/jdk6/bin/jar ln -s /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/bin/xjc /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/jdk6/bin/xjc mkdir /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/jdk6/lib ln -s /system/library/java/javavirtualmachines/1.6.0.jdk/contents/classes/classes.jar /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/jdk6/lib/tools.jar mkdir /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/jdk6/jre mkdir /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/jdk6/jre/bin ln -s /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/bin/java /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/jdk6/jre/bin/java mkdir /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/jdk6/jre/lib ln -s /system/library/java/javavirtualmachines/1.6.0.jdk/contents/classes/classes.jar /system/library/java/javavirtualmachines/1.6.0.jdk/contents/home/jdk6/jre/lib/rt.jar
Update …
It seems now that I have Insufficient disk space no matter that in reality I have way more then 300GB free 🙂
Well luckily I am not the first one that had this problem so the solution came quite fast :
http://dequeue.blogspot.be/2010/04/insufficient-disk-space-weblogic-10320.html
As it is written in this blog the problem is that i need to run the installation jar with the following argument :
java -Dos.name=unix -XX:MaxPermSize=512m -Xmx1024m -jar wls1034_generic.jar
leave a comment