updating your java client - rainfocus...–relates to project jigsaw (java platform module system)...
TRANSCRIPT
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
UpdatingYourJavaClientDesktopandJavaFXApplicationsforJDK9CON5795
PhilRace,KevinRushforthJavaPlatformGroupOctober,2017
3
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
SafeHarborStatementThefollowingisintendedtooutlineourgeneralproductdirection.Itisintendedforinformationpurposesonly,andmaynotbeincorporatedintoanycontract.Itisnotacommitmenttodeliveranymaterial,code,orfunctionality,andshouldnotberelieduponinmakingpurchasingdecisions.Thedevelopment,release,andtimingofanyfeaturesorfunctionalitydescribedforOracle’sproductsremainsatthesolediscretionofOracle.
4
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
MigratingSwingandAWTApplicationstoJDK9PhilRace
5
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
ThistalkisnotaboutallthesenewJDK9clientfeatures..• TIFFsupportforImageI/O• GTK3supportforLinuxdesktops• Platformspecificdesktopfeatures• Harfbuzz OpenTypeLayoutEngine– BOF4226,MondayOct2nd (toolate,youmissedit)
• MarlinGraphicsRasterizer– Session4052,Wednesday Oct3rd,1.45pm,thisroom(2008,Moscone West)
• ForthosenotcoveredintheirownsessionscometotheclientBOF– BOF4507,Tuesday Oct2nd,6.45pm (today!),thisroom(2008,Moscone West)
6
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Thistalkisaboutmigration/adoption/porting
• Hi-dpisupportforWindowsandLinux– Relatestonewmulti-resolutionimageAPIs.
• EncapsulationofinternalAPIs– RelatestoProjectJigsaw(JavaPlatformModuleSystem)
• Removednon-standardAPIs– RelatestoProjectJigsaw(JavaPlatformModuleSystem)
Whathaschangedthatmayrequireyoutoupdateyourapplication.
7
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Hi-DPIsupportforWindows
• Javahaspreviouslyopted-outofboth– Allowingwindowstoauto-scaleit– Sizingthewindowconsistentlywithbuilt-inWindowsapps
• Javawindowsdisplayasifthedisplayis96dpi• Thishasavoideddifficultissuessuchas– Fuzziness–Mappingfloatingpointcoordinatestopixels
• Resultiswindowsandtextthataretoosmallontoday’shi-resdisplays
8
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Font2DTest8runningonJDK8onWindowsat120dpi
9
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Font2DTest8runningonJDK9onWindowsat120dpi
10
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Font2DTest8runningonJDK9at120dpi- analysis
• Nowthecorrectphysicalsize– 1.25timeslarger(120/96)
• Textinthepanelishorrid– ButOKintheUIControls..whatisdifferent?
• DrawstoanimageandcopiesthattotheSwingbackbuffer.– Softwareimageisnotthesamesizeindevicepixelsasthebackbufferexceptat96dpi• For120dpigetsscaledupby1.25– fractionalscale,mapping1pixelto1.25pixelsisnoteasy
– Canthisbefixed?
Whatischanged?
11
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Font2DTest9runningonJDK9onWindowsat120dpi
12
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Font2DTest9runningonJDK9analysis
• Canthisbefixed?• Obviouslyyes.
• How?– TheupdatedcodejustdrawsdirectlytotheSwingbackbuffer.–Minimalchanges–Oldcodewasprobablyintendedtohelpperformance,butitisnotneeded.
Whatischanged?
13
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Whataboutimageresources?
• ImagesarewidelyusedinUIs– iconsinmenus,tooltips,buttons, forradiobuttons,checkboxesetc.– Vectorgraphicsnotanoption,itneedsanimage.
• Upscaleofatinyimagetoscreenresolutionwilloftenlookbad.• Applicationneedstoprovidehigherresolutionimages• Maccanpickup@2ximagesautomatically• SimilarsolutionintheworksforAWT/SwingonWindows&Linux• Multi-resolutionimageAPIcanalsobeused
14
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
class ButtonImages extends java.awt.image.BaseMultiResolutionImage {
public ButtonImages() {super(createImage(1.0), createImage(2.0));
}
BufferedImage createImage(double scale) {bi = new BufferedImage((int)(w*scale), (int)(h*scale), TYPE_INT_RGB);Graphics2D g2d = bi.createGraphics();// ..g2d.drawString(scale + ””, x, y);return bi;
}}
MultiResolution ImageExampleCode
15
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Image multiResImage = new ButtonImages();ImageIcon icon = new ImageIcon(multiResImage);JButton b = new JButton("Button Text", icon);
MultiResolution Imagecontinued– 1.0xscale
16
Nohi-dpi.Devicescaleis1.0,selectedimageisfor1.0scale
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
MultiResolution Imageexamplecontinued– 2.0xscale
17
Devicescaleis2– i.e.192dpionWindows,retinadevicescaleonMac.Thislooks”physically”biggerbecausewearelookingatbothonthesamedisplay
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
MultiResolution Imageexamplecontinued– 1.25xscale
18
Devicescaleis1.25– i.e.120dpionWindowsThefirstimagewithscale>=1.25isselected– souses2.0scaleimagePhysicallysmallerthanwhenrenderedfor192dpi– downscaled.UsingMulti-ResolutionimageAPIatruntimeIcouldhavecreateda1.25scaleImagewhichdidnotneedanyscaling– advantageovercannedimages.
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
MultiResolution Imageexamplecontinued– comparison
19
Baseimageat1.0renderingscale2ximageat1.25renderingscale2ximageat2.0renderingscale
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Hidpi migration- Graphics2d.setTransform()
• BecarefulwithGraphics2D.setTransform()– youhavenoideawhattransformyouareover-riding.– Exceptioniswhenusingtosave/restoreatransform.
• Lookatanexampleprogramthatcentres rectanglesinapane– UsessetTransform torestoretransform– thisisOK– UsessetTransform tosetrenderingtransform– thisisNOT.
20
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
public class DontUseSetTransform extends JPanel {
protected void paintComponent(Graphics g) {Graphics2D g2d = (Graphics2D)g;g2d.setStroke(new BasicStroke(8.0f));for (int i=0; i<colors.length; i++) {
AffineTransform oldTx = g2d.getTransform(); // save current transformAffineTransform at = AffineTransform.getTranslateInstance(size/2, size/2); at.scale(0.2*(i+1), 0.2*(i+1));g2d.setTransform(at); /// bad – instead must use g2d.transform(at)g2d.setColor(colors[i]);g2d.drawRect(-size/4, -size/4, size/2, size/2);g2d.setTransform(oldTx); // this one is OK – restoring the saved transform
}}
}
Hidpi migration- Graphics2d.setTransform()
21
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Hidpi migration- Graphics2d.setTransform()
22
Leftimage:JDK8– 1.0renderingscale– Graphics2D.setTransform()MiddleimageJDK9at1.5renderingscale- Graphics2D.setTransform().Rectanglesarenownotcentred asintended,noraretheythecorrectsize.
Rightimage:JDK9at1.5renderingscale- Graphics2D.transform()Rectanglesnowcenteredandatcorrectsize.
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Hi-DPImigrationsummary
• Off-screenimagesintendedtobeusedonscreen,shouldbecreatedwithscreenresolutioninmind• AvoidGraphics2D.setTransform()– youhavenoideawhattransformyouareover-riding.• –Dsun.java2d.uiScale=1.0canbeuseduntilissuesinyourapplicationcanbefixed.
23
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
ApplicationuseofencapsulatedJDKinternalAPIs
• ApplicationsareknowntomakeuseofJDKinternalAPIs– Somecasesknowingly,othersunknowingly
• JavaPlatformModuleSystemmaypreventsuchaccess.– JDK9willnotenforcethis,butinthefutureitwill– Usethisgraceperiodtofixyourapps
• NBthisisnotaProjectJigsawsession.– DiscussingonlytotheextentneededtoillustrateclientAPIsweknowpeopleuseandwillwantalternatives.
24
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
public class WindowOpacityUtil {
public static void main(String args[]) {Window win = new Window(new Frame()); com.sun.awt.AWTUtilities.setWindowOpacity(win, 0.5f);
}}
$ jdk8u131/bin/javac WindowOpacityUtil.javaWindowOpacityUtil.java:8: warning: AWTUtilities is internal proprietary API and may be removed in a future release
com.sun.awt.AWTUtilities.setWindowOpacity(win, 0.5f); ^
1 warning
$ jdk9/bin/javac WindowOpacityUtil.javaWindowOpacityUtil.java:8: error: package com.sun.awt is not visible
com.sun.awt.AWTUtilities.setWindowOpacity(win, 0.5f); ^
(package com.sun.awt is declared in module java.desktop, which does not export it) 1 error
UseofEncapsulatedAPIs– example:AWTUtilities
25
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
$ jdk9/bin/javac --add-exports java.desktop/com.sun.awt=ALL-UNNAMED WindowOpacityUtil.java
WindowOpacityUtil.java:8: warning: AWTUtilities is internal proprietary API and may be removed in a future release
com.sun.awt.AWTUtilities.setWindowOpacity(win, 0.5f);
WillrunfineinJDK9
$ jdk9/bin/java WindowOpacityUtil
Butnotforever…$ jdk9/bin/java --illegal-access=deny WindowOpacityUtilException in thread "main" java.lang.IllegalAccessError: class WindowOpacityUtil (in unnamed module @0x2781e022) cannot access class com.sun.awt.AWTUtilities (in module java.desktop) because module java.desktop does not export com.sun.awt to unnamed module @0x2781e022
at WindowOpacityUtil.main(WindowOpacityUtil.java:8)
UseofEncapsulatedAPIs– example:AWTUtilities
26
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
public class WindowOpacityUtil {
public static void main(String args[]) {Window win = new Window(new Frame()); com.sun.awt.AWTUtilities.setWindowOpacity(win, 0.5f);
}}
$ jdk8u131/bin/javac WindowOpacityUtil.javaWindowOpacityUtil.java:8: warning: AWTUtilities is internal proprietary API and may be removed in a future release
com.sun.awt.AWTUtilities.setWindowOpacity(win, 0.5f); ^
1 warning
$ jdk9/bin/javac WindowOpacityUtil.javaWindowOpacityUtil.java:8: error: package com.sun.awt is not visible
com.sun.awt.AWTUtilities.setWindowOpacity(win, 0.5f); ^
(package com.sun.awt is declared in module java.desktop, which does not export it) 1 error
UseofEncapsulatedAPIs– example:AWTUtilities
27
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
public class WindowOpacity {
public static void main(String args[]) {Window win = new Window(new Frame());win.setOpacity(0.5f); // since JDK 7
}
}
UseofEncapsulatedAPIs– example:AWTUtilities
28
SolutionistoupdateyourcodetouseexportedstandardAPIs beforethegraceperiodrunsout
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
public class CreateSystemLAF_Reflect {public static void main(String args[]) throws Exception {
String lafName = javax.swing.UIManager.getSystemLookAndFeelClassName();Class c = Class.forName(lafName);javax.swing.LookAndFeel laf = (javax.swing.LookAndFeel)(c.newInstance());
}}
UseofEncapsulatedAPIs– example:SwingSystemL&F
29
java --illegal-access=deny CreateSystemLAF_Reflect com.apple.laf.AquaLookAndFeel
Exception in thread "main" java.lang.IllegalAccessException: class CreateSystemLAF_Reflectcannot access class com.apple.laf.AquaLookAndFeel (in module java.desktop)because module java.desktop does not export com.apple.laf to unnamed module @2ef5e5e3at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:361)at java.base/jdk.internal.reflect.Reflection.ensureMemberAccess(Reflection.java:107)at java.base/java.lang.Class.newInstance(Class.java:553)at CreateSystemLAF_Reflect.main(CreateSystemLAF_Reflect.java:5)
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
public class CreateSystemLAF {
public static void main(String args[]) {String lafName = javax.swing.UIManager.getSystemLookAndFeelClassName();javax.swing.UIManager.installLookAndFeel(lafName);
}
}
UseofEncapsulatedAPIs– example:SwingSystemL&F
30
Solutionistoupdateyourcodetoletcodeinthejava.desktop moduledotheinstantiation
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Applicationuseofremovednon-standardAPIs
• Thisincludes– APIswhichmayhavebeenpreviouslydocumentedbutarenowremovedorchanged,evenifpreviouslydocumented– APIswhichhaveneverbeendocumentedandmaybeeitherremovedorchanged
• Nograceperiodhere.– Yourapplicationneedtobeupdatedoritwillnotrun
• Examples– com.sun.jpeg.codec – migratetojavax.imageio– java.awt.peer APIs– migratetosupportedComponentAPIs
31
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
import java.awt.Frame;import java.awt.peer.ComponentPeer;
public class GetPeer {
public static void main(String args[]) {Frame f = new Frame();
}}
$ jdk8u131/bin/javac GetPeer.javaGetPeer.java:1: warning: ComponentPeer is internal proprietary API and may be removed in a future releaseimport java.awt.peer.ComponentPeer
^GetPeer.java:8: warning: ComponentPeer is internal proprietary API and may be removed in a future release
ComponentPeer peer = f.getPeer();
2 warnings
UseofRemovedAPIs– example:AWTPeers
32
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
$ jdk9/bin/java GetPeerException in thread "main" java.lang.NoSuchMethodError:
java.awt.Frame.getPeer()Ljava/awt/peer/ComponentPeer;at GetPeer.main(GetPeer.java:8)
Convertto”new”APIsASAP:eg,thesejava.awt.Component APISfromJDK1.1/1.2
public boolean isLightweight(); // for getPeer() instanceof LightweightPeerpublic boolean isDisplayable(); // for getPeer() != null
WatchoutforoldSwingcodeusingtheunbundledswing.jar from1997whichdoesthis!
UseofRemovedAPIs– example:AWTPeers
33
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
AWT/Swingmigrationsummary
• Hi-DPIwillmakeyourapplookmorenative– Butforbestresultsappsmayneedupdating–Will(mostly)notstopyourappfromworking• ExceptionisifyouareusingsetTransform incorrectly
• AppswillneedupdatingtostopusingremovedandencapsulatedAPIs– Usejdeps tooland“—illegal-access=warn|deny”tofindthem– Standardpublicalternativesareavailableforthecasesweknowabout– ReportanymissingonesASAPatbugs.java.com
34
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
MigratingJavaFXApplicationstoJDK9KevinRushforth
35
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
JavaFXinJDK9
• JavaFXinJDK9is(mostly)compatiblewithJDK8ureleases– If youstickwithdocumentedpublicAPIs– moreonthislater
• ThereareafewthingstowatchoutforevenifyoudoonlyusepublicAPIs:– Hi-DPIsupportaddedtoLinux,enabledonWindowsinmorecases– SWTbridgerenamedfromjfxswt.jartojavafx-swt.jarforuseasautomaticmodule
• Ifyoumodularizeyourappthereareafewmorethingstocareabout–Mosthavetodowithvisibilityandencapsulation
Overview
36
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Hi-DPI• JDK8u60hasthefollowingsupportforHigh-DPI:–Mac:forretinadisplay,integerscales(200%)–Windows:forHigh-DPIsettings>=150%– NoLinuxsupport– NoAPItoallowapplicationcontroloverHigh-DPIscaling• Renderingisalwaysdonewithanintegerscale• OnWindows,theblit tothescreenmightuseanon-integerscale
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Hi-DPI• InJDK9weadded:– High-DPIsupportforLinux– High-DPIenabledonWindowsforscale>1(e.g.,125%)– APItogetthescreenscale– APItoforceintegerrenderscale(falsebydefault)– APItoset/gettherenderscale– Supportfor“snaptopixel”evenwhenusingnon-integerrenderscale– Automaticallyhandleswindowsmovingbetweenscreenswithdifferentscales
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Hi-DPI• InJDK8wealwaysrenderatanintegerscaleandstretchorshrinktheoffscreenrenderbuffertotheactualsizeoftheoutputwindow
• InJDK9therenderbufferiscreatedwiththesamesizeastheoutputwindow,meaningtherenderingscalecanbenon-integer– ThiscanbedisabledwiththeforceIntegerScale property– UsesnapPosition{XY}andsnapSize{XY}methodstoavoidblurriness
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Hi-DPI• JavaFXautomaticallyrecognizesandloads@2ximage,ifpresentandrunninginHi-DPImode
• Withnon-integerscreenscaleonWindows(e.g.,125%or150%)imagescanlookblurry– YoucanprovideanimageofthecorrectresolutionbasedontherenderScale oftheWindow
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Hi-DPI• Ifyoudon'twantHi-DPIscalingatall,itcanbedisabledbysettingthefollowingsystemproperty:
java -Dprism.allowhidpi=false
• OnWindowsandLinux,youcanforcethescalingtosomethingotherthanthedefaultbysettingthefollowing.–Windows:glass.win.uiScale– Linux:glass.gtk.uiScale–MacOS:nowaytooverride(althoughcanbedisabledwithprism.allowhidpi)–Mainlyfordebugging/testingwhatyourappwilllooklikeatdifferentscales
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
SWTInterop:DeployingYourApplication• SWTinteropisstilldeliveredasaseparatejarfile:– Cannotbelinkedintoruntimeimagebecauseitdependsonthird-partyswt.jar– Itisan“automatic”module(meaningnomodule-info.class)– Renamedtojavafx-swt.jar(formerlyjfxswt.jar)• Automaticmodulenameisderivedas:javafx.swt
• InJDK8youcouldaddittothebootclasspath:java --Xbootclasspath/a:$JRE/lib/jfxswt.jar …
• InJDK9youneedtoadditasamodule:java --module-path $JRE/lib/javafx-swt.jar --add-modules javafx.swt …
• Italsorequirespermissionsifasecuritymanagerisenabled
42
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
JavaFXinJDK9:KnownIncompatibilities• TheJavamodulesystemprovidesencapsulationofinternalpackages• Thecom.sun.*packagesinJavaFXarenotpartofthepublicAPI– Someapplicationsendedupusingthemanyway(e.g.,controlsskins,CSSparsing)–Manyhavebeenremovedorchangedincompatibly(somemight“accidentally”continuetoworkabsentstrictencapsulation)– Severalofthesehavepublicreplacements
• Allpublic/protectedimpl_*methodsinpublicclasseshavebeenremoved
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
JavaFXinJDK9:KnownIncompatibilities• Nodebuilderclasses– DeprecatedinJDK8(andnotpartofAPIdocs)andslatedforremoval– RemovedfromJDK9– AppsshouldconstructFXnodesdirectlyandcallsetmethods
• JMXsupport–Weusedtoshipastandalonejavafx-mx.jarfilewiththeJDK(notJRE)– UnsupportedinJDK8– RemovedfromJDK9– SourcecodeisavailableinOpenJFX projectifneeded(butyou’reonyourown)
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
EncapsulationofImplementationPackages• Onlyexportedpackagescanbeseenatcompiletime– Use“javac --add-exports”tooverridestrictencapsulation
• Unnamedmoduleswillcontinuetobeabletoaccessinternalpackages–fornow• Runwith“java--illegal-access=deny”forapreviewofwhat’stocome• JDK9givesyouagraceperiodforsomecases– Doesn’thelpforAPIsthatwerechangedincompatiblyorremoved–Modularapplicationsgetstrictencapsulationfromthestart
• Usethisreleasetotransitionyourapplicationawayfrominternal“APIs”
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Encapsulationofimpl_“API”• JavaFXhasalwayshadpublicmethodsthatstartedwith‘impl_’,e.g.– Image::impl_getUrl orContextMenu::impl_showRelativeToWindow
• ThesewerehiddenfromAPIdocsandmarked@Deprecatedtoindicatethatapplicationsshouldnotusethem–Mostofthesewerejustimplementationdetails– Someweretherebecauseweweren’treadytocommittothemasfinalAPI
• Themodulesystemhidesnon-publicpackages,sowetooktheopportunitytocleanupourimpl_* APIsinJavaFX• Allimpl_* methodsaregone,butafewhavebecomepublicAPI
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Turningimpl_*methodsintopublicAPI• Publicreplacementsforsomeformerimpl_* methods:– FXMLLoader:LoadListener interface+set/getmethods– Image:getUrl()– KeyCode:getChar(),getCode()– GridPane:getRowCount(),getColumnCount(),getCellBounds(col,row)– Text,TextFlow:selection,caret,hittestAPIs–Window:getWindows()– FXCanvas:getFXCanvas()– TableColumnBase:reorderable property
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
public class PlatformTest {public static void main(String[] args) {
com.sun.javafx.application.PlatformImpl.startup(() -> {System.err.println("JavaFX runtime started");
});}
$ jdk9/bin/javac PlatformTest.javaPlatformTest.java:3: error: package com.sun.javafx.application is not visible
com.sun.javafx.application.PlatformImpl.startup(() -> {^
(package com.sun.javafx.application is declared in module javafx.graphics, which does not export it to the unnamed module)1 error
UseofEncapsulatedAPIs– example:PlatformImpl
48
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
$ jdk9/bin/javac --add-exports javafx.graphics/com.sun.javafx.application=ALL-UNNAMED PlatformTest.java
WillrunfineinJDK9
$ jdk9/bin/java PlatformTestJavaFX runtime started.
Butnotforever…
$ jdk9/bin/java --illegal-access=deny PlatformTestException in thread "main" java.lang.IllegalAccessError: class PlatformTest (in unnamed module @0x33ce2c) cannot access class com.sun.javafx.application.PlatformImpl (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.applicationto unnamed module @0x33ce2c
at PlatformTest.main(PlatformTest.java:3)
UseofEncapsulatedAPIs– example:PlatformImpl
49
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
public class PlatformTest {public static void main(String[] args) {
javafx.application.Platform.startup(() -> {System.err.println("JavaFX runtime started");
});}
UseofEncapsulatedAPIs– example:PlatformImpl
50
SolutionistoupdateyourcodetouseexportedstandardAPIsbeforethegraceperiodrunsout
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Example:CustomControl• Applicationsthatextendthefunctionalityofexistingcontrols,needtoextendtheexistingSkinclassinordertoenhanceit• Thecom.sun.javafx.scene.control.skin packageisgonein9– Therelevantskinsmovedtoapublicjavafx.scene.control.skin package– Notallmethodsintheoldskinclassesareexposed– ItisaminimalAPIthatcanbeenhancedlateriftheneedarises
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Example:CustomControl(fromcontrolsfx)• Usecase:customizingtheTextField control• CustomTextFieldSkin:startbyjustchangingthe“import”statements–Otherminorchangeswillbeneeded
• NOTE:BehaviorsarenotexposedinJDK9(andtheimplementationchanged)– SoyoucannotextendtheBehaviorsinyourcustomcontrol– thisisn’tcommonanyway
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Example:CustomControl– JDK8import com.sun.javafx.scene.control.behavior.TextFieldBehavior;import com.sun.javafx.scene.control.skin.TextFieldSkin;import com.sun.javafx.scene.text.HitInfo;
import javafx.scene.control.TextField;
public class CustomTextFieldSkin extends TextFieldSkin {public CustomTextFieldSkin(TextField control) {
super(control, new TextFieldBehavior(control));...registerChangeListener(leftProperty(), "LEFT_NODE");registerChangeListener(rightProperty(), "RIGHT_NODE");
}
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Example:CustomControl– JDK8@Override protected void handleControlPropertyChanged(String p) {
super.handleControlPropertyChanged(p);if ("LEFT_NODE".equals(p) || "RIGHT_NODE".equals(p)) {
updateChildren();}
}
@Override public HitInfo getIndex(double x, double y) {// Adjust parameters and call super.getIndexfinal double adjX = f(x)final double adjY = f(y)
return super.getIndex(x - adjX, y - adjY);}...
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Example:CustomControl– JDK9import javafx.scene.control.TextField;
import javafx.scene.control.skin.TextFieldSkin;import javafx.scene.text.HitInfo;
public class CustomTextFieldSkin extends TextFieldSkin {public CustomTextFieldSkin(TextField control) {
super(control); // no Behavior passed to superclass...registerChangeListener(leftProperty(), e -> updateChildren());registerChangeListener(rightProperty(), e -> updateChildren());
}
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Example:CustomControl– JDK9// No public handleControlPropertyChanged method in TextControlSkin
@Override public HitInfo getIndex(double x, double y) {// Adjust parameters and call super.getIndexfinal double adjX = f(x)final double adjY = f(y)
return super.getIndex(x - adjX, y - adjY);}...
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Modularizingyourapplication• Modularapplicationslisttheirdependenciesinmodule-info.java– Exportedpackagesofrequiredmodulesareaccessible– Hereisaminimalmodule-info.javaforanapplicationthatusesthejavafx.controls,javafx.graphics,andjavafx.base modules(controlsre-exportsgraphicsandbase)
57
module mymod {requires javafx.controls;
}
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Encapsulation:ImpactonModularApplications• LaunchingaJavaFXApplication– TheJavaFXlauncherconstructsaninstanceofyourApplicationsubclass– ThismeansJavaFXmustbeabletoaccessthatclass,orelsewillthrowIllegalAccessException– Youneedtoexportthecontainingpackagetojavafx.graphics (orpublicly)– Example:
module mymod {requires javafx.controls;
exports my.pkg to javafx.graphics;}
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Encapsulation:ImpactonModularApplications• Annotatingnon-publictypeswith@FXML– FXMLneedsabilitytoaccessyourprivatefieldsandmethods,orelsewillthrowIllegalAccessException– Youneedto“open”yourpackagetojavafx.fxml– Example:
module mymod {requires javafx.controls;requires javafx.fxml;
exports my.pkg to javafx.graphics;opens my.pkg to javafx.fxml;
}
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
ResourceEncapsulation:ImpactonModularApplications• JavaFXhasseveralAPIsthattakeaURL(orurl String)– CSSStylesheets– FXMLLoader– Image&Media–WebEngine
• Class::getResource willfindresourcesinmodulesifpackageisexported– Nomore“dippinginto”theinternalstoloadanothermodule’sresource
• ClassLoader::getResource willnotfindresourcesinmodulesbydefault– Amodularappcannotsimplyuse"/some/path/myresource.css"asstylesheetURL– Itwillworkifyou“open”thepackagecontainingtheresource
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
ModularExample:CSSStyleSheets• Twochoicesforlocatingresourcesinmodularapplication:1.RelativeURL:"/mypkg/MyStyle.css“• FindsresourcesusingContextClassLoader• Youmust"open"thecontainingpackageunconditionally
2.AbsoluteURL:MyClass.class.getResource("MyStyle.css").toExternalForm()• Useaclassinthesamepackage(or"super-package")tolocateyourresources• Norequirementtoopen(orexport)thepackage
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
ModularExample:CSSStyleSheetspackage pkg1;
...
public class MyApp extends Application {@Override public void start(Stage stage) {
String urlString;if (RELATIVE_URL) {
urlString = "pkg1/resources/style.css";} else {
urlString = MyApp.class.getResource("resources/style.css").toExternalForm();
}
...
Scene = new Scene(root, WIDTH, HEIGHT);scene.getStylesheets().add(urlString);
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
ModularExample:CSSStyleSheetsmodule mymod {
requires javafx.graphics;
exports pkg1 to javafx.graphics;
//opens pkg1.resources; // Needed for relative URLs to work}
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
JavaFXMigrationSummary• AppswillneedupdatingtostopusingremovedandencapsulatedAPIs– Usejdeps tooland“—illegal-access=warn|deny”tofindthem– Don’tusesetAccessible toaccessnon-publictypes(eveninajavafx.*package)– Standardpublicalternativesareavailableforthemostcommoncases– ReportanymissingonesASAPatbugs.java.com
• Hi-DPIwillmakeyourapplookmorenative– Shouldbetransparenttomany/mostapplications– Butforbestresultsappsmayneedupdating
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
JavaFXMigrationSummary• Modularappsneedtotakeextracare–MustexportoropenpackagesthatJavaFXneedstoaccess• Youcanstilllimitvisibilitywithqualifiedexportsoropensstatements
– UseClass.getResource()whenconstructingURLs• Oryoumust“open”yourresourcepackage(s)unconditionally
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Sessionsreminder• MeettheOracleJavaFXandJDKClientTeam[BOF4507]– Tuesday,Oct03,6:45p.m.- 7:30p.m.|Moscone West- Room2008
• Marlin,aJDK9SuccessStory:VectorGraphicsonSteroidsforJava2DandJavaFX[CON4052]–Wednesday,Oct04,1:45p.m.- 2:30p.m.|Moscone West- Room2008
Copyright©2017, Oracleand/oritsaffiliates.Allrightsreserved. |
Stayconnected
• Joinus:DevOpsCorner(DeveloperLounge– Moscone West)• Learnmore:openjdk.java.net |wercker.com/java• Follow:@OpenJDK,@wercker #JavaOne #DevOps
67