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 :)

Monday, October 27, 2014

JBoss 7 WSConsume with Maven : Generate Web Service Client with WSconsume

I have an application running on JBoss EAP 6. I wants to cnsume a Web service. So I need to generate Web Service Client using maven. For that reason I need to declare this lines in my pom.xml :


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<dependencies>
 <dependency>
  <groupId>org.jboss.ws.cxf</groupId>
  <artifactId>jbossws-cxf-client</artifactId>
  <version>4.1.1.Final</version>
  <scope>provided</scope>
 </dependency>

</dependencies>

<plugins>
 <plugin>
  <groupId>org.jboss.ws.plugins</groupId>
  <artifactId>maven-jaxws-tools-plugin</artifactId>
  <version>1.1.1.Final</version>
  <executions>
   <execution>
    <id>myService</id>
    <goals>
     <goal>wsconsume</goal>
    </goals>
    <configuration>
     <wsdls>
     
      <wsdl>http://localhost:8080/test_project/myService.ws?wsdl</wsdl>
      <wsdl>http://localhost:8080/test_project/mySecondService?wsdl</wsdl>
     </wsdls>
     <targetPackage>org.dcp.clients.myservice</targetPackage>
     <sourceDirectory>${project.basedir}/src/main/java
     </sourceDirectory>
     <extension>true</extension>
     <verbose>true</verbose>
     <goalPrefix>wsconsume</goalPrefix>
    </configuration>
   </execution>

   <execution>
    <id>userService</id>
    <goals>
     <goal>wsconsume</goal>
    </goals>
    <configuration>
     <wsdls>
      <wsdl>http://localhost:8080/user_project/UserService.ws?wsdl</wsdl>
     </wsdls>
     <targetPackage>org.dcp.clients.userservice</targetPackage>
     <sourceDirectory>${project.basedir}/src/main/java
     </sourceDirectory>
     <extension>true</extension>
     <verbose>true</verbose>
     <goalPrefix>wsconsume</goalPrefix>
    </configuration>
   </execution>
  </executions>
 </plugin>

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

</plugins>


So next, just need to run clean install and all the classes will be generated. Some problems may accur when your web service throws some User Exceptions. This will be discussed later.




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 :).

Tuesday, October 14, 2014

Spring Resolve Error : Element 'beans' cannot have character [children], because the type's content type is element-only.

I was working with Spring framework and get this error in the applicationcontext.xml (spring-integration-context.xml with Spring-Integration):

 Element 'beans' cannot have character [children], because the type's content type is element-only.

So something is wrong with my configuration. In fact, after reading carefully again the xml, I have found that I have added a wrong comment. So if you get this error, just check again your xml tags.

I get also this error :

cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'int-mqtt:outbound-channel-adapter'.
- schema_reference.4: Failed to read schema document 'http://www.springframework.org/schema/integration/mqtt/spring-integration-mqtt.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the 
document is not .

In fact the problem was that the given xsd address don't exists. By checking, I have found the right one:

http://www.springframework.org/schema/integration/mqtt/spring-integration-mqtt-4.0.xsd

Normally if you use maven you will not get this error.


Sunday, September 28, 2014

Sparx Enterprise Architect Reverse Engineering : From Code to UML

Working on an existing project which I need to change. I was wondering to get the UML classes to have better idea about it and to know from where to begin.

So using Sparx Enterprise architect, I was able to do the Reverse Engineering by giving my code.
Here are the steps:

First create a new Project in EA.



Clic on the desired Diagram (For me it is Class Diagram), the go to Tools -> Source Code Engineering , then Import Source Directory.



Select the Source Directory and the source language  (Java in my case). Clic on Ok.

All the UML diagrams will be then generated.

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 :).


Monday, September 22, 2014

Jboss EAP 6 : Remote Access to Admin Console and To Web Services in JBoss AS 7 / JBoss EAP 6

By default, JBoss can be accessed only locally using the address 127.0.0.1. So I wasn't able to access the console neither to the web Services (once the application deployed, coming below).
To fix that, we need to make some changes in the "jboss-eap-6.2/standalone/configuration/standalone.xml" where I change the IP addresses from 127.0.0.1 to 0.0.0.0. Like this, JBoss will accept remote call to the Console and to the Web Services.

If your Server is locally, there is no need for this Step and go directly to /jboss-eap-6.2/standalone/configuration/Standalone.xml.

ELSE  :
In order to make it easy to edit remote files, configure FileZilla to edit your files using your favorite program. So in FileZilla go to Edit->Settings and choose you program.




Then:
Come back to Standalone.xml, it should look like this:

So all the addresses are 0.0.0.0.

Now you will be able to access remotely to your Console and to your WSDLs.



Sunday, September 21, 2014

How to Fix Maven compile Cannot find symbol

I was compiling a project using Maven  when I got this error:




Compilation failure: Compilation failure:
[ERROR] /C:/test/unittest/TestManager.java:[3,24] package org.junit does not exist
[ERROR] /C:/test//unittest/TestManager.java:[3,1] static import only from classes and interfaces
[ERROR] /C:/test/unittest/TestManager.java:[138,10] cannot find symbol
[ERROR] symbol:   class Test
[ERROR] location: class org.test.unittest.TestManager
[ERROR]  /C:/test/unittest/TestManager.java:[19,17] cannot find symbol
[ERROR] symbol:   method assertFalse(boolean)

My Junit package was thete as I don't have errors in my code. But NO, I wasn't adding it as a Dependency in the pom but as a jar in my Build Path.

So in order to fix the problem, I have removed JUnit form the Build Path and added it as Dependency:


<dependency>
    <groupId>junit</groupId>
    <artifactId>junit-dep</artifactId>
    <version>4.11</version>
</dependency>


That is it ;)

Log4j 2 Migration Tutorial : Solve ERROR StatusLogger Could not search jar file 'C:\EAP-6.2.0\jboss-eap-6.2\standalone\deployments\myPorject.war\WEB-INF\lib\log4j-core-2.0.2.jar\org\apache\logging\log4j\core

I was working with Log4j-1.2, but have decided to move to Log4j-2.0. I have hence removed the old dependencies and add the new ones.





<dependency>
 <groupId>org.apache.logging.log4j</groupId>
 <artifactId>log4j-core</artifactId>
 <version>2.0.2</version>
</dependency>
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-slf4j-impl</artifactId>
  <version>2.0.2</version>
</dependency>

Once done, I deployed my application but got this error:

ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.

 ERROR StatusLogger Could not search jar file 'C:\EAP-6.2.0\jboss-eap-6.2\standalone\deployments\myProject.war\WEB-INF\lib\log4j-core-2.0.2.jar\org\apache\logging\log4j\core' for classes matching criteria: annotated with @Plugin file not found java.io.FileNotFoundException: C:\EAP-6.2.0\jboss-eap-6.2\standalone\deployments\drl_m2m.war\WEB-INF\lib\log4j-core-2.0.2.jar\org\apache\logging\log4j\core (The system cannot find the path specified)


In fact, using Log4j 2.0, we need to make some changes on the Log4j file :

- Step 1 : Rename it to log4j2.xml. Change also the file structure.



<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Logger name="com.myproject" level="trace">
      <AppenderRef ref="Console"/>
    </Logger>
    <Root level="error">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>


- Step 2 : Change the dependencies to use the 2.0 and no more 1.2 libraries.

- Step 3Remove all the log4j filters and listeners from the web.xml According to this JIRA.

- Step 4: Exclude any dependency to old versions of log4j.



<dependency>
 <groupId>common_m2m</groupId>
 <artifactId>common_m2m</artifactId>
 <version>${project.version}</version>
 <exclusions>
  <exclusion>
   <artifactId>log4j</artifactId>
   <groupId>log4j</groupId>
  </exclusion>
 </exclusions>
</dependency>

- Step 5: Change the call in the java code.



import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

public class MyClass {

 private Logger logger = LogManager.getLogger(MyClass.class);

}

That's all for this post, hope you enjoyed it and thanks for my friend Hassen Kalaldeh for his help.

Articles les plus consultés