Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Sunday, November 30, 2014

Java Interview Questions

Here few questions that can be asked in job interviews about Java.

Java interview question for experts


Actual Java Version:

Java 21 has arrived in a production release with 15 features including virtual threads, a generational Z garbage collector, and a key encapsulation mechanism API.


Explain Encapsulation:

Encapsulation in java is the process of wrapping code and data inside a single unit, and make this unit accessible or not. This helps to protect the code and give access to use it only through getters and setters that give limits to change variables and data.


Encapsulation access modifiers

In Java, the terms "public," "protected," and "private" provide varied degrees of visibility and encapsulation. In Java:

  • "public" makes a member accessible from any class, 
  • "protected" permits access inside the same package and by subclasses,
  • "private" restricts access to only within the declaring class
  • the default "package-private" gives access only within the package

Abstract class

An abstract class is that which can have one or more than one abstract methods. Abstract class is used to provide abstraction by hiding implementation and leave it on its child class.

  •  Abstract methods are those which don't have implementation/body rather only has its declaration. 
  • it necessarily have abstract keyword.
  • we can't instantiate our abstract class.
  • all variables inside abstract class must be static.

Explain Static in java:

static is a keyword which makes any variable or method a class level variable or class level method ,means we can access it by our class name without making object of class (without instantiating the class).

Collections in java:

List interface: List interface extends the Collection interface, and it is an ordered collection of objects. It contains duplicate elements.

Set interface: Set (java.util.Set) interface is a collection which cannot contain duplicate elements.

Queue interface: Queue (java.util.Queue) interface defines queue data structure, which stores the elements in the form FIFO

Dequeue interface: it is a double-ended-queue

Map interface: A Map (java.util.Map) represents a key, value pair storage of elements. Map interface does not implement the Collection interface


Collections in java


Lambda in java

Lambda expressions are a concise way to represent anonymous functions. They provide implementation of functional interface. Lambda expression allow hence to pass a function as argument and return values from methods.


lambda expressions are a concise way to represent anonymous functions. They allow us to pass functions as arguments to methods and return them as values from methods. An interface which has only one abstract method is called functional interface. Java provides an annotation @FunctionalInterface, which is used to declare an interface as functional interface.

  1. (argument-list) -> {body}


Java functional interface: annotation @FunctionalInterface

A functional interface contains only a single abstract method which is not implemented. It can contains default and static method that have implementation

Functional interfaces are significant because they are the only types that can serve as the context for a lambda expression or method reference in Java 8. Java provide an annotation for them; @functionalInterface.

Here some example of Default functional interfaces in java

java lambda and function interface


Example of function interface:

  • consumer: A Consumer is a functional interface that accepts a single input and returns no output. (biconsumer)
  • supplier: This Functional Interface is used in all contexts where there is no input but an output is expected.
  • function: represents function which take arguments and return result. unaryoperator extend function but the input and oytput is the same type. (unaryOperator work on 1 operator, binaryoperator)
  • predicate: used for conditionel check. represents a boolean value function. Can be used with filter() operator (specialized predicate, intpredicate, longpredicate..)


Streams in java

Streams are wrappers around a data source, allowing us to operate with that data source and making bulk processing convenient and fast.

A stream does not store data and, in that sense, is not a data structure. It also never modifies the underlying data source.

A terminal operation means that once the operation is performed, the stream pipeline is considered consumed and can no longer be used

Intermediate operations such as filter() return a new stream on which further processing can be done. Terminal operations, such as forEach(), mark the stream as consumed, after which point it can no longer be used further.

Tuesday, November 25, 2014

Configure Maven to Deploy on Nexus

Today we will give the tip to deploy your war on Nexus.



So, in order to be able to deploy you war on a remote Repository using Maven, you need to add some configuration to your pom.xml. Here the lines to add :


<distributionManagement>
 <repository>
  <id>releases</id>
  <name>Releases</name>
  <url>http://NEXUS_ADDRESS:8081/nexus/content/repositories/releases/</url>
 </repository>
 <snapshotRepository>
  <id>snapshots</id>
  <name>Snapshots</name>
  <url>http://NEXUS_ADDRESS:8081/nexus/content/repositories/snapshots/</url>
 </snapshotRepository>
</distributionManagement>

You need to make sure that you have the right to deploy on the repository otherwise you may have an error like this :

 Access denied to http://NEXUS_ADDRESS:8081/nexus/content/repositories/snapshots/my_project/my_project/0.0.1-SNAPSHOT/my_projectm2m-0.0.1-20141125.092913-1.war. Error code 401, Unauthorized -> [Help 1]

So if you have access to the server using login/Password, you can provide that information in the .m2/setting.xml file :




<server>
    <id>all</id>
    <username>user</username>
    <password>password</password>
</server>

If you like the post, and it helps you, don't forget to share 

Tuesday, November 4, 2014

JBoss 7 : Set JAVA_OPTS in JBoss standalone.sh

I was working with a JBoss EAP 6 server (based on JBoss As7). This latest is installed on Linux server.

As the allocated memory is not enough, I wanted to add more space. To do so, you think first of modifying the JAVA_OPTS in standalone.sh. But this will not be taken in account.

The solution is in fact to change these JAVA_OPTS parameters in standalone.conf located in jboss-eap-6.2/bin/.


Don't forget to share ...  

Monday, November 3, 2014

Set Authentication WebService and Set Authentication Cookies in SoapUi

After development step, we need to test the Web Services. Using SoapUi, we can give the generated WSDL address and get all the exposed WebMethods.

I developed an application where authentication is needed. So the called method is authenticate which will generate a JSessionId (Cookie) :


@Resource 
private WebServiceContext wsContext;

 
@WebMethod
public User authenticate(@WebParam(name = "userName") String userName, @WebParam(name = "password") String password){
   
 User userToconnect = null;

 HttpServletRequest req = (HttpServletRequest) wsContext.getMessageContext().get(MessageContext.SERVLET_REQUEST);

 userToconnect = webService.authenticate(userName, password);
  
 req.getSession().setAttribute("User", userToconnect);
    
 return userToconnect;  
}

In next method, we will need to get the user. This one will no more be sent by the authenticated user, but it will be retrieved directly from the WebServiceContext.


public User getUser(WebServiceContext wsContext) throws Exception{

 User user = getUserFromSession(wsContext);
 if(user== null){
  throw new  Exception("User not Authenticated ", UamErrorCode.INVALID_PARAMETER);
 }
 return user.getEnterpriseName();
}


Calling the authenticate method using SoapUi, we will get a Set-Cookie in the header.



Then, in next call, user need to specify the given JsessionId. So the Authentication Cookies should be specified in SoapUi for next requests. This can be done using headers. Clic on add, Copy the JSeesionId generated by the autehnticate (copy all the row, paste, then remove the Set-Cookie). Then create a Header called Cookie, and Set the JSESSIONID.



Thant's all, now your method will work.

Don't forget to share with friends ...

Thursday, October 30, 2014

How to read Configuration Property File Keys : Java configuration.properties File


I needed some predefined values in my system. For that, I have declared a property file containing all these values. My configuration.properties looks like this:



1
2
3
threads=5
configurationProfile=default_profile
autostartup=true


In order to load this property file using Java, we need first to put the file under: src/main/resources. Then we use this code:


private Properties configProp=null;
...
public String getProperty(String key, String returnType) throws LoaderException {
 String result = null;
 // the returnType can only be null or STRING return type  
 if((returnType!=null)&&(!returnType.equalsIgnoreCase(STRING_RETURN_TYPE)))
 {
  logger.error("Invalid return type, should be string !! ");
  throw new LoaderException(" Invalid return type, should be string !! ", LoaderErrorEnum.RETURN_TYPE_ERROR);
 }
 try {
  loadFileInMemory();
  result = this.configProp.getProperty(key);
 } catch (Exception e) {
  logger.error("EXCEPTION WHILE GETTING PROPERTY ["+key+ "]" , e);
 }

 return result;
}


So in order to get a property by Key, we need to use :


public String getProperty(String key, String returnType) throws LoaderException {
 String result = null;
 
 if((returnType!=null)&&(!returnType.equalsIgnoreCase(STRING_RETURN_TYPE)))
 {
  logger.error("Invalid return type, should be string !! ");
  throw new LoaderException(" Invalid return type, should be string !! ", LoaderErrorEnum.RETURN_TYPE_ERROR);
 }
 try {
  loadFileInMemory();
  result = this.configProp.getProperty(key);
 } catch (Exception e) {
  logger.error("EXCEPTION WHILE GETTING PROPERTY ["+key+ "]" , e);
 }

 return result;
}


That's all for today. Don't forget to share :)

Sunday, October 26, 2014

Fixed Error assembling WAR: webxml attribute is required

Using Maven, I was building my application, but I get this error.


[ERROR] Failed to execute goal 
org.apache.maven.plugins:maven-war-plugin:2.1.1:war (default-war) on project myProject: 
Error assembling WAR: webxml attribute is required
 (or pre-existing WEB-INF/web.xml if executing in update mode)

In fact, with Servlet 3, I am no more supposed to specify my Web.xml and I can use annotations like @WebServlet, @WebFilter.

So two solutions are possible :


Solution 1 : Add web.xml path
:



<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-war-plugin</artifactId>
 <configuration>
   
          <webXml>src\main\webapps\WEB-INF\web.xml</webXml>
    
 </configuration>
</plugin>

Solution 2 : Ignore the Web.xml as you don't have it



<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-war-plugin</artifactId>
 <configuration>  
  <failOnMissingWebXml>false</failOnMissingWebXml>
 </configuration>
</plugin>



Sunday, October 19, 2014

JSefa tutorial and how to Support for Double, Short Data Type Mapping and Custom String separator

Having a Java Bean object, I wanted to create a CSV file. For that reason, I have used JSEFA which is a Java Simple exchange format API. So JSEFA allows us to convert our Java Bean to CSV file using few lines.

So first, I have created my bean  :


import org.jsefa.csv.annotation.CsvDataType;
import org.jsefa.csv.annotation.CsvField;


@CsvDataType
public class UserInfo {

 @CsvField(pos = 1)
 String userId;
 @CsvField(pos = 2)
 String userPassword;
 @CsvField(pos = 7, converterType = ShortConverter.class)
 Short bloodType;
 @CsvField(pos = 12, converterType = DoubleConverter.class)
 Double altitude;

}

Here if you don't put the Converted, you will get an error of type :

org.jsefa.IOFactoryException: Failed to create an CsvIOFactory
at org.jsefa.csv.CsvIOFactory.createFactory(CsvIOFactory.java:113)
at org.jsefa.csv.CsvIOFactory.createFactory(CsvIOFactory.java:87)
.....
Caused by: org.jsefa.common.mapping.TypeMappingException: Can not create a type mapping for field bloodType of class org.quwic.itms.dal.expression.UserInfo
at org.jsefa.rbf.annotation.RbfTypeMappingFactory.createFieldMappings(RbfTypeMappingFactory.java:181)
at org.jsefa.rbf.annotation.RbfTypeMappingFactory.createComplexTypeMappingIfAbsent(RbfTypeMappingFactory.java:129)

For that reason I have added the convertType = ShortConverter.class. The same thing for the Double type which is not supported by JSEFA.
So the ShortConverter and DoubleConverter classes should be provided. and they need to implements the JSefa Interface SimpleTypeConverter.



import org.jsefa.common.converter.SimpleTypeConverter;

public class DoubleConverter implements SimpleTypeConverter {
 
 private static final DoubleConverter INSTANCE = new DoubleConverter();
 public static DoubleConverter create() {
 return INSTANCE;
 }
 private DoubleConverter() {
 }
 @Override
 public Object fromString(String s) {
 return new Double(s);
 }
 @Override
 public String toString(Object d) {
 return d.toString();
 }

}

Once this is done, you need then to map your beans one by one and create the CSV (or XML file) in your main class:


import java.io.StringWriter;
import org.jsefa.Serializer;
import org.jsefa.csv.CsvIOFactory;
import org.jsefa.csv.config.CsvConfiguration;

public class UsersBeanToCSV {

 public void processUser(List<UserInfo> users){
  CsvConfiguration config = new CsvConfiguration();
  config.setFieldDelimiter(',');
  config.getSimpleTypeConverterProvider().registerConverterType(Double.class, DoubleConverter.class);
  config.getSimpleTypeConverterProvider().registerConverterType(Short.class, ShortConverter.class);
   
  
  Serializer serializer = CsvIOFactory.createFactory(config,MddNotification.class).createSerializer();
  StringWriter writer = new StringWriter();

  serializer.open(writer);
  for(UserInfo user:users){
   serializer.write(user);
  } 
  
  
  serializer.close(true);
 } 
} 

We use here the CsvConfiguration to register the new Converter.
By default, Jsefa uses the ';' to delimit fields, but as  I want to use ',', I declare that using the setFieldDelimiter.

I have just discovered an other issue, so I update my post. In fact, you need to pay attention when the double or Short value may be null (you will have a NullponterException)

 So if the values are optional, you may have some beans with null values.
So you need to modify the DoubleConverter:



import org.jsefa.common.converter.SimpleTypeConverter;

public class DoubleConverter implements SimpleTypeConverter {
 
  private static final DoubleConverter INSTANCE = new DoubleConverter();
  public static DoubleConverter create() {
  return INSTANCE;
  }
  private DoubleConverter() {
  }
  @Override
  public Object fromString(String s) {
   if(s!=null){
    return new Double(s);
   }else{
    return null
   }    
  }
  @Override
  public String toString(Object d) {
   if(d!= null){
    return d.toString();
   }else{
    return null;
   }
  }

}


That's all, hope it helped you :).

Wednesday, September 24, 2014

Java SQL : Get previous item in ResultSet Iteration

I was iterating a ResultSet to  create the bean but in the While loop, I had another While as I may have tow rows having the same Id, but the assignment is different.
So in my Query I try to get information about Persons and the Job to which they was assigned in their life. So if a person worked in 3 different Jobs, by executing the SQL Query, we will get 3 rows for that person, then the other rows for other persons.
For have a better understanding here is the Code:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
while(rs.next()){
 bean = new Person();
 long personSurId = rs.getLong("person_sur_id");
 bean.setDescription(rs.getString("This is a new Person"));
  
 if (withLtJobs){
  bean.setJobAssignments(new ArrayList<PersonJobAssignment>());
  hasChilds = rs.getObject("lt_person_sur_id") != null;
  if (hasChilds){
   do{
    ob = rs.getLong("lt_person_sur_id");
    if (ob.equals(personId)){
     assignment = DAOFactory.getLtPersonJobeDAO().getBean(rs);
     bean.getJobAssignments().add(assignment);
    }else{     
     break;
    }
   }while(rs.next());
  }
 }

 result.add(bean);
}


The problem in this row is that in the the do while loop we will go through the rows. But in the Fourth iteration we will take a row that is no more for that person, so we will break and go to the principle loop where we get the next row. So the Fourth row is lost.

So I need to be able to  GET THE PREVIOUS ROW IN THE RESULTSET before going to the principle Iteration,

So in order to get the Previous Item in the ResultSet, We can use previous methood:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
  if (hasChilds){
   do{
    ob = rs.getLong("lt_person_sur_id");
    if (ob.equals(personId)){
     assignment = DAOFactory.getLtPersonJobeDAO().getBean(rs);
     bean.getJobAssignments().add(assignment);
    }else{  
     rs.previous();
     break;
    }
   }while(rs.next());
  }

Using only this call we will have an Error:

org.postgresql.util.PSQLException: Operation requires a scrollable ResultSet, but this ResultSet is FORWARD_ONLY.
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.checkScrollable(AbstractJdbc2ResultSet.java:235)

Yes, in fct by Default, when we create a Statement or Prepared Statement, the Returned ResultSet is FORWARD_ONLY. So we need to create a Prepared Statement by Specifying that we need a Scrollable ResultSet.  This is done like this:


1
preparedStatement = connection.prepareStatement(sqlStatement.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

Tuesday, September 23, 2014

JPA 2.0 Native Query Result Mapping to a Bean or an Array

Working with JPA 2.0, I wanted to Construct a Bean (Array of Beans) by executing a Native Query.
Using the NamedQuery, we can declare the wanted new Bean, not necessarily an entity. This is done through this Declaration :

1
2
3
@NamedQuery(name="findPerson", 
 query = "SELECT new  org.nd.enterprise.bean.PersonDetail(e.personId, e.birthDate)"
   + " FROM Person p WHERE p.personId = :person")

We need to provide a constructor Containing exactly these parameters.

So Now coming back to the Native query. Sometime, the Query is quite complex so that we need to have it as Native Query. But in that case, it is not possible to declare the Bean inside the Query. And by using the below line we will get an error: org.hibernate.MappingException: Unknown entity: org.nd.enterprise.bean.PersonDetail


1
// Here we declare just a String query = "select ...."
List<PersonDetail> rec2 = entityManager.createNativeQuery(query,PersonDetail.class).getResultList();


This problem is resolved in JPA 2.1, see this post.
But in JPA 2.0, we may use this code :


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
public List<PersonDetail> getPersonByEnterprise(String enterpriseId, List<String> personIds){
 @SuppressWarnings("unchecked")
 List<PersonDetail> records = entityManager.createNamedQuery("personDetailsByEnterprise").setParameter("enterpriseId", enterpriseId).setParameter("personIds", personIds).getResultList();
 List<PersonDetail> personRecords = new ArrayList<PersonDetail>();

 @SuppressWarnings("rawtypes")
 Iterator it = records.iterator( );

 while (it.hasNext( )) {
  Object[] result = (Object[])it.next(); // Iterating through array object 
     
  personRecords.add(new PersonDetail(result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7]));

     }
 return personRecords; 
  
}


So now, don't forget to create the appropriate constructor for PersonDetail.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public PersonDetail(Object enterprise_id, Object person_id, Object name,
   Object surname, Object profession, Object status, Object age, Object lunch_time) {

  
 this.enterpriseId = (String) enterprise_id;
 this.personId = (String) person_id;
 this.name = (String) name;
 this.surname =(String) surname;
 this.profession = (String) profession;
 if(status  != null ){
  this.status = StatusEnum.valueOf((String) status);
 }
 this.age = (Integer) age;
 this.lunchTime= (Date) lunch_time;
}

That's it, hope it helps you :).


Tuesday, May 27, 2014

Create ConcurrentHashmap with a Bean as Key (in Spring Project)

Step 1: Create the Bean Key:

In our case, the Key is a Bean. Normally it should be an immutable, but as I am working with Spring and it is difficult to use immutable beans, I have created a normal bean.


Step 2: Override Equal and HashCode:


Using eclipse, you can generate source code for the hashcode and equal. So you need just to right-clic -> Source -> Generate Hash


So the Bean which will be the Key (here it is called User.java) is :

package main.org.qmic.nr.beans;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("singleton")
public class User {

    String enterprise;
    String name;
    
    
    public User() {
        super();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((enterprise == null) ? 0 : enterprise.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }


    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        User other = (User) obj;
        if (enterprise == null) {
            if (other.enterprise != null)
                return false;
        } else if (!enterprise.equals(other.enterprise))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    
    public User(String enterprise, String name) {
        super();
        this.enterprise = enterprise;
        this.name = name;
    }

    public String getEnterprise() {
        return enterprise;
    }


    public void setEnterprise(String enterprise) {
        this.enterprise = enterprise;
    }

    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }   
}



Step3: Declare the ConcurrentHashMap


private final Map<Device, LatestInfo> latestInfoCache = new ConcurrentHashMap<Device, LatestInfo>();


That's all :)

Wednesday, May 21, 2014

Resolved: Change the Project facet Dynamic Web Module and fix web-app_2_5 xsd

I was using an existing web application. So when I copied the code, I get this error:

Description Resource Path Location Type
Cannot change version of project facet Dynamic Web Module to 2.4. webappVaadin line 1 Maven Java EE Configuration Problem

In fact, in web.xml I have seen that the version of the servlet was 2.4.


1
2
3
<web-app id="WebApp_ID" version="2.4"
 xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">


But in the Project facets, it was Servlet 2.5.



By only changing the version from 2.4 to 2.5, I still get error:

Description Resource Path Location Type
Referenced file contains errors (http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd). 

At the end I have find the solution: For Web 2.5, the namespace has changes from j2ee to javaee, So the declaration should be :


1
2
3
4
5
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
       http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
       version="2.5">

Using Servlet 3.0, we need to declare it like this :

1
2
3
4
5
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
       http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
       version="3.0">



Wednesday, May 7, 2014

JPA Mapping Native Query to Bean (POJO, Class) other than the Entity JPA2.1

Working with JPA 2.0, every time I need to create a new bean (named PersonDetail) from the result of a query, I create a NamedQuery like this:


1
2
3
@NamedQuery(name="findPerson", 
 query = "SELECT new  org.nd.enterprise.bean.PersonDetail(e.personId, e.birthDate)"
   + " FROM Person p WHERE p.personId = :person")

A constructor with the desired output should be set in the PersonDetail bean.

But using the NativeQuery, this is not possible as the Query will be executed like it is given.
In fact while creating the query (NativeQuery or NamedQuery), we can fore the result to be the desired Bean, but this  will generate this error:



1
2
3
4
// Here we declare a @NamedNativeQuery   
List<PersonDetail> rec = entityManager.createNamedQuery("findPerson", PersonDetail.class).getResultList();
// Here we declare just a String query = "select ...."
List<PersonDetail> rec2 = entityManager.createNativeQuery(query,PersonDetail.class).getResultList();

org.hibernate.MappingException: Unknown entity: org.nd.enterprise.bean.PersonDetail

This is normal as it accepts only an Entity and not a Class (See this post to know how to fix that with JPA2.0). Fortenately JPA2.1 comes with the solution, by adding the @ConstructorResult in the @SqlResultSetMapping where you cone construct your Class (In JPA 2.0 only the Entity cn be specified and not another POJO .)




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
 Query q = em.createNativeQuery(
      "SELECT personId, birthDate)"
   + " FROM Person p",
      "PersonDetailsResult");

   @SqlResultSetMapping(
       name="PersonDetailsResult",
       classes={
          @ConstructorResult(
               targetClass=org.nd.enterprise.bean.PersonDetail,
                 columns={
                    @ColumnResult(name="personId"),
                    @ColumnResult(name="birthDate")
                    }
          )
       }
      )

Saturday, April 26, 2014

Resolve TransactionManager lookup fails on JBoss EAP 6 (AS7): No JTA TransactionManager found at fallback JNDI location (NameNotFoundException)

Using JBoss EAP 6.2, I have an application running on it. I needed to exclude the JBoss Logging as explained in this link.
So adding the exclusion in the jboss-deployment-structure.xml I have errors.

 javax.naming.NameNotFoundException: TransactionManager -- service jboss.naming.context.java.module.myprojectname.TransactionManager
org.springframework.transaction.jta.JtaTransactionManager] No JTA TransactionManager found at fallback JNDI location [java:appserver/TransactionManager]
 javax.naming.NameNotFoundException: java:appserver/TransactionManager
javax.naming.NameNotFoundException: java:pm/TransactionManager

Oh oOh what happens. Ayyy. Jboss is angry because I have excluded its logging :|. Ok I will not use the Jboss logging even if it is not happy for that.
So now I need to fix the jndi lookup of the jboss transaction manager. If you look in Standalone.xml, you will not find this jndi name. Strange no !! In fact by default it is java:jboss/TransactionManager.

So all what I need now is to specify to Spring the name of my Transaction Manager. So first, I have removed the old declaration :


<tx:jta-transaction-manager/>

And I substitute it by : 


1
2
3
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
       <property name="transactionManagerName" value="java:jboss/TransactionManager"/>
</bean>

And now every think is working and I can see in the log while deploying :

DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Retrieving JTA TransactionManager from JNDI location [java:jboss/TransactionManager]

Articles les plus consultés