Tuesday, August 24, 2021

Java Maven project error: Source option 5 is no longer supported. Use 6 or later.

Problem:


Suppose we are building an application from scratch based on Maven and JDK 11 and our pom.xml file contains nothing but groupId/artifactId/version information. An attempt to compile will end with an error as in the title.

The same thing will happen if we have an application in Java 1.5 (yes, it happens...) and we try to upgrade JDK version to e.g. 1.8 or 11. Changing Java version in the project and trying to compile will also end with this error.

Requirements:

  • installed IntelliJ, JDK and Maven as described here. We need Java 11 to be installed.

Solution:


Let's try to repeat this mistake by creating simple "Hello World" application wchich is based on Maven and uses JDK 11 from Amazon:



Now let's try compiling it with Maven using the "mvn clean package" command in terminal (You can also do it by clicking in Idea's Maven window):



Tip: if you're wondering why I have such nice colors in the terminal, let me remind you that I set up the Idea terminal to use Git Bash underneath. How to do it is described here (search for "optional" keyword). However when You use standard Windows Terminal (cmd.exe) or Windows PowerShell as a Terminal underneath colours also work.

We can observer compilation error with message marked in red rectangle. Why does this happen? 
  • Maven uses "maven-compiler-plugin" to do the job, even if we don't have this plugin explicitly written into pom.xml
  • this plugin (3.1.0) by default tries to set source and target bytecode version to 1.5 even if we set our project to use JDK 11:



Solution: 
  • change the plugin version to a newer one - just add the plugin into the pom.xml explicitly
  • set the source and target to 11 in the pom.xml. 
Why explicitly set version to 11? Because without explicitly setting them, newer plugin (from 3.6.0) will use 1.6 as default. Compilation is OK now but language level is set to 1.6 even we can use 11 as our JDK:





So, to set up everything together (plugin and language) just put those in pom.xml: 
    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

You can also put information about source and target language directly into the plugin instead of  defining properties:

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                    <configuration>
                        <source>11</source>
                        <target>11</target>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
From JDK 1.9 and above plugin can also be configured using <release> option:

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                    <configuration>
                        <release>11</release>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
Fortunately, when you create a new maven-based project from scratch in Idea, it (based on the selected JDK) automatically places the appropriate source and target for the language level in pom.xml (using <properties>).

Tuesday, August 10, 2021

Chargers, cables, standards - everything matters

 The story:

Some time ago I tried to charge my powerbank (20000 mAh). I just grab "no-name" charger and some "no-name" cable and start to charge. I took all night to charge it from 0 to 100%. I though this is normal, big powerbank, long time. Later, I tried to charge the same powerbank from 0 to 100% using the same "no-name" charger but with better (let's say "branded") cable. And the charging time was significantly better. I decided to use  "branded" charger and "branded" cable and charging from 0 to 100% again. And it was faster than in previous two trials. So I started to read about charging standards, how cable can affect the process and so on. 

The theory:

We have "USB standards" and "prioprietary specifications" in terms of charging. 

USB standards are:

1. Standard USB port i.e. in PC

When connected and transferring data we can charge devices with different power depend on USB type:

  • USB 1.0 gives 0.1A with 5V which gives 0.5W
  • USB 2.0 gives 0.5A with 5.0V which gives 2.5W (from 2000)
  • USB 3.0 gives 0.9A with 5.0V which gives 4.5W (from 2008)
  • USB Type-C gives 1.5A/3.0A with 5.0V which gives 7.5/15.0W (from 2014)

2. Battery Charging (BC) 1.1/1.2

In year 2000 and up USB 2.0 with its 2.5W was not enough. In 2007 a Battery Charging 1.1 (BC 1.1) specification was released. It defined three new types of ports:

  • Standard Downstream Port (SDP) - USB 2.0 compatible in terms of power (2.5W)
  • Dedicated Charging Port (DCP) - does not support data transfer, used only for charging. Support max 1.5A with 5.0V which gives max 7.5W
  • Downstream Port (CDP) - allows both data transfer like USB 2.0 and charging like DCP

In 2010 a Battery Charging 1.2 (BC 1.2) specification was released, where 1.5A was increased to 5A, which gives max 25W using 5.0V. 

3. Power Delivery (PD) 1.0/2.0/3.0

In 2012 Power Delivery 1.0 specification was released. It introduces so called source profiles:

  • 5.0V with 2.0A which gives 10W (profile 1)
  • 12.0V with 1.5A which gives 18 W (profile 2)
  • 12.0V with 3.0A which gives 36 W (profile 3)
  • 20.0V with 3.0A which gives 60W (profile 4)
  • 20.0V with 5.0A which gives 100W (profile 5) 

In 2014 Power Delivery 2.0 specification was released (as a part of USB 3.1 and USB Type-C). Comparing to PD 1.0, 12V is gone and 9V and 15V are introduced. Source profiles no longer exist - they were replaced by power rules. Power rules keep fixed voltage but allow to negotiate current level, which gives different power level: 

  • 5.0V with 0.1A - 3.0A which gives 0.5W - 15W (rule 1)
  • 9.0V with 1.67A - 3.0A which gives 15W - 27W (rule 2)
  • 15.0V with 1.8A - 3.0A which gives 27W - 45W (rule 3)
  • 20.0V with 2.25A - 3.0A / 3.0A - 5.0A (using rated cable) - 45W - 100W (rule 4)

In 2018 Power Delivery 3.0 specification was released. It does not change power rules introduced in PD 2.0 but adds some features like Programmable Power Supply (PPS) which allows configure voltage in 20mV granular increments.

4. Prioprietary specifications

  • Qualcomm Quick Charge (QC 1.0/2.0/3.0/4.0/4+)
  • MediaTek Pump Express
  • Samsung Adaptive Fast Charging
  • Oppo VOOC (named Dash Charge/Warp Charge on OnePlus devices and Dart Charge on Realme devices)
  • Huawei SuperCharge

The test:

Lets have a look how it looks like in real life. I will charge those devices:

  • Tablet Lenovo Tab2 A10-70L
  • Xiaomi YDDYP01 20000mAh power bank
  • Xiaomi Redmi 5 Plus smartphone
  • Xiaomi POCO X3 NFC smartphone
  • Aukey PB-XD26 26800mAh power bank
  • Sony Xperia 10 III smartphone

I will use chargers:

  • Aukey PT-Y11 wall charger which have to ports: USB-A supports Quick Charge 3.0 (18W) and USB-C supports Power Delivery 3.0 (30W). 
  • Xiaomi POCO X3 stock charger delivered with the phone.
  • Sony Xperia 10 III stock charger delivered with the phone.

I will use cables: 

  • 1m Aukey USB-A/micro-USB
  • 1m Aukey USB-A/USB-C
  • 1m Aukey USB-C/USB-C (rated for 100W for PD 3.0)

I will use testers:

  • Fnirsi FNB28 for USB-A
  • Fnirsi FNC88 for USB-C

Results:

1. Lenovo Tab2 A10-70L 

Connection: Aukey PT-Y11 USB-A -> Fnirsi FNB28 -> USB-A/micro-USB -> Lenovo Tab2 A10-70L

Power measured: 10W


I cannot find if it is compatible with any proprietary specification, but 10W suggests it is Qualcomm QC 1.0. Tester does not recognize it as Qualcomm QC 1.0, intstead it showh Batery Charge 1.1 DCP standard.

2. Xiaomi YDDYP01 20000mAh

Connection: Aukey PT-Y11 USB-A -> Fnirsi FNB28 -> USB-A/micro-USB -> Xiaomi YDDYP01 20000mAh. 

Power measured: 18W


Accroding to this device specification it is compatible with Qualcomm QC 2.0 and tester recognizes it indeed as Qualcomm QC 2.0 12V

3. Xiaomi Redmi 5 Plus (smartphone was initially charged about 30% during the test) 

Connection: Aukey PT-Y11 USB-A -> Fnirsi FNB28 -> USB-A/micro-USB -> Xiaomi Redmi 5 Plus

Power measured: 14W


 The device is based on Qualcomm Snapdragon 625 which is in theory Qualcomm QC 3.0 compatible (according to specification of this chipset). However tester recognizes it as Qualcomm Quick Charge 2.0 9V, so I suspect that smartphone manufacturer "downgraded" charging to QC 2.0 in order not to pay higher license fo QC 3.0,

4. Xiaomi POCO X3 NFC (smartphone was initially charged about 85% during each the test) 

Test 1:

Connection: Aukey PT-Y11 USB-A -> Fnirsi FNB28 -> USB-A/USB-C -> Xiaomi POCO X3 NFC

Power measured: 16W


The device is based on Qualcomm Snapdragon 732G which is in theory Qualcomm QC 4+ compatible (according to specification of this chipset). Tester recognizes it as Qualcomm QC 3.0 which is OK because charger is QC 3.0 compatible and QC 4+ device is backward compatible with QC 3.0

Test 2:

Connection: Aukey PT-Y11 USB-C -> Fnirsi FNC88 -> USB-C/USB-C -> Xiaomi POCO X3 NFC

Power measured: 14W

QC 4+ is compatible with Power Delivery (and can give max 27W), so charging with PD port of this charger simply works. However tester recognizes it as Huawei SCP standard.

Test 3:

Connection: Xiaomi stock charger USB-C -> Fnirsi FNB28 -> USB-A/USB-C -> Xiaomi POCO X3 NFC

Power measured: 20W


Xiaomi stock charger has max 27W, so it is QC 4.0 compatible, however tester recognizes it as QC 3.0.

5. Aukey PB-XD26 26800mAh 

Connection: Aukey PT-Y11 USB-C -> Fnirsi FNC88 -> USB-C/USB-C -> Aukey PB-XD26 26800mAh

Power measured: 30W


According to specification of this power bank it is PD 3.0 compatible and its max charging power is 45W. Used charger has max 30W output via its PD port, so charging works with its maximum speed due to charger limit (limited to 30W by charger). However tester does not recognize it as Power Delivery standard.

6. Sony Xperia 10 III

Test 1:

Connection: Aukey PT-Y11 USB-A -> Fnirsi FNB28 -> USB-A/USB-C -> Sony Xperia 10 III

Power measured: 7W


The device is based on Qualcomm Snapdragon 690 5G which is in theory Qualcomm QC 4+ compatible (according to specification of this chipset). But this phone does not support any QC standard (probably due to licensing costs). Moreover stock charger delivered with the phone gives also max 7,5W power.

Test 2:

Connection: Aukey PT-Y11 USB-C -> Fnirsi FNC88 -> USB-C/USB-C -> Sony Xperia 10 III

Power measured: 15W


In theory this Sony phone can take 30W via PD. I have never achieved such value, I was able to get 18W max.

Final notes:

  1. The simple truth is: the more power (W) delivered, the faster charging.
  2. Charged device and charger should be compatible with the same charge standard.
  3. USB cable used for charging must have good quality too. 
  4. Those USB testers used are not always reliable in my opinion:
    • they do not properly recognize charging standards (especially PD, QC 4.0)
    • sometimes I had to connect them second or third time to start charging i.e 18W not 10W. It looks like sometimes "handshake" between charged device and charger with tester plugged in between does not work (or works depending on the connection order...)


Sunday, January 13, 2019

Gather all hammers inside toolbox - revisited

It's been a long time since I wrote something here. When I started this blog, one of the first thing I wrote about was how to set up development environment. It was ten years ago - see here. A lot of things changed in Java world in this time. Let's try to set up everything again using modern and most popular tools now.

What are we going to install? For today it will be:
  • Java JDK - we still have Java like in the past, however significant changes were done by Oracle last time.
  • IntelliJ Idea  - an IDE, as replacement for Eclipse
  • Apache Maven - dependency management
  • Git - version control system
As before, all things will be installed in C:\Development

===============================================
Installing Java JDK
===============================================

We all get used to that Java is free to use either for personal or commercial purpose. It was true for Java 8 and older versions until 1st January 2019. Starting from 1st Jan 2019 Oracle announced end of public updates of Java SE 8. It simply means If You use Java in commercial purpose and You want get updates for Your Java SE 8, from 1st January 2019 You have to pay for this.

Why Java 8, what about other versions like 9,10,11...? From Java 8, every three years Oracle will relese Java version known as Long Time Support (LTS). First LTS is Java 8, second is Java 11 - it means that Java 9 and 10 is no longer supported now. Changing licensing model for commercial use means that You have to pay for the updates/support for each LTS version starting from 8 (from 1st Jan 2019). See more here.

So what are options? We can:
1. Stay with latest available Java 8 from Oracle (JDK 8u192) without possibility to update anything - we don't have security updates, but we are free of charge.
2. Become Java Commerical User and pay for latest JDK (11 at the time of writing)
3. Use OpenJDK from Oracle - this is free Java for commercial use, but each new version is publicly available in 6-month interval, with 6-month support/updates available. So every half a year You have to update used OpenJDK on Your own.
4. Use a Java based on OpenJDK but with long-term support - for example Amazon Corretto 11 available here.

Let's use JDK 8 from Oracle from point 1. If You want to use latest free Java with LTS You can use Amazon Corretto from point 4 - just download .zip file and extract it for exmple into C:\Development\Java\AmazonJDK\Java11_64bit

Step 1: Download 64 bit version of JDK 8u192 or Windows from here.
Step 2: Create directory C:\Development\Java\OracleJDK\Java8_64bit and start the installer:


Remove installing public JRE and choose previously created directory:


Step 3: After succesfull install create system variable named JAVA_HOME with value C:\Development\Java\OracleJDK\Java8_64bit then modify Path system variable by adding %JAVA_HOME%\bin at the end.

Step 4: Verify Java installation by opening command line and type java -version and javac -version. You should see informationa about Java installed:


Java is installed.


===============================================
Installing IDE - IntelliJ Idea
===============================================


Step 1:
Create directory C:\Development\Jetbrains\Idea
Step 2: Download and install an application JetBrains Toolbox from here. This is an application to maintain all products from Jetbrains (IntelliJ Idea manufacturer). It allows to automatically update installed tools.


Step 3: Configure toolbox.

Choose created directory in step 1. Do not forget to  click apply after choosing it. If You have any license from Jetbrains, log in into your account now - You will not have to provide license when installing tools:


Now You can choose a tool to install:


After click on a tool, it will be installed into the previously selected directory:


Just click on tool to launch it. You can also change settings of the tool being installed, like update plan, memory consumption and so on:


IntelliJ Idea is installed. Start it, then go thru some creator in order to perform basic settings (You may leave all the options default).

===============================================
Hello World in Java - using IntelliJ Idea and installed JDK
===============================================

Step 1: Create directory C:\Development\Projects

Step 2: Run Idea. You will see initial screen for creating/opening/downloading a project. Choose create new project:


Step 2: Choose Java project type:


Idea is shipped with its own JDK. We would like to use our own JDK. Press button New ans select the JDK directory C:\Development\Java\OracleJDK\Java8_64bit (or another directory like C:\Development\Java\AmazonJDK\Java11_64bit if You use Amazon Corretto)Then press Next.

Step 3: Choose project type from template: 

 
 Step 4: Choose project name and location (use projects directory created in step 1): 


Step 5: Sample application is ready. You can start is using green "play" button:



Step 6 (optional): Leave only our installed JDK for future projects. 

As mentioned above, Idea comes with built in JDK. We can disable showing this JDK as a option to select for future projects and leave only those we installed in C:\Development\Java\OracleJDK\Java8_64bit. In order to do it open project properties and find Platform SDK. Then choose JDK provided by Idea and delete it:


Then select our installed Java and change its name:


From now this is only one and thus default Java to use in Java projects. Of course You can add other JDK version like OpenJDK.

That's all. Idea is configured and ready for Java development.

===============================================
Installing Maven
===============================================

Maven will be used for dependency managment, building and running future apps. Idea comes with bundled Maven, so we do not have install our version. But similar to installing Java, we will install our own version of Maven.

Step 1: Create directory C:\Development\Maven. Then download Maven (binary zip archive) from here and unpack it to the created directory.

Step 2: Create directory C:\Development\Maven\repository for artifacts downloaded by Maven:



Step 3: Tell Maven to use created above directory as a repository. 

Locate Maven settings file named settings.xml and add a line inside:


Step 4: Add Maven's bin folder to the system PATH variable in order to use maven commands from console.

Step 5: Verify if Maven is installed correctly. 

Open command line and execute command: mvn -version. You should see similar information:


Note 1: Maven displays information about Java used. That's why You have to install Java before and set JAVA_HOME variable.

Note 2: There is no need to set up MAVEN_HOME or M2_HOME system variable like it was done for previous versins of Maven.

Step 6: Tell Idea to use installed Maven. Open settings, type Maven in search field. Idea will show settings for Maven. Choose Maven installation directory. You may notice that Idea will display recognized version of selected Maven installation and local respoitory path will change to the value set in step 3:


That's all. Maven is installed and configured in IntelliJ Idea.

===============================================
Installing Git
===============================================

Git will be used to track changes we make in our projects files. 

Step 1: Download Git for Windows from here
Step 2: Create directory C:\Development\Git. Run the downloaded git installer and choose created directory as the installation target: 


Install Git using all defaults, but choose Your favourite text editor and PATH modification:



This option will modify PATH system variable, allowing to execute git command from command line. 

Step 3: Verify installation and basic configuration. 

Open command prompt and execute command git -version to see if git responds. After that configure user and email: 


Step 4: Make IntelliJ aware of installed Git.

Open settings and type Git in search box. Go to Git settings and set path to git.exe:


That's all. Git is installed and configured in IntelliJ Idea.

===============================================
Make Java Hello World in control of Git
===============================================

Using git is beyond of the scope of this blog :) There are many great tutorials explaining the nature of git - for example this one. I will show how to add a git support to the existing project (Hello World created earlier).

Step 1: Convert existing projest into git respository. 

Open project location (C:\Development\Projects\Test) and using context menu (right mouse click) select option Git Bash Here. Git will open its terminal with path set to the project. Now enter command git init:


This will create empty repository:


The project is now maintained by Git.

Step 2: Verify git integration under IntelliJ Idea. 

Open Test project in Idea to see that it is recognized as a git project now:


Step 3 (optional): Use git command directly from IntelliJ Idea.

Idea has great integration with Git, however it is possible to use git commands entered by hand directly in Idea - just like we use them in Git Bash. We can use Idea's terminal and set it to open Git Bash under the hood. Go to the settings and find options for Termimal. Set shell path to point to the Git Bash executable script with some additional options:


Now we can execute git command in Idea's terminal:




That's all. Development environment is set up and ready for work :)














Thursday, December 08, 2011

JSF 1.2 (myFaces) + RichFaces 3.3.x + IE 9 = troubles

Note: below description uses Eclipse Indigo, Tomcat 7.0.28, MyFaces 1.2.12, RichFaces 3.3.3 (Final).

Requirements:
  • working JSF 1.2 sample application from here
  • RichFaces 3.3.x added to the project
You will learn:
  • how to fix problems with RichFaces 3.3.x for IE 9
Let's assume that You develop JSF 1.2 web application. It does not matter if Your application uses .jsp pages or Facelets with .xhtml pages. I assume that .jsp pages are in use. Then You decided to add some Ajax capabilities, new components and so on. So You simply take RichFaces and add them to the project. This is simple thing:
a) download latest RichFaces 3.3.3 (final), take those jars: richfaces-api-3.3.3.Final.jar, richfaces-impl-3.3.3.Final.jar, richfaces-ui-3.3.3.Final.jar and place them in WEB-INF\lib folder of Your web application. 
b) modify your web.xml file by adding there:
 <filter>
  <display-name>RichFaces Filter</display-name>
  <filter-name>richfaces</filter-name>
  <filter-class>org.ajax4jsf.Filter</filter-class>
 </filter>

 <filter-mapping>
  <filter-name>richfaces</filter-name>
  <servlet-name>Faces Servlet</servlet-name>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>INCLUDE</dispatcher>
 </filter-mapping>
c) add proper taglib directives to each Your jsp page (note that for .xhtml pages syntax is different):
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
Now You can use RichFaces components. Let's try to modify our sample JSF 1.2 application by creating new web project named "JSFRichFaces". Then let's add ajax button (<a4j:commanButton>) and expandable toggle panel (<rich:simpleTogglePanel>). All modifications are shown below:




Everything works OK under Firefox, Chrome, IE 7, IE 8 - unless You use Internet Explorer 9. You can observe two problems: with RichFaces ajax components and RichFaces components layout.

RichFaces 3.3.x does not fully support IE 9. RichFaces developers encourage everyone to migrate into RichFaces 4.x which are IE 9 compatible. The main problem is that RichFaces 4.x works only with JSF 2.x application, and this is not so easy to migrate If You have many clients where You already delivered Your application...

Problem 1: ajax components do not work (some JavaScript errors).


When You try to press ajax button named "Go (RichFaces) " under IE 9, You can observe following error (open IE Developer's Toolbar Java Script console before):





Solution: You have to force IE 9 to act as IE 8, where RichFaces 3.3.x works OK. In order to do it You have to define X-UA-Compatible header for each page. You can do it in two ways:
a) add a special <meta> element for each page or
b) write a special filter which adds this header to the HTTP response

In our simple case it is sufficient to add a <meta> into the page <head> section:

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
Remember that this <meta> must be placed as first element in <head> section!

Problem 2: RichFaces components have broken layout (problems with CSS).


When You open our sample application under IE 9, toggle panel has no CSS styles set at all. Under Chrome or Firefox everything looks OK. Checking HTTP request/response headers shows that for IE 9 proper CSS for RichFaces component (CSS located in the .jar file) is not loaded and server returns error:





Console under Eclipse shows that exception is thrown:



Under Firefox everything looks OK:






Why it happens? Accroding to that article, there was a change in IE 9 for MIME type handling. IE 9 ignores CSS styles if they are not delivered with a text/css MIME type.

Why it works for previous IE 7 and IE 8? Because also HTTP Request Accept header sent by IE 9 is different than sent from IE 7 or 8. IE 7/8 sent text/css, */* as Accept, where IE 9 sends only text/css as Accept.
Knowing that it is time to look inside myFaces source, to find the code which produces mentioned exception. Everything is located in HtmlRendererUtils.java (located in myfaces-impl-1.2.11.jar) in the selectContentType() method. It works for IE 7/8 because */* sent in Accept by IE 7/8 is on supported content type list, where text/css is not recognized at all.

Solution: add text/css support, then recompile HtmlRendererUtils.java and replace it in myfaces-impl-1.2.11.jar (or build complete myfaces-impl-1.2.11.jar). In order to avoid this mumbo-jumbo with Maven to build whole .jar, just create simple Java Project, create a HtmlRendererUtils.java in certain package, change it and compile, then replace compiled class in myfaces-impl-1.2.11.jar ;-)





Or download recompiled myfaces-impl-1.2.11.jar from here.


That's all. IE 9 works again without need to add Your web page to its compatibility view list or something. And You have time to migrate to JSF 2.x and RichFaces 4.x before IE 10 comes to market...