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

How to resolve the sun.security.validator.ValidatorException: PKIX path building failed



When you first setup Maven in your office/home computer you might come up with an exception as below when you try to run/build the Maven project.


Could not transfer artifact com.adobe.aem:aem-api:pom:6.0.0.1 from/to adobe-public-releases (https://repo.adobe.com/nexus/content/groups/public): sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target -> [Help 1]

SOLUTION to sun.security.validator.ValidatorException: PKIX path building failed

So for the exception above we can see that the URL is clearly mentioned in the exception report. In this case it is https://repo.adobe.com/nexus/content/groups/public


Resolution Steps:


STEP 1:  Navigate to the URL in the exception report using a browser. In this case I am using Google Chrome browser. See below snapshot.



STEP 2: Now press F12 or right click on the page and click on “Inspect”. This will open the developer tools.


STEP 3: Go to the “Security” tab.

STEP 4: Click on the “View Certificate” button.


STEP 5: Check the name of the Certificate (or the issuing authority)



STEP 6: Now close this window and go to browser “Settings”.


STEP 7: Now search for “Manage Certificates”. Alternatively, you can open the “Internet Options” in IE or similar browser and go to “Content” tab and click on “Certificates” button.




STEP 8: Now find the name of the certificate matching the one in STEP 5.




STEP 9: Click on “Export” and export it in a new file (using the default selected format).



STEP 10: Now run the JAVA  Keytool command to add this certificate to your computer’s JDK keystore.


STEP 11: You should run this command.

keytool -import -alias ctsrootca3 -file D:\certs\ctsrootca3.cer -keystore "C:\Program Files\Java\jdk1.8.0_152\jre\lib\security\cacerts"

Please make changes as below.
D:\certs\ctsrootca3.cer  - This should be the path to your certificate file that you exported.
C:\Program Files\Java\jdk1.8.0_152 – This should be path to your JDK folder.
 
If prompted for a password use : “changeit” (without the quotes, this is the default password for cacerts file)



STEP 12: After successful addition of the key you will see a message like this.



STEP 13: If you have followed this steps correctly then now when you run Maven it should not give any errors.



How to resolve ObjectFactory Collisions in JAVA

In my previous article I have explained how to generate the web service classes.If you have not already read the topic then I would advise you to do so. Moving on, we can sometimes get an error like below

[ERROR] Two declarations cause a collision in the ObjectFactory cl
  line 1191 of file:/D:/RAMEEZ/Web%20Services/TeamBpl/TeamBpl3.xsd

[ERROR] (Related to above error) This is the other declaration.
  line 981 of file:/D:/RAMEEZ/Web%20Services/TeamBpl/TeamBpl3.xsd

This is a very common issue we face, and the way to resolve this is to simply write a XML file having a JAXB binding configuration.

Simple Steps for Clear Understanding:

Here are a few simple steps with images to help you fix the issue quickly :)


STEP 1:

Analyze the issue.
From the above error log we see line number 1191 and 981 have issues in the
XSD Schema file. Lets look into the XSD file. See below.



STEP 2:

So this is happening because the "name" attribute is somehow causing collision when the WSDL file is getting parsed.


STEP 3:

To solve this simple open a new file in Notepad(or any text editor you use) and name it something like "conflict.xml".

STEP 4:

Copy it from here.

<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">

 <jxb:bindings node="/xs:schema" schemalocation="TeamBpl3.xsd">
  <jxb:bindings schemalocation="TeamBpl3.xsd">
   <jxb:bindings node="./xs:element[@name='MediaUrl']">
    <jxb:factorymethod name="RootMediaElement">
   </jxb:factorymethod></jxb:bindings>
  </jxb:bindings>
 </jxb:bindings> 


</jxb:bindings> 



STEP 5:

Now run the "wsimport" command with the -b switch. This is called the binding (-b).

wsimport [WSDL_FILE.wsdl] -b conflict.xml -keep -verbose

STEP 6:

This will generate the stub classes properly without any issues.




REMEMBER:

When you have multiple collisions then in that case you have to write multiple jxb:bindings for each. Means you have to repeat line number 5 to 11 from STEP 3.

Hope this helps!



Steps to Create Web Service Stub

This document gives instructions on creating web service stubs better knowas proxy classes. We will take an example and proceed with the explanation.

STEP 1:

Copy the URL link in the browser address bar and hit enter.Check if the WSDL is accessible through your network or not.

STEP 2:

Download the WSDL file in a folder and should be saved with the ".wsdl" extension.

STEP 3:

Now start to download the artifacts in a folder in your local drive.This should include the WSDL file and all the associated XSDs. The XSD files can be downloaded from the links found inside the downloaded WSDL file.

STEP 4:

Go into the WSDL file.You will see a section having the schemas.

STEP 5:

Rename the XSD Http links.Point it to the local path of the XML Schemas.

STEP 6:

Open a command prompt and check the "wsimport" tool.

STEP 7:

We will use the wsimport and the associated commands to create the stubs.Please check the snap shot below f the command prompt.The command is like:wsimport -keep -extensionThere are many associated commands. We need to use them as and when required.

STEP 8:

After the previous command we can see folders created in the same destination of the artifact files.

STEP 9:

Copy this folders in the “src” folder of your JAVA project in your IDE.It should look like this ad you are good to go.

 

Java DecimalFormat - For Large Decimal Point Numbers

The Java DecimalFormat class helps us to format numbers in many ways. I was trying to convert
a big number to a 2 decimal point number.Thought of sharing the same with some explaination.

Trying to achieve this:    1,308,207 ---> 1.31


    String number = "1,308,207";
    java.text.DecimalFormat df = new java.text.DecimalFormat("#.##");
    number = number.replace(",", ""); 
    Float f = Float.parseFloat(number) / 1000000;
    String result = df.format(f); 
    System.out.println(result);   // result = 1.31

So how does it work??

Well it works like this. DecimalFromat uses java.math.RoundingMode.HALF_EVEN method which
rounds off the number to nearest even i.e when it's 0.05 it becomes 0.1.

1. The number becomes 1308207 at line 3.
2. At line no. 5 it becomes 1.308207.
3. Now the actual formatting starts:-
4. The right hand side(RHS) value is 07,so nearest round off is 10, only 1 taken & RHS discarded.
5. Now the number becomes 1.308201
6. Rightmost 01,the nearest round off id 00, RHS discarded & number becomes 0.
7. Again number becomes smaller 1.30820, in same way becomes 1.3082.
8. Next step : 1.308
9. Finally 1.31(08 becomes 10 with HALF_EVEN method and 0 discarded).


Do you have suggestions or want to improve the solution? Please do feel free to write back to us

Remove SOAP Request XML parameter programmatically.

SOAP is a protocol that allows systems to communicate using HTTP and uses predominantly XML
for communication. The necessity of web applications to inter communicate made it necessary for
a protocol to be designed.

Sometimes when setting the web service parameters there are compulsory parameters whose values needs
to be set. But passing these parameter might cause the Web Service to fail. So a situation may arise
where we need to both set the web service parameter value as well as remove the parameter from the
request XML!!!

So lets say for example you have a webservice parameter like this:

<ProductName>CoderMagnet<ProductName>
<CodeValue>...</CodeValue>
<ProductId>ABCXYZ<ProductId>


Suppose passing this value in the request xml is giving an error.
And also lets assume this is being set from the JAVA program like this.


product.setProductName("CoderMagnet");
product.setCodeValue("ABC123");
product.setProductId("004");



Now to remove this parameter from the web service request XML we just need to set
the parameter as NULL. This will remove the web service parameter from the request XML.


product.setProductName("CoderMagnet");
product.setCodeValue(null);
product.setProductId("004");



Afer you set a web service parameter to null. It will automatically
be dropped like shown below.


<ProductName>CoderMagnet<ProductName>
<ProductId>004<ProductId>



We can see from the above XML that the CodeValue got dropped.




How to iterate over a HashMap in Java

Iterating over a HashMap in Java is a very common task but can be tricky sometimes
since it uses the Entry object (java.util.Map.Entry) which we may not be familiar with readily.

Whenever we need to "Iterate over a HashMap" we need to call the entrySet() method over the map
object and then only we can iterate over it.


This is best achieved in the following two ways.
Supposing we have a Hashmap like like this.


Map<String,String> timeZones=new HashMap<String, String>();
 
timeZones.put(" (GMT-12:00) ", " International Date Line West ");
timeZones.put(" (GMT-11:00) ", " Midway Island ");
timeZones.put(" (GMT-10:00) ", " Hawaii Time ");
timeZones.put(" (GMT-09:00) ", " Alaska Time ");
timeZones.put(" (GMT-08:00) ", " Pacific Time (US and Canada) ");


Method 1: Using For Each Loop to iterate over a HashMap

for(Map.Entry timeZone : timeZones.entrySet()){

    System.out.println(timeZone.getKey() + " is the " + timeZone.getValue());

  }


Method 2: Using Iterator and While Loop to iterate over a HashMap

 while (it.hasNext()) {
  
  Entry timeZone = (Entry)it.next();
  System.out.println(timeZone.getKey() + " is the " + timeZone.getValue());
  it.remove(); 
    }


Output:

 (GMT-08:00)  is the  Pacific Time (US and Canada) 
 (GMT-12:00)  is the  International Date Line West 
 (GMT-09:00)  is the  Alaska Time 
 (GMT-10:00)  is the  Hawaii Time 
 (GMT-11:00)  is the  Midway Island


Well in both cases the result is he same. Its depends on the taste and the situation
to decide which one of the method you want to use.
Going a little deeper we can look into other requirements of HashMap iteration.





Iterate over a HashMap Values/ How to iterate over the values in a HashMap.

Well you may very well come across a situation where you only need to iterate over HashMap values.
This can be easily achieved in the following two ways.

 for(String timeZone : timeZones.values()){

  System.out.println(timeZone);
 }


OR,


Iterator it = timeZones.values().iterator();

 while (it.hasNext()) {
  String timeZone = (String) it.next();
  System.out.println(timeZone);
  it.remove();
 }


Output:

 Pacific Time (US and Canada) 
 International Date Line West 
 Alaska Time 
 Hawaii Time 
 Midway Island 






Iterate over a HashMap Keys/ How to iterate over the Keys in a HashMap.

You may also need to iterate over HashMap keys. This HashMap iteration is shown below.

 for (String timeZone : timeZones.keySet()) {

  System.out.println(timeZone);
 }


OR,


Iterator it = timeZones.keySet().iterator();

 while (it.hasNext()) {
  String timeZone = (String) it.next();
  System.out.println(timeZone);
  it.remove();
 }


Output:

 (GMT-08:00) 
 (GMT-12:00) 
 (GMT-09:00) 
 (GMT-10:00) 
 (GMT-11:00) 


How to convert String to Int in Java

Converting a String to Int in Java is a common scenario which we face everyday.
Now this can be achieved in multiple ways.

Integer.parseInt()
Integer.parseInt() returns a primitive int datatype.

String num = "12345";
int number = 0;

try {  
number = Integer.parseInt(num);   
} 
catch (NumberFormatException e) {
}


Integer.valueOf()
The Integer.valueOf() method returns an cached instance of java.lang.Integer.

String num = "12345";
Integer number = 0;
try {
      number = Integer.valueOf(num);
    } 
catch (NumberFormatException e) {
}


Integer.decode()
This basically decodes a String into an Integer.It returns a wrapper object of type java.lang.Integer.
It accepts Strings in the formats like DecimalNumeral, HexDigits, and OctalDigits.
DecimalNumeral, HexDigits, and OctalDigits are as defined in section 3.10.1 of The Java™ Language
Specification, except that underscores are not accepted between digits.

String num = "12345";
Integer number = 0;
try {
      number = Integer.decode(num);
    } 
catch (NumberFormatException e) {
}


Integer.decode() for Octal numbers

String num = "022";
Integer number = 0;
try {
      number = Integer.decode(num); //18
    } 
catch (NumberFormatException e) {
}


Integer.decode() for Hexadecimal numbers

String num = "0X12A";
Integer number = 0;
try {
      number = Integer.decode(num); //298
    } 
catch (NumberFormatException e) {
}


Retrieve List from java.util.Stream in Java 8

In the previous article I explained the new class introduced in Java 8 called Optional.
Today I was working with streams and needed to convert it to a List. So thought of sharing this..

Go here if you need to Convert a List to Stream.
Stream API in Java 8 does not define a direct operation or standard to convert a stream data,
into a List. Java 8 design pattern unfortunately does not allow direct conversions from the Stream
to Collections like List or Set.

However not everything is lost, as the developers have given us the
concept of Collectors.You can read more about collectors in my Simple Collector Tutorial.
Using Collectors we can easily achieve inter conversions from Stream to Collections.


There are various method explaining how to convert Stream to List in Java 8.
Here are the most common ones.

The Collectors.toList() method


The Collectors.toList() method is the most straightforward method to convert Stream to List in java 8.
It involves some simple code.

Stream<String> streamData=Stream.of("Convert","Stream","to","List");
List<String> newList=streamData.collect(Collectors.toList());

System.out.println(newList);  //[Convert, Stream, to, List]

Most of the daily requirements will be addressed by the above method
but if in case you are the odd one out who just can't do thing as the normal
people do, then you might look at the below options as well.



The Collectors.toCollection() method to convert a Stream to List in Java8


This is quite same as the previous one except for the fact that it is more generalized
conversion. The toCollection() can be used to convert Stream to other collection class also
like for example a TreeSet.

Stream<String> streamData=Stream.of("Convert","Stream","to","List");
List<String> newList=streamData.collect(Collectors.toCollection(ArrayList::new ));
//TreeSet<String> set=streamData.collect(Collectors.toCollection(TreeSet::new ));

System.out.println(newList);  //[Convert, Stream, to, List]



Using forEach() to convert a Stream to List in Java 8


Ok so this is a crude way of converting a Stream to a List. But if the other options
are not good enough for you then you might try out this one. Here what we will traverse
through the elements of the Stream using the forEach() loop and add each element to the List.

Stream<String> streamData=Stream.of("Convert","Stream","to","List");
List<String> newList=new ArrayList<String>();
 
streamData.forEach(newList::add);
 
System.out.println(newList);  // [Convert, Stream, to, List]



Using forEachOrdered() to convert a Stream to ordered List in Java 8


The forEach() will work with Streams pretty good. But there is a catch.
In case of parallel streams where multiple Stream data is processed horizontally
it will break the ordering. So you will end up with a jumbled list of objects from the initial
Stream. The forEachOrdered() helps to traverse a parallel stream in an orderly way. So the
list you will get will maintain the initial order of elements as present in the parent Stream.

Stream<String> streamData=Stream.of("Convert","Stream","to","List");
List<String> newList=new ArrayList<String>();
 
streamData.forEachOrdered(newList::add);
 
System.out.println(newList);  // [Convert, Stream, to, List]




Using toArray() and Arrays.asList() to convert a Stream to List in Java 8


If you are really looking to lower efficiency, readability and clarity of our code
and you do not like the normal stuff that others do then you can try this out.
Jokes apart, this method can be used to learn the features of Stream and also to
understand the basics of Streams and Collections in Java 8.

Stream<String> streamData=Stream.of("Convert","Stream","to","List");
List<String> newList=(List<String>)(Object)Arrays.asList(streamData.toArray());

System.out.println(newList);  // [Convert, Stream, to, List]



Conclusion:

To conclude we can adopt various steps to convert Stream to List in Java 8.
Since there is no direct way to do this I leave it upto you to choose the best method
for your development activity.However I prefer the first two methods using Collectors.

SEE ALSO: Convert a List to Stream in Java 8.