The following method with the classname passed as parameter will return the location of the jar from which the class is loaded.
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
public static String getJarLocation(String className) {
try {
Class cls = Class.forName(className);
ProtectionDomain pDomain = cls.getProtectionDomain();
CodeSource cSource = pDomain.getCodeSource();
URL loc = cSource.getLocation();
return loc.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Alternatively we can also add the following to the startup JVM paramteres , which will print all the classes loaded along with the jar names and its path.
-verbose:class
Saturday, May 16, 2009
Getting jar name & location from loaded class
Scheduling simple Quartz job Using Spring
Currently, Spring supports the Timer, part of the JDK since 1.3, and the Quartz Scheduler (http://www.quartzscheduler.org).
Both schedulers are set up using a FactoryBean with optional references to Timers or Triggers, respectively
Quartx job can be written in several ways
1. Wiring up jobs using triggers and the SchedulerFactoryBean
<bean id="sampleJob" class="com.xyx.SampleJob" />
<bean id="sampleJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="sampleJob" />
<property name="startDelay" value="10000" />
<property name="repeatInterval" value="50000" />
</bean>
OR
<bean id="sampleJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="exampleJob"/>
<!-- run every morning at 6 AM -->
<property name="cronExpression" value="0 0 6 * * ?"/>
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="sampleJobTrigger" />
</list>
</property>
</bean>
2. Using the JobDetailBean
<bean name="exampleJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.xyx.SampleJob"/>
<property name="jobDataAsMap">
<map>
<entry key="timeout" value="5"/>
</map>
</property>
</bean>
In this case com.xyx.SampleJob has to extend QuartzJobBean.
3. Using the MethodInvokingJobDetailFactoryBean
Often you just need to invoke a method on a specific object. Using the MethodInvokingJobDetailFactoryBean you can do as follows
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="sampleJob"/>
<property name="targetMethod" value="sampleMethod"/>
</bean>
The above example will result in the sampleMethod() being called on the sampleJob object.
Ref:
http://www.opensymphony.com/quartz.
http://static.springframework.org/spring/docs/1.2.9/reference/scheduling.html
JMX - Exposing an mbean
JMX is an easy-to-utilize way to expose some of the key inner-workings of your application in a standardized way, so you can maximize the
manageability and monitoring facilities of your application.
A standard MBean is defined by writing a Java interface called SomethingMBean and a Java class called Something that implements that interface.
Every method in the interface defines either an attribute or an operation in the MBean. By default, every method defines an operation.
MBean Interface
public interface TestMBean
{
public void sayHello();
public int add(int x, int y);
}
By convention, an MBean interface takes the name of the Java class that implements it, with the suffix MBean added.
Meab Implementation
public class Test implements TestMBean {
public void sayHello() {
System.out.println("hello, world");
}
public int add(int x, int y) {
return x + y;
}
}
Creating a JMX Agent to Manage a Resource
public class Main {
public static void main(String[] args) throws Exception {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("com.example:type=Test");
Test mbean = new Test();
mbs.registerMBean(mbean, name);
.....
System.out.println("Waiting forever...");
Thread.sleep(Long.MAX_VALUE);
}
}
must contain a domain and a list of key-properties. In the object name defined by Main, the domain is com.example (the package in which the example
MBean is contained). In addition, the key-property declares that this object is of the type Test.
An instance of a Test object, named mbean, is created. The Hello object named mbean is then registered as an MBean in the MBean server mbs with the
object name name, by passing the object and the object name into a call to the JMX method MBeanServer.registerMBean().
Running the Standard MBean Example
Run the sample application
Connect using jconsole and these operations can be directly called from there and values can be set.
Caster - XML/JAVA Object Mapping
Castor is an Open Source data binding framework for Java[tm].Castor provides Java-to-XML binding
Castor XML can marshal almost any "bean-like" Java Object to and from XML. In most cases the marshalling
framework uses a set of ClassDescriptors and FieldDescriptors to describe how an Object should be marshalled
and unmarshalled from XML.
The mapping rules can be mentioned in xml files which makes it easy for customization.
It also has features for java code generation from xml.
http://www.castor.org/
JAXB -Xml/Java Mapping
After looking at many options which helped me convert java classes into xml and vice versa, i found this JAXB very exciting.The Java Architecture
for XML Binding provides a powerful and practical way of working with XML content from within Java applications. The newly released JAXB 2.0 offers
many new features, including full support of all XML Schema features, significantly fewer generated classes, generated classes that are easier to
manipulate, and a more flexible validation mechanism.
JAXB prerequisites
To get started with JAXB 2.0 you need:
1 Java Platform, Standard Edition 5: JAXB 2.0 relies heavily on features of Java SE 5, such as annotations and generics
2. An implementation of JAXB 2.0
I chose this implementation - https://jaxb.dev.java.net/
To start with the JAXb we first need to generate java classes using the xsd.This can be easily done ussing the xjc compiler
syntax : $xjc
Once this command are exceuted the classes are generated in teh given package.These can be used to marshel and unmarshel the xml quite easily.
First we create a JAXBContext
JAXBContext jaxbContext = JAXBContext.newInstance("package.of.the.generated.classes");
Then carete a unmarsheller using the context
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Use the unmarshellor to get the data objects for the xml
DataObj data = (DataObj) unmarshaller.unmarshal(url);
url is URL which returns the xml response.Also xml can be given from a file directly
this data object can ve used to access all other valuse presnt in the xml response.
Ref : http://java.sun.com/developer/technicalArticles/WebServices/jaxb/
http://www.javaworld.com/javaworld/jw-06-2006/jw-0626-jaxb.html
Simple java Regular Expression matching
This simple regular expression matching code just checks for all hyper links in the input string and converts it into proper clickable links in html.
import java.util.regex.*;
public static void main(String args[]) {
System.out.println("test");
String test="sdsfssuwww.yah2oo.com/sds3d jisds sdsds www.google.com/sdsd.htm sds";
Pattern pattern = Pattern.compile("(http://)?www.[a-zA-Z0-9./]*");
Matcher matcher = pattern.matcher(test);
boolean found = false;
while (matcher.find()) {
String a = test.substring(0,matcher.start()-1);
String b =test.substring(matcher.end());
String c=a+"<a href=\""+matcher.group()+"\">"+matcher.group()+"</a> "+b;
System.out.println("a"+a);
System.out.println("b"+b);
System.out.println("c"+c);
found = true;
}
if (!found) {
System.out.println("No match found.");
}
}
Sunday, April 12, 2009
Hibernate Assosiations :Mapping Relations
Let us take the case of Employee and Company , its a typical case for many to one relation. Many employees can belong to a single Company.
Now this relation is unidirectional
@Entity
public class Employee
{
@Id
@GeneratedValue
@Column(name = "F_EMP_ID")
private int empId;
@ManyToOne(optional = true,fetch=FetchType.EAGER)
@JoinColumn
(name = "F_EMP_CMPNY_ID",referencedColumnName="F_CMPNY_ID")
private Company company;
private String name ;
.....
.....
getter and setters for all the values ...
}
@Id : shows its primary key
@GeneratedValue : asks hibernate to generate the primary keys
@Column : to give a java name for a corresponding DB field name
@ManyToOne : shows the many to one realtionship with field company
<Company>
optional : says if this field can be null for Employee row ( true is the default value)
fetch : whether to eagerly fetch the dependent rows (of company ) when fetching employee
(LAZY if the default value , we can change it to FetchType.EAGER)
@JoinColumn - how to join the column for the realtionship
name database field of the current entity which is used for joining
referencedColumnName data base field of the joining entity used for joining
If this field is not mentioned the primary key of the joing entity is taken hence in the above example we ned not mention this value
The other entity in the relationship
@Entity
public class Company
{
@Id
@GeneratedValue
@Column(name = "F_CMPNY_ID")
private int cmpnyId;
private String cmpnyName ;
.....
getter and setters for all the values ...
}
Now in the above example the mapping is complete .Now we can use the entitymanager to fetch any row of Emlpoye entity
(as showm in the previous blog)
entityManager.find(Employee.class, id) --> gives the corresponding Employee
(Note : This statement will come under the scope of @Transactional which manages the session)
Now we can use Employee.getCompany() -> which gives the coresponding Company value
Note:
This is possible because we used fetch=FetchType.EAGER while mentioning the manytoone relation.This ensure that when the request is made for Employee the corresponding Company is also fetched from the DB.
If this option(fetch=FetchType.EAGER) was not mentioned the default one would be used ,that is (fetch=FetchType.LAZY)
Lazy initilization commands hibernate that when Employee is fetched the corresponding , the coresponding Company is not fetched . This is called lazy initilization.Hibernate tries to fetch Company only when i first request is made to the company field in the Employee instance.
Now if this request for company is made outide the scope of @Transaction , that is when no session is open , hibernate gibes a error saying it could not Lazily initialize Company because of Lazy init.
Hence care should be taken to see to that the first request to the depending Entity(in this Company )in the case of FetchType.EAGER should be made inside a valid session.
There is an alternative to get all the dependent rows , when we use Fetch.LAZY . this is by explicitly initializing hibernate.
//include this in the service which gets employee
Employee e = entityManager.find(Employee.class, id);
//this ensures that corresponding company is also fetched along with employee
Hibernate.initialize(employee.getCompany());
//employee.getCompany() -- i sthe first request to Company
return e;
Now the above relation is Unidirectional , that is employee gets Company .Now what if we want to get all the employees in a Company.
We can achive this by making it Bidirectional
We will make small chages in Company Entity to make it bidirectional
@Entity
public class Company
{
@Id
@GeneratedValue
@Column(name = "F_CMPNY_ID")
private int cmpnyId;
private String cmpnyName ;
@OneToMany(mappedBy = "company" ,fetch =FetchType.EAGER)
private List<Employee> employees;
.....
getter and setters for all the values ...
}
@OneToMany - > indicates that the relationship is onetomany with List of employess , that is this company instance can have list of employees
mappedBy -> indicates that the other side is the owner of the relation.
That is a corresponding relation is defined in Employee entity and the
Employee entity had a member variable of Company by name company
fetch =FetchType.EAGER - > defines the type of fetch (Described above)
Now this relation is bidirectional that is when we fetch a Company insatnce we will get all the employees working for it by
Company c = entityManager.find(Company.class, id);
c.getEmployees(); - will return all the emplyees working in that company
One to One mapping
NO\ow to show a one2one mapping lets take a case of Address Entity
public class Address
{
@Id
@GeneratedValue
@Column(name = "F_ADDRS_ID")
private Long id;
.....
// Getters and Setters ...
}
@Entity
public class Company
{
@Id
@GeneratedValue
@Column(name = "F_CMPNY_ID")
private int cmpnyId;
private String cmpnyName ;
@OneToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "F_CMPNY_ID", referencedColumnName = "F_ADDRS_ID")
private Address address;
getter and setters for all the values ...
}
The above relation is similar to the above mentioned many to one relation , and all the attributes for many to one also apply to this.
This relation in Unidirectional and can be made bidirectional by declaring a corresponding relation on Address Entity.
Some Interesting notes on Hibernate
When a primitive value is mapped from a java class to db table column remeber to assign default values to these in the DB ,else when null is
inserted to the column ,and when we retrieve this its gives an error saying null canot be casted to primitive members.Hence for example if null
is present in the DB to retrieve this Wrapper classes such as Integer should be used instead of int.
Though we mention relation(involving primary key) in the classes using annotaions it is also helpful to mention the primary again with indertable and
updatebale equlas false , because in certain cases we need to retrive a row(or certain fileds only) in the db just based on this value and it can be '
hence mentioned in the HQL query directly .
// @Column(name = "F_PRODUCT_CATEGORY_ID" , insertable = false , updatable = false)
// private int pSampleId;\
Still to Follow .....
Many To Many Relation ..
.jpg)