diff --git a/build.xml b/build.xml
index f9fad849..1afe3785 100644
--- a/build.xml
+++ b/build.xml
@@ -57,6 +57,7 @@
+
@@ -66,6 +67,7 @@
+
@@ -90,6 +92,7 @@
+
@@ -173,6 +176,7 @@
+
@@ -469,28 +473,10 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
+
+
diff --git a/ivy.xml b/ivy.xml
index 879b868c..741cd5f8 100644
--- a/ivy.xml
+++ b/ivy.xml
@@ -39,6 +39,7 @@
+
diff --git a/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.5.txt b/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.5.txt
index 68c1bf3b..b1f04eda 100644
--- a/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.5.txt
+++ b/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.5.txt
@@ -1,7 +1,6 @@
-# This file contains API signatures extracted from the rt.jar file
-# shipped with the class library of Oracle's Java Runtime Environment.
-# It is provided here for reference, but can easily regenerated by executing:
-# $ java de.thetaphi.forbiddenapis.DeprecatedGen 1.5 /path/to/rt.jar /path/to/this/file.txt
+# This file contains API signatures extracted from the rt.jar file shipped with the class library of Oracle's Java Runtime Environment.
+# It is provided here for reference, but can easily regenerated by executing from the source folder of forbidden-apis:
+# $ ant generate-deprecated
# This file contains all public, deprecated API signatures in Java version 1.5 (extracted from build 1.5.0_22).
diff --git a/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.6.txt b/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.6.txt
index 84b8073a..cc806b9b 100644
--- a/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.6.txt
+++ b/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.6.txt
@@ -1,7 +1,6 @@
-# This file contains API signatures extracted from the rt.jar file
-# shipped with the class library of Oracle's Java Runtime Environment.
-# It is provided here for reference, but can easily regenerated by executing:
-# $ java de.thetaphi.forbiddenapis.DeprecatedGen 1.6 /path/to/rt.jar /path/to/this/file.txt
+# This file contains API signatures extracted from the rt.jar file shipped with the class library of Oracle's Java Runtime Environment.
+# It is provided here for reference, but can easily regenerated by executing from the source folder of forbidden-apis:
+# $ ant generate-deprecated
# This file contains all public, deprecated API signatures in Java version 1.6 (extracted from build 1.6.0_32).
diff --git a/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.7.txt b/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.7.txt
index aa593ea6..789fc048 100644
--- a/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.7.txt
+++ b/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.7.txt
@@ -1,7 +1,6 @@
-# This file contains API signatures extracted from the rt.jar file
-# shipped with the class library of Oracle's Java Runtime Environment.
-# It is provided here for reference, but can easily regenerated by executing:
-# $ java de.thetaphi.forbiddenapis.DeprecatedGen 1.7 /path/to/rt.jar /path/to/this/file.txt
+# This file contains API signatures extracted from the rt.jar file shipped with the class library of Oracle's Java Runtime Environment.
+# It is provided here for reference, but can easily regenerated by executing from the source folder of forbidden-apis:
+# $ ant generate-deprecated
# This file contains all public, deprecated API signatures in Java version 1.7 (extracted from build 1.7.0_65).
diff --git a/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.8.txt b/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.8.txt
index 22ea9ee9..326dcb10 100644
--- a/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.8.txt
+++ b/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.8.txt
@@ -1,7 +1,6 @@
-# This file contains API signatures extracted from the rt.jar file
-# shipped with the class library of Oracle's Java Runtime Environment.
-# It is provided here for reference, but can easily regenerated by executing:
-# $ java de.thetaphi.forbiddenapis.DeprecatedGen 1.8 /path/to/rt.jar /path/to/this/file.txt
+# This file contains API signatures extracted from the rt.jar file shipped with the class library of Oracle's Java Runtime Environment.
+# It is provided here for reference, but can easily regenerated by executing from the source folder of forbidden-apis:
+# $ ant generate-deprecated
# This file contains all public, deprecated API signatures in Java version 1.8 (extracted from build 1.8.0_25).
diff --git a/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.9.txt b/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.9.txt
new file mode 100644
index 00000000..483eae36
--- /dev/null
+++ b/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.9.txt
@@ -0,0 +1,464 @@
+# This file contains API signatures extracted from the rt.jar file shipped with the class library of Oracle's Java Runtime Environment.
+# It is provided here for reference, but can easily regenerated by executing from the source folder of forbidden-apis:
+# $ ant generate-deprecated
+
+# This file contains all public, deprecated API signatures in Java version 1.9 (extracted from build 1.9.0-ea).
+
+@ignoreUnresolvable
+@defaultMessage Deprecated in Java 1.9
+
+java.awt.BorderLayout#addLayoutComponent(java.lang.String,java.awt.Component)
+java.awt.CardLayout#addLayoutComponent(java.lang.String,java.awt.Component)
+java.awt.CheckboxGroup#getCurrent()
+java.awt.CheckboxGroup#setCurrent(java.awt.Checkbox)
+java.awt.Choice#countItems()
+java.awt.Component#action(java.awt.Event,java.lang.Object)
+java.awt.Component#bounds()
+java.awt.Component#deliverEvent(java.awt.Event)
+java.awt.Component#disable()
+java.awt.Component#enable()
+java.awt.Component#enable(boolean)
+java.awt.Component#getPeer()
+java.awt.Component#gotFocus(java.awt.Event,java.lang.Object)
+java.awt.Component#handleEvent(java.awt.Event)
+java.awt.Component#hide()
+java.awt.Component#inside(int,int)
+java.awt.Component#isFocusTraversable()
+java.awt.Component#keyDown(java.awt.Event,int)
+java.awt.Component#keyUp(java.awt.Event,int)
+java.awt.Component#layout()
+java.awt.Component#locate(int,int)
+java.awt.Component#location()
+java.awt.Component#lostFocus(java.awt.Event,java.lang.Object)
+java.awt.Component#minimumSize()
+java.awt.Component#mouseDown(java.awt.Event,int,int)
+java.awt.Component#mouseDrag(java.awt.Event,int,int)
+java.awt.Component#mouseEnter(java.awt.Event,int,int)
+java.awt.Component#mouseExit(java.awt.Event,int,int)
+java.awt.Component#mouseMove(java.awt.Event,int,int)
+java.awt.Component#mouseUp(java.awt.Event,int,int)
+java.awt.Component#move(int,int)
+java.awt.Component#nextFocus()
+java.awt.Component#postEvent(java.awt.Event)
+java.awt.Component#preferredSize()
+java.awt.Component#reshape(int,int,int,int)
+java.awt.Component#resize(int,int)
+java.awt.Component#resize(java.awt.Dimension)
+java.awt.Component#show()
+java.awt.Component#show(boolean)
+java.awt.Component#size()
+java.awt.ComponentOrientation#getOrientation(java.util.ResourceBundle)
+java.awt.Container#countComponents()
+java.awt.Container#deliverEvent(java.awt.Event)
+java.awt.Container#insets()
+java.awt.Container#layout()
+java.awt.Container#locate(int,int)
+java.awt.Container#minimumSize()
+java.awt.Container#preferredSize()
+java.awt.Cursor#predefined
+java.awt.Dialog#hide()
+java.awt.Dialog#show()
+java.awt.Font#getPeer()
+java.awt.FontMetrics#getMaxDecent()
+java.awt.Frame#CROSSHAIR_CURSOR
+java.awt.Frame#DEFAULT_CURSOR
+java.awt.Frame#E_RESIZE_CURSOR
+java.awt.Frame#HAND_CURSOR
+java.awt.Frame#MOVE_CURSOR
+java.awt.Frame#NE_RESIZE_CURSOR
+java.awt.Frame#NW_RESIZE_CURSOR
+java.awt.Frame#N_RESIZE_CURSOR
+java.awt.Frame#SE_RESIZE_CURSOR
+java.awt.Frame#SW_RESIZE_CURSOR
+java.awt.Frame#S_RESIZE_CURSOR
+java.awt.Frame#TEXT_CURSOR
+java.awt.Frame#WAIT_CURSOR
+java.awt.Frame#W_RESIZE_CURSOR
+java.awt.Frame#getCursorType()
+java.awt.Frame#setCursor(int)
+java.awt.Graphics#getClipRect()
+java.awt.List#addItem(java.lang.String)
+java.awt.List#addItem(java.lang.String,int)
+java.awt.List#allowsMultipleSelections()
+java.awt.List#clear()
+java.awt.List#countItems()
+java.awt.List#delItem(int)
+java.awt.List#delItems(int,int)
+java.awt.List#isSelected(int)
+java.awt.List#minimumSize()
+java.awt.List#minimumSize(int)
+java.awt.List#preferredSize()
+java.awt.List#preferredSize(int)
+java.awt.List#setMultipleSelections(boolean)
+java.awt.Menu#countItems()
+java.awt.MenuBar#countMenus()
+java.awt.MenuComponent#getPeer()
+java.awt.MenuComponent#postEvent(java.awt.Event)
+java.awt.MenuContainer#postEvent(java.awt.Event)
+java.awt.MenuItem#disable()
+java.awt.MenuItem#enable()
+java.awt.MenuItem#enable(boolean)
+java.awt.Polygon#getBoundingBox()
+java.awt.Polygon#inside(int,int)
+java.awt.Rectangle#inside(int,int)
+java.awt.Rectangle#move(int,int)
+java.awt.Rectangle#reshape(int,int,int,int)
+java.awt.Rectangle#resize(int,int)
+java.awt.ScrollPane#layout()
+java.awt.Scrollbar#getLineIncrement()
+java.awt.Scrollbar#getPageIncrement()
+java.awt.Scrollbar#getVisible()
+java.awt.Scrollbar#setLineIncrement(int)
+java.awt.Scrollbar#setPageIncrement(int)
+java.awt.TextArea#appendText(java.lang.String)
+java.awt.TextArea#insertText(java.lang.String,int)
+java.awt.TextArea#minimumSize()
+java.awt.TextArea#minimumSize(int,int)
+java.awt.TextArea#preferredSize()
+java.awt.TextArea#preferredSize(int,int)
+java.awt.TextArea#replaceText(java.lang.String,int,int)
+java.awt.TextField#minimumSize()
+java.awt.TextField#minimumSize(int)
+java.awt.TextField#preferredSize()
+java.awt.TextField#preferredSize(int)
+java.awt.TextField#setEchoCharacter(char)
+java.awt.Toolkit#getFontList()
+java.awt.Toolkit#getFontMetrics(java.awt.Font)
+java.awt.Toolkit#getFontPeer(java.lang.String,int)
+java.awt.Window#applyResourceBundle(java.lang.String)
+java.awt.Window#applyResourceBundle(java.util.ResourceBundle)
+java.awt.Window#hide()
+java.awt.Window#postEvent(java.awt.Event)
+java.awt.Window#reshape(int,int,int,int)
+java.awt.Window#show()
+java.awt.datatransfer.DataFlavor#equals(java.lang.String)
+java.awt.datatransfer.DataFlavor#normalizeMimeType(java.lang.String)
+java.awt.datatransfer.DataFlavor#normalizeMimeTypeParameter(java.lang.String,java.lang.String)
+java.awt.datatransfer.DataFlavor#plainTextFlavor
+java.awt.event.KeyEvent#(java.awt.Component,int,long,int,int)
+java.awt.event.KeyEvent#setModifiers(int)
+java.awt.image.renderable.RenderContext#concetenateTransform(java.awt.geom.AffineTransform)
+java.awt.image.renderable.RenderContext#preConcetenateTransform(java.awt.geom.AffineTransform)
+java.io.ByteArrayOutputStream#toString(int)
+java.io.DataInputStream#readLine()
+java.io.File#toURL()
+java.io.LineNumberInputStream
+java.io.ObjectInputStream#readLine()
+java.io.ObjectOutputStream$PutField#write(java.io.ObjectOutput)
+java.io.StreamTokenizer#(java.io.InputStream)
+java.io.StringBufferInputStream
+java.lang.Character#isJavaLetter(char)
+java.lang.Character#isJavaLetterOrDigit(char)
+java.lang.Character#isSpace(char)
+java.lang.Character$UnicodeBlock#SURROGATES_AREA
+java.lang.ClassLoader#defineClass(byte[],int,int)
+java.lang.Runtime#getLocalizedInputStream(java.io.InputStream)
+java.lang.Runtime#getLocalizedOutputStream(java.io.OutputStream)
+java.lang.Runtime#runFinalizersOnExit(boolean)
+java.lang.SecurityManager#checkAwtEventQueueAccess()
+java.lang.SecurityManager#checkMemberAccess(java.lang.Class,int)
+java.lang.SecurityManager#checkMulticast(java.net.InetAddress,byte)
+java.lang.SecurityManager#checkSystemClipboardAccess()
+java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object)
+java.lang.SecurityManager#classDepth(java.lang.String)
+java.lang.SecurityManager#classLoaderDepth()
+java.lang.SecurityManager#currentClassLoader()
+java.lang.SecurityManager#currentLoadedClass()
+java.lang.SecurityManager#getInCheck()
+java.lang.SecurityManager#inCheck
+java.lang.SecurityManager#inClass(java.lang.String)
+java.lang.SecurityManager#inClassLoader()
+java.lang.String#(byte[],int)
+java.lang.String#(byte[],int,int,int)
+java.lang.String#getBytes(int,int,byte[],int)
+java.lang.System#runFinalizersOnExit(boolean)
+java.lang.Thread#countStackFrames()
+java.lang.Thread#destroy()
+java.lang.Thread#resume()
+java.lang.Thread#stop()
+java.lang.Thread#stop(java.lang.Throwable)
+java.lang.Thread#suspend()
+java.lang.ThreadGroup#allowThreadSuspension(boolean)
+java.lang.ThreadGroup#resume()
+java.lang.ThreadGroup#stop()
+java.lang.ThreadGroup#suspend()
+java.net.DatagramSocketImpl#getTTL()
+java.net.DatagramSocketImpl#setTTL(byte)
+java.net.HttpURLConnection#HTTP_SERVER_ERROR
+java.net.MulticastSocket#getTTL()
+java.net.MulticastSocket#send(java.net.DatagramPacket,byte)
+java.net.MulticastSocket#setTTL(byte)
+java.net.Socket#(java.lang.String,int,boolean)
+java.net.Socket#(java.net.InetAddress,int,boolean)
+java.net.URLConnection#getDefaultRequestProperty(java.lang.String)
+java.net.URLConnection#setDefaultRequestProperty(java.lang.String,java.lang.String)
+java.net.URLDecoder#decode(java.lang.String)
+java.net.URLEncoder#encode(java.lang.String)
+java.net.URLStreamHandler#setURL(java.net.URL,java.lang.String,java.lang.String,int,java.lang.String,java.lang.String)
+java.rmi.RMISecurityException
+java.rmi.RMISecurityManager
+java.rmi.ServerRuntimeException
+java.rmi.dgc.VMID#isUnique()
+java.rmi.registry.RegistryHandler
+java.rmi.server.LoaderHandler
+java.rmi.server.LogStream
+java.rmi.server.Operation
+java.rmi.server.RMIClassLoader#getSecurityContext(java.lang.ClassLoader)
+java.rmi.server.RMIClassLoader#loadClass(java.lang.String)
+java.rmi.server.RemoteCall
+java.rmi.server.RemoteRef#done(java.rmi.server.RemoteCall)
+java.rmi.server.RemoteRef#invoke(java.rmi.server.RemoteCall)
+java.rmi.server.RemoteRef#newCall(java.rmi.server.RemoteObject,java.rmi.server.Operation[],int,long)
+java.rmi.server.RemoteStub
+java.rmi.server.ServerRef
+java.rmi.server.Skeleton
+java.rmi.server.SkeletonMismatchException
+java.rmi.server.SkeletonNotFoundException
+java.rmi.server.SocketSecurityException
+java.rmi.server.UnicastRemoteObject#exportObject(java.rmi.Remote)
+java.security.Certificate
+java.security.Identity
+java.security.IdentityScope
+java.security.Security#getAlgorithmProperty(java.lang.String,java.lang.String)
+java.security.Signature#getParameter(java.lang.String)
+java.security.Signature#setParameter(java.lang.String,java.lang.Object)
+java.security.SignatureSpi#engineGetParameter(java.lang.String)
+java.security.SignatureSpi#engineSetParameter(java.lang.String,java.lang.Object)
+java.security.Signer
+java.sql.CallableStatement#getBigDecimal(int,int)
+java.sql.Date#(int,int,int)
+java.sql.Date#getHours()
+java.sql.Date#getMinutes()
+java.sql.Date#getSeconds()
+java.sql.Date#setHours(int)
+java.sql.Date#setMinutes(int)
+java.sql.Date#setSeconds(int)
+java.sql.DriverManager#getLogStream()
+java.sql.DriverManager#setLogStream(java.io.PrintStream)
+java.sql.PreparedStatement#setUnicodeStream(int,java.io.InputStream,int)
+java.sql.ResultSet#getBigDecimal(int,int)
+java.sql.ResultSet#getBigDecimal(java.lang.String,int)
+java.sql.ResultSet#getUnicodeStream(int)
+java.sql.ResultSet#getUnicodeStream(java.lang.String)
+java.sql.Time#(int,int,int)
+java.sql.Time#getDate()
+java.sql.Time#getDay()
+java.sql.Time#getMonth()
+java.sql.Time#getYear()
+java.sql.Time#setDate(int)
+java.sql.Time#setMonth(int)
+java.sql.Time#setYear(int)
+java.sql.Timestamp#(int,int,int,int,int,int,int)
+java.util.Date#(int,int,int)
+java.util.Date#(int,int,int,int,int)
+java.util.Date#(int,int,int,int,int,int)
+java.util.Date#(java.lang.String)
+java.util.Date#UTC(int,int,int,int,int,int)
+java.util.Date#getDate()
+java.util.Date#getDay()
+java.util.Date#getHours()
+java.util.Date#getMinutes()
+java.util.Date#getMonth()
+java.util.Date#getSeconds()
+java.util.Date#getTimezoneOffset()
+java.util.Date#getYear()
+java.util.Date#parse(java.lang.String)
+java.util.Date#setDate(int)
+java.util.Date#setHours(int)
+java.util.Date#setMinutes(int)
+java.util.Date#setMonth(int)
+java.util.Date#setSeconds(int)
+java.util.Date#setYear(int)
+java.util.Date#toGMTString()
+java.util.Date#toLocaleString()
+java.util.Properties#save(java.io.OutputStream,java.lang.String)
+java.util.jar.Attributes$Name#EXTENSION_INSTALLATION
+java.util.jar.Attributes$Name#IMPLEMENTATION_URL
+java.util.jar.Attributes$Name#IMPLEMENTATION_VENDOR_ID
+java.util.logging.LogRecord#getMillis()
+java.util.logging.LogRecord#setMillis(long)
+java.util.logging.Logger#global
+java.util.logging.Logger#logrb(java.util.logging.Level,java.lang.String,java.lang.String,java.lang.String,java.lang.String)
+java.util.logging.Logger#logrb(java.util.logging.Level,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+java.util.logging.Logger#logrb(java.util.logging.Level,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.Object[])
+java.util.logging.Logger#logrb(java.util.logging.Level,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.Throwable)
+javax.accessibility.AccessibleResourceBundle
+javax.activation.ActivationDataFlavor#normalizeMimeType(java.lang.String)
+javax.activation.ActivationDataFlavor#normalizeMimeTypeParameter(java.lang.String,java.lang.String)
+javax.imageio.spi.ImageReaderSpi#STANDARD_INPUT_TYPE
+javax.imageio.spi.ImageWriterSpi#STANDARD_OUTPUT_TYPE
+javax.jws.HandlerChain#name()
+javax.jws.soap.InitParam
+javax.jws.soap.SOAPMessageHandler
+javax.jws.soap.SOAPMessageHandlers
+javax.lang.model.util.AbstractAnnotationValueVisitor6
+javax.lang.model.util.AbstractElementVisitor6
+javax.lang.model.util.AbstractTypeVisitor6
+javax.lang.model.util.ElementKindVisitor6
+javax.lang.model.util.ElementScanner6
+javax.lang.model.util.SimpleAnnotationValueVisitor6
+javax.lang.model.util.SimpleElementVisitor6
+javax.lang.model.util.SimpleTypeVisitor6
+javax.lang.model.util.TypeKindVisitor6
+javax.management.AttributeValueExp#()
+javax.management.AttributeValueExp#setMBeanServer(javax.management.MBeanServer)
+javax.management.DefaultLoaderRepository
+javax.management.MBeanServer#deserialize(java.lang.String,byte[])
+javax.management.MBeanServer#deserialize(java.lang.String,javax.management.ObjectName,byte[])
+javax.management.MBeanServer#deserialize(javax.management.ObjectName,byte[])
+javax.management.StringValueExp#setMBeanServer(javax.management.MBeanServer)
+javax.management.ValueExp#setMBeanServer(javax.management.MBeanServer)
+javax.management.loading.DefaultLoaderRepository
+javax.management.monitor.CounterMonitor#getDerivedGauge()
+javax.management.monitor.CounterMonitor#getDerivedGaugeTimeStamp()
+javax.management.monitor.CounterMonitor#getThreshold()
+javax.management.monitor.CounterMonitor#setThreshold(java.lang.Number)
+javax.management.monitor.CounterMonitorMBean#getDerivedGauge()
+javax.management.monitor.CounterMonitorMBean#getDerivedGaugeTimeStamp()
+javax.management.monitor.CounterMonitorMBean#getThreshold()
+javax.management.monitor.CounterMonitorMBean#setThreshold(java.lang.Number)
+javax.management.monitor.GaugeMonitor#getDerivedGauge()
+javax.management.monitor.GaugeMonitor#getDerivedGaugeTimeStamp()
+javax.management.monitor.GaugeMonitorMBean#getDerivedGauge()
+javax.management.monitor.GaugeMonitorMBean#getDerivedGaugeTimeStamp()
+javax.management.monitor.Monitor#alreadyNotified
+javax.management.monitor.Monitor#dbgTag
+javax.management.monitor.Monitor#getObservedObject()
+javax.management.monitor.Monitor#setObservedObject(javax.management.ObjectName)
+javax.management.monitor.MonitorMBean#getObservedObject()
+javax.management.monitor.MonitorMBean#setObservedObject(javax.management.ObjectName)
+javax.management.monitor.StringMonitor#getDerivedGauge()
+javax.management.monitor.StringMonitor#getDerivedGaugeTimeStamp()
+javax.management.monitor.StringMonitorMBean#getDerivedGauge()
+javax.management.monitor.StringMonitorMBean#getDerivedGaugeTimeStamp()
+javax.management.openmbean.OpenType#ALLOWED_CLASSNAMES
+javax.naming.Context#APPLET
+javax.security.auth.Policy
+javax.sql.rowset.BaseRowSet#setUnicodeStream(int,java.io.InputStream,int)
+javax.sql.rowset.CachedRowSet#COMMIT_ON_ACCEPT_CHANGES
+javax.swing.AbstractButton#getLabel()
+javax.swing.AbstractButton#setLabel(java.lang.String)
+javax.swing.FocusManager#disableSwingFocusManager()
+javax.swing.FocusManager#isFocusManagerEnabled()
+javax.swing.ImageIcon#component
+javax.swing.ImageIcon#tracker
+javax.swing.JComponent#disable()
+javax.swing.JComponent#enable()
+javax.swing.JComponent#getNextFocusableComponent()
+javax.swing.JComponent#hide()
+javax.swing.JComponent#isManagingFocus()
+javax.swing.JComponent#requestDefaultFocus()
+javax.swing.JComponent#reshape(int,int,int,int)
+javax.swing.JComponent#setNextFocusableComponent(java.awt.Component)
+javax.swing.JComponent$AccessibleJComponent#accessibleFocusHandler
+javax.swing.JInternalFrame#getMenuBar()
+javax.swing.JInternalFrame#setMenuBar(javax.swing.JMenuBar)
+javax.swing.JList#getSelectedValues()
+javax.swing.JMenuBar#getComponentAtIndex(int)
+javax.swing.JPasswordField#getText()
+javax.swing.JPasswordField#getText(int,int)
+javax.swing.JPopupMenu#getComponentAtIndex(int)
+javax.swing.JRootPane#defaultPressAction
+javax.swing.JRootPane#defaultReleaseAction
+javax.swing.JRootPane#getMenuBar()
+javax.swing.JRootPane#setMenuBar(javax.swing.JMenuBar)
+javax.swing.JTable#createScrollPaneForTable(javax.swing.JTable)
+javax.swing.JTable#sizeColumnsToFit(boolean)
+javax.swing.JViewport#backingStore
+javax.swing.JViewport#isBackingStoreEnabled()
+javax.swing.JViewport#setBackingStoreEnabled(boolean)
+javax.swing.KeyStroke#getKeyStroke(char,boolean)
+javax.swing.ScrollPaneLayout#getViewportBorderBounds(javax.swing.JScrollPane)
+javax.swing.SwingUtilities#findFocusOwner(java.awt.Component)
+javax.swing.plaf.basic.BasicDesktopPaneUI#closeKey
+javax.swing.plaf.basic.BasicDesktopPaneUI#maximizeKey
+javax.swing.plaf.basic.BasicDesktopPaneUI#minimizeKey
+javax.swing.plaf.basic.BasicDesktopPaneUI#navigateKey
+javax.swing.plaf.basic.BasicDesktopPaneUI#navigateKey2
+javax.swing.plaf.basic.BasicInternalFrameUI#openMenuKey
+javax.swing.plaf.basic.BasicSplitPaneUI#createKeyboardDownRightListener()
+javax.swing.plaf.basic.BasicSplitPaneUI#createKeyboardEndListener()
+javax.swing.plaf.basic.BasicSplitPaneUI#createKeyboardHomeListener()
+javax.swing.plaf.basic.BasicSplitPaneUI#createKeyboardResizeToggleListener()
+javax.swing.plaf.basic.BasicSplitPaneUI#createKeyboardUpLeftListener()
+javax.swing.plaf.basic.BasicSplitPaneUI#dividerResizeToggleKey
+javax.swing.plaf.basic.BasicSplitPaneUI#downKey
+javax.swing.plaf.basic.BasicSplitPaneUI#endKey
+javax.swing.plaf.basic.BasicSplitPaneUI#getDividerBorderSize()
+javax.swing.plaf.basic.BasicSplitPaneUI#homeKey
+javax.swing.plaf.basic.BasicSplitPaneUI#keyboardDownRightListener
+javax.swing.plaf.basic.BasicSplitPaneUI#keyboardEndListener
+javax.swing.plaf.basic.BasicSplitPaneUI#keyboardHomeListener
+javax.swing.plaf.basic.BasicSplitPaneUI#keyboardResizeToggleListener
+javax.swing.plaf.basic.BasicSplitPaneUI#keyboardUpLeftListener
+javax.swing.plaf.basic.BasicSplitPaneUI#leftKey
+javax.swing.plaf.basic.BasicSplitPaneUI#rightKey
+javax.swing.plaf.basic.BasicSplitPaneUI#upKey
+javax.swing.plaf.basic.BasicTabbedPaneUI#downKey
+javax.swing.plaf.basic.BasicTabbedPaneUI#leftKey
+javax.swing.plaf.basic.BasicTabbedPaneUI#rightKey
+javax.swing.plaf.basic.BasicTabbedPaneUI#upKey
+javax.swing.plaf.basic.BasicToolBarUI#downKey
+javax.swing.plaf.basic.BasicToolBarUI#leftKey
+javax.swing.plaf.basic.BasicToolBarUI#rightKey
+javax.swing.plaf.basic.BasicToolBarUI#upKey
+javax.swing.plaf.metal.MetalComboBoxUI#editablePropertyChanged(java.beans.PropertyChangeEvent)
+javax.swing.plaf.metal.MetalComboBoxUI#removeListeners()
+javax.swing.plaf.metal.MetalComboBoxUI$MetalComboPopup
+javax.swing.plaf.metal.MetalScrollPaneUI#uninstallListeners(javax.swing.JScrollPane)
+javax.swing.table.TableColumn#disableResizedPosting()
+javax.swing.table.TableColumn#enableResizedPosting()
+javax.swing.table.TableColumn#resizedPostingDisableCount
+javax.swing.text.DefaultTextUI
+javax.swing.text.LabelView#getFontMetrics()
+javax.swing.text.TableView#createTableCell(javax.swing.text.Element)
+javax.swing.text.TableView$TableCell
+javax.swing.text.View#modelToView(int,java.awt.Shape)
+javax.swing.text.View#viewToModel(float,float,java.awt.Shape)
+javax.swing.text.html.FormView#RESET
+javax.swing.text.html.FormView#SUBMIT
+javax.swing.text.html.HTMLEditorKit$InsertHTMLTextAction#insertAtBoundry(javax.swing.JEditorPane,javax.swing.text.html.HTMLDocument,int,javax.swing.text.Element,java.lang.String,javax.swing.text.html.HTML$Tag,javax.swing.text.html.HTML$Tag)
+javax.swing.tree.DefaultTreeSelectionModel#notifyPathChange(java.util.Vector,javax.swing.tree.TreePath)
+javax.xml.bind.JAXBContext#createValidator()
+javax.xml.bind.Unmarshaller#isValidating()
+javax.xml.bind.Unmarshaller#setValidating(boolean)
+javax.xml.bind.Validator
+javax.xml.soap.SOAPElementFactory
+javax.xml.stream.XMLEventFactory#newInstance(java.lang.String,java.lang.ClassLoader)
+javax.xml.stream.XMLInputFactory#newInstance(java.lang.String,java.lang.ClassLoader)
+javax.xml.stream.XMLOutputFactory#newInstance(java.lang.String,java.lang.ClassLoader)
+org.omg.CORBA.Any#extract_Principal()
+org.omg.CORBA.Any#insert_Principal(org.omg.CORBA.Principal)
+org.omg.CORBA.DynAny
+org.omg.CORBA.DynArray
+org.omg.CORBA.DynEnum
+org.omg.CORBA.DynFixed
+org.omg.CORBA.DynSequence
+org.omg.CORBA.DynStruct
+org.omg.CORBA.DynUnion
+org.omg.CORBA.DynValue
+org.omg.CORBA.DynamicImplementation
+org.omg.CORBA.ORB#create_basic_dyn_any(org.omg.CORBA.TypeCode)
+org.omg.CORBA.ORB#create_dyn_any(org.omg.CORBA.Any)
+org.omg.CORBA.ORB#create_dyn_array(org.omg.CORBA.TypeCode)
+org.omg.CORBA.ORB#create_dyn_enum(org.omg.CORBA.TypeCode)
+org.omg.CORBA.ORB#create_dyn_sequence(org.omg.CORBA.TypeCode)
+org.omg.CORBA.ORB#create_dyn_struct(org.omg.CORBA.TypeCode)
+org.omg.CORBA.ORB#create_dyn_union(org.omg.CORBA.TypeCode)
+org.omg.CORBA.ORB#create_recursive_sequence_tc(int,int)
+org.omg.CORBA.ORB#get_current()
+org.omg.CORBA.Principal
+org.omg.CORBA.PrincipalHolder
+org.omg.CORBA.ServerRequest#except(org.omg.CORBA.Any)
+org.omg.CORBA.ServerRequest#op_name()
+org.omg.CORBA.ServerRequest#params(org.omg.CORBA.NVList)
+org.omg.CORBA.ServerRequest#result(org.omg.CORBA.Any)
+org.omg.CORBA.TCKind#(int)
+org.omg.CORBA.portable.InputStream#read_Principal()
+org.omg.CORBA.portable.OutputStream#write_Principal(org.omg.CORBA.Principal)
+org.xml.sax.AttributeList
+org.xml.sax.DocumentHandler
+org.xml.sax.HandlerBase
+org.xml.sax.Parser
+org.xml.sax.helpers.AttributeListImpl
+org.xml.sax.helpers.ParserFactory
diff --git a/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-unsafe-1.9.txt b/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-unsafe-1.9.txt
new file mode 100644
index 00000000..4e92fa7c
--- /dev/null
+++ b/src/main/resources/de/thetaphi/forbiddenapis/signatures/jdk-unsafe-1.9.txt
@@ -0,0 +1,19 @@
+# (C) Copyright Uwe Schindler (Generics Policeman) and others.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# These methods and classes should not be used by server classes (unsafe, no charset, no locale,...):
+
+# We only include 1.9 for now.
+# TODO: Scan Java 9 API for additional locale/charset/... violations!
+@includeBundled jdk-unsafe-1.8
diff --git a/src/tools/groovy/generate-deprecated-java5.groovy b/src/tools/groovy/generate-deprecated-java5.groovy
new file mode 100644
index 00000000..924f0a33
--- /dev/null
+++ b/src/tools/groovy/generate-deprecated-java5.groovy
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright Uwe Schindler (Generics Policeman) and others.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import de.thetaphi.forbiddenapis.DeprecatedGen;
+
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+new DeprecatedGen(properties['build.java.runtime'], new File(System.getProperty("java.home"), "lib/rt.jar"), properties['deprecated.output.file'] as File) {
+ @Override
+ protected void collectClasses(File source) throws IOException {
+ new ZipInputStream(new FileInputStream(source)).withStream {
+ ZipEntry entry;
+ while ((entry = it.getNextEntry()) != null) {
+ try {
+ if (entry.isDirectory()) continue;
+ if (entry.getName().endsWith(".class")) {
+ parseClass(it);
+ }
+ } finally {
+ it.closeEntry();
+ }
+ }
+ }
+ }
+}.run();
diff --git a/src/tools/groovy/generate-deprecated-java9.groovy b/src/tools/groovy/generate-deprecated-java9.groovy
new file mode 100644
index 00000000..2797a101
--- /dev/null
+++ b/src/tools/groovy/generate-deprecated-java9.groovy
@@ -0,0 +1,49 @@
+/*
+ * (C) Copyright Uwe Schindler (Generics Policeman) and others.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import de.thetaphi.forbiddenapis.DeprecatedGen;
+
+import java.nio.file.Files;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.PathMatcher;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+
+new DeprecatedGen(properties['build.java.runtime'], URI.create("jrt:/"), properties['deprecated.output.file'] as File) {
+ @Override
+ protected void collectClasses(URI uri) throws IOException {
+ Path modules = Paths.get(uri);
+ PathMatcher fileMatcher = modules.getFileSystem().getPathMatcher("glob:*.class"),
+ prefixMatcher = modules.getFileSystem().getPathMatcher("glob:/java.**");
+ Files.walkFileTree(modules, new SimpleFileVisitor() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+ if (fileMatcher.matches(file.getFileName())) {
+ // System.out.println(file);
+ Files.newInputStream(file).withStream { parseClass(it) };
+ }
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+ return (dir.getNameCount() == 0 || prefixMatcher.matches(dir)) ? FileVisitResult.CONTINUE : FileVisitResult.SKIP_SUBTREE;
+ }
+ });
+ }
+}.run();
diff --git a/src/tools/groovy/generate-deprecated.groovy b/src/tools/groovy/generate-deprecated.groovy
new file mode 100644
index 00000000..6fc6c3f2
--- /dev/null
+++ b/src/tools/groovy/generate-deprecated.groovy
@@ -0,0 +1,34 @@
+/*
+ * (C) Copyright Uwe Schindler (Generics Policeman) and others.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.tools.ant.BuildException;
+
+URL objectClassURL = ClassLoader.getSystemClassLoader().getResource("java/lang/Object.class");
+boolean isJava9 = objectClassURL != null && "jrt".equalsIgnoreCase(objectClassURL.getProtocol());
+
+boolean hasRTJar = new File(properties['java.home'], "lib/rt.jar").isFile();
+
+String vendor = properties['java.vendor'].toLowerCase(Locale.ENGLISH);
+boolean isOracle = vendor.contains("oracle") || vendor.contains("sun microsystems");
+boolean isDetectedJavaVersion = properties['java.version'].startsWith(properties['build.java.runtime']);
+
+if (isOracle && isDetectedJavaVersion && (isJava9 || hasRTJar)) {
+ String script = isJava9 ? "generate-deprecated-java9.groovy" : "generate-deprecated-java5.groovy";
+ evaluate(new File(properties['groovy-tools.dir'], script));
+} else {
+ throw new BuildException("Regenerating the deprecated signatures files need stock Oracle/Sun JDK, "+
+ "but your Java version or operating system is unsupported: " + properties['build.java.info']);
+}
\ No newline at end of file
diff --git a/src/tools/java/de/thetaphi/forbiddenapis/DeprecatedGen.java b/src/tools/java/de/thetaphi/forbiddenapis/DeprecatedGen.java
index 716f51e9..abb6f924 100644
--- a/src/tools/java/de/thetaphi/forbiddenapis/DeprecatedGen.java
+++ b/src/tools/java/de/thetaphi/forbiddenapis/DeprecatedGen.java
@@ -16,6 +16,17 @@
* limitations under the License.
*/
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.util.Locale;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
@@ -23,33 +34,26 @@
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
-import java.io.IOException;
-import java.io.BufferedWriter;
-import java.io.OutputStreamWriter;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-public class DeprecatedGen implements Opcodes {
+/** Lists all classes in Java runtime, scans them for deprecated signatures and writes them to a signatures file. */
+public abstract class DeprecatedGen implements Opcodes {
final static String NL = System.getProperty("line.separator", "\n");
final SortedSet deprecated = new TreeSet();
final String javaVersion, header;
- DeprecatedGen(String javaVersion) {
+ private final Input source;
+ private final File output;
+
+ public DeprecatedGen(String javaVersion, Input source, File output) {
this.javaVersion = javaVersion;
+ this.source = source;
+ this.output = output;
if (!System.getProperty("java.version").startsWith(javaVersion))
throw new IllegalArgumentException("Java version mismatch: build " + System.getProperty("java.version") + " != expected " + javaVersion);
this.header = new StringBuilder()
- .append("# This file contains API signatures extracted from the rt.jar file").append(NL)
- .append("# shipped with the class library of Oracle's Java Runtime Environment.").append(NL)
- .append("# It is provided here for reference, but can easily regenerated by executing:").append(NL)
- .append("# $ java ").append(DeprecatedGen.class.getName()).append(' ').append(javaVersion).append(" /path/to/rt.jar /path/to/this/file.txt").append(NL)
+ .append("# This file contains API signatures extracted from the rt.jar file shipped with the class library of Oracle's Java Runtime Environment.").append(NL)
+ .append("# It is provided here for reference, but can easily regenerated by executing from the source folder of forbidden-apis:").append(NL)
+ .append("# $ ant generate-deprecated").append(NL)
.append(NL)
.append("# This file contains all public, deprecated API signatures in Java version ").append(javaVersion)
.append(" (extracted from build ").append(System.getProperty("java.version")).append(").").append(NL)
@@ -65,10 +69,17 @@ protected boolean isDeprecated(int access) {
}
protected boolean isInternalClass(String className) {
- return className.startsWith("sun.") || className.startsWith("com.sun.") || className.startsWith("com.oracle.") || className.startsWith("jdk.") || className.startsWith("sunw.");
+ return className.startsWith("sun.") || className.startsWith("com.sun.") || className.startsWith("com.oracle.") || className.startsWith("jdk.") || className.startsWith("sunw.") || className.startsWith("oracle.");
}
- void checkClass(final ClassReader reader) {
+ protected void parseClass(InputStream in) throws IOException {
+ final ClassReader reader;
+ try {
+ reader = new ClassReader(in);
+ } catch (IllegalArgumentException iae) {
+ // unfortunately the ASM IAE has no message, so add good info!
+ throw new IllegalArgumentException("The class file format of your runtime seems to be too recent to be parsed by ASM (may need to be upgraded).");
+ }
final String className = Type.getObjectType(reader.getClassName()).getClassName();
// exclude internal classes like Unsafe,... and non-public classes!
// Note: reader.getAccess() does no indicate if class is deprecated, as this is a special
@@ -114,30 +125,7 @@ public FieldVisitor visitField(final int access, final String name, final String
}, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
}
- void parseRT(InputStream in) throws IOException {
- final ZipInputStream zip = new ZipInputStream(in);
- ZipEntry entry;
- while ((entry = zip.getNextEntry()) != null) {
- try {
- if (entry.isDirectory()) continue;
- if (entry.getName().endsWith(".class")) {
- final ClassReader classReader;
- try {
- classReader = new ClassReader(zip);
- } catch (IllegalArgumentException iae) {
- // unfortunately the ASM IAE has no message, so add good info!
- throw new IllegalArgumentException("The class file format of your rt.jar seems to be too recent to be parsed by ASM (may need to be upgraded).");
- }
- checkClass(classReader);
- }
- } finally {
- zip.closeEntry();
- }
- }
- }
-
- @SuppressForbidden
- void writeOutput(OutputStream out) throws IOException {
+ protected void writeOutput(OutputStream out) throws IOException {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
writer.write(header);
for (final String s : deprecated) {
@@ -145,28 +133,21 @@ void writeOutput(OutputStream out) throws IOException {
writer.newLine();
}
writer.flush();
- System.err.println("Deprecated API signatures for Java version " + javaVersion + " written successfully.");
}
-
+
+ protected abstract void collectClasses(Input source) throws IOException;
+
@SuppressForbidden
- public static void main(String... args) throws Exception {
- if (args.length != 3) {
- System.err.println("Invalid parameters; must be: java_version /path/to/rt.jar /path/to/outputfile.txt");
- System.exit(1);
- }
- System.err.println("Reading '" + args[1] + "' and extracting deprecated APIs to signature file '" + args[2]+ "'...");
- final InputStream in = new FileInputStream(args[1]);
- try {
- final DeprecatedGen parser = new DeprecatedGen(args[0]);
- parser.parseRT(in);
- final FileOutputStream out = new FileOutputStream(args[2]);
- try {
- parser.writeOutput(out);
- } finally {
- out.close();
- }
+ public void run() throws IOException {
+ System.err.println(String.format(Locale.ENGLISH, "Reading '%s' and extracting deprecated APIs to signatures file '%s'...", source, output));
+ collectClasses(source);
+ final FileOutputStream out = new FileOutputStream(output);
+ try {
+ writeOutput(out);
} finally {
- in.close();
+ out.close();
}
+ System.err.println("Deprecated API signatures for Java version " + javaVersion + " written successfully.");
}
+
}