LUCENE-4570: Use the Policeman Forbidden API checker, released separately from Lucene and downloaded via Ivy

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1442507 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Uwe Schindler 2013-02-05 09:15:35 +00:00
parent 9705a9d0de
commit ec8e1b9cdd
18 changed files with 50 additions and 1156 deletions

View File

@ -137,6 +137,9 @@ Build
* LUCENE-4636: Upgrade ivy to 2.3.0 (Shawn Heisey via Robert Muir)
* LUCENE-4570: Use the Policeman Formbidden API checker, released separately
from Lucene and downloaded via Ivy. (Uwe Schindler, Robert Muir)
======================= Lucene 4.1.0 =======================
Changes in backwards compatibility policy

View File

@ -157,28 +157,34 @@
<license-check-macro dir="${basedir}" licensedir="${common.dir}/licenses" />
</target>
<target name="check-forbidden-apis" depends="compile-tools,compile-test,load-custom-tasks,-check-forbidden-jdk-apis,-check-forbidden-test-apis,-check-system-out" description="Check forbidden API calls in compiled class files"/>
<target name="check-forbidden-apis" depends="compile-tools,compile-test,install-forbidden-apis,-forbidden-apis-classpath,-check-forbidden-jdk-apis,-check-forbidden-test-apis,-check-system-out" description="Check forbidden API calls in compiled class files"/>
<!-- TODO: Make the forbidden API checks per module! -->
<target name="-forbidden-apis-classpath">
<path id="forbidden-apis.classpath">
<fileset dir="${basedir}" includes="**/lib/*.jar"/>
<dirset dir="${basedir}/build" includes="**/classes/*"/>
</path>
</target>
<target name="-check-forbidden-jdk-apis">
<forbidden-apis>
<apiFileSet dir="${custom-tasks.dir}/forbiddenApis">
<include name="jdk.txt" />
<include name="jdk-deprecated.txt" />
<include name="executors.txt" />
</apiFileSet>
<forbidden-apis internalRuntimeForbidden="true" classpathref="forbidden-apis.classpath">
<bundledSignatures name="jdk-unsafe-${javac.target}"/>
<bundledSignatures name="jdk-deprecated-${javac.target}"/>
<signaturesFileSet file="${common.dir}/tools/forbiddenApis/executors.txt"/>
<fileset dir="${basedir}/build" includes="**/*.class" />
</forbidden-apis>
</target>
<target name="-check-forbidden-test-apis">
<forbidden-apis apiFile="${custom-tasks.dir}/forbiddenApis/tests.txt">
<forbidden-apis signaturesFile="${common.dir}/tools/forbiddenApis/tests.txt" classpathref="forbidden-apis.classpath">
<classpath refid="junit-path"/>
<fileset dir="${basedir}/build" includes="**/classes/test/**/*.class,test-framework/**/*.class" />
</forbidden-apis>
</target>
<target name="-check-system-out">
<forbidden-apis apiFile="${custom-tasks.dir}/forbiddenApis/system-out.txt">
<forbidden-apis bundledSignatures="jdk-system-out" classpathref="forbidden-apis.classpath">
<fileset dir="${basedir}/build">
<include name="**/classes/java/**/*.class"/>
<!-- this is basically tests -->

View File

@ -1902,6 +1902,14 @@ ${tests-output}/junit4-*.suites - per-JVM executed suites
<property name="groovy.loaded" value="true"/>
</target>
<!-- Forbidden API Task -->
<target name="install-forbidden-apis" unless="forbidden-apis.loaded" depends="ivy-availability-check,ivy-configure">
<ivy:cachepath organisation="de.thetaphi" module="forbiddenapis" revision="1.0"
inline="true" conf="default" transitive="true" pathid="forbidden-apis.classpath"/>
<taskdef name="forbidden-apis" classname="de.thetaphi.forbiddenapis.AntTask" classpathref="forbidden-apis.classpath"/>
<property name="forbidden-apis.loaded" value="true"/>
</target>
<!-- PEGDOWN macro: Before using depend on the target "resolve-pegdown" -->
<target name="resolve-pegdown" unless="pegdown.loaded" depends="ivy-availability-check,ivy-configure">

View File

@ -1 +0,0 @@
dd6ba5c392d4102458494e29f54f70ac534ec2a2

View File

@ -1,29 +0,0 @@
Copyright (c) 2000-2011 INRIA, France Telecom
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,2 +0,0 @@
ASM - Lightweight Java Bytecode Manipulation Framework
Copyright © 1999-2012, OW2 Consortium

View File

@ -25,7 +25,6 @@
<import file="../common-build.xml"/>
<path id="classpath">
<fileset dir="lib"/>
</path>
<!--

View File

@ -10,7 +10,6 @@
<taskdef resource="lucene-solr.antlib.xml">
<classpath>
<pathelement location="${custom-tasks.dir}/../build/tools/classes/java" />
<fileset dir="${custom-tasks.dir}/lib" includes="asm-debug-all-4.1.jar" />
</classpath>
</taskdef>
<property name="custom-tasks.loaded" value="true"/>

View File

@ -1,35 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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 from commons-io should not be used by Solr classes (unsafe, no charset,...):
org.apache.commons.io.IOUtils#copy(java.io.InputStream,java.io.Writer)
org.apache.commons.io.IOUtils#copy(java.io.Reader,java.io.OutputStream)
org.apache.commons.io.IOUtils#readLines(java.io.InputStream)
org.apache.commons.io.IOUtils#toByteArray(java.io.Reader)
org.apache.commons.io.IOUtils#toByteArray(java.lang.String)
org.apache.commons.io.IOUtils#toCharArray(java.io.InputStream)
org.apache.commons.io.IOUtils#toInputStream(java.lang.CharSequence)
org.apache.commons.io.IOUtils#toInputStream(java.lang.String)
org.apache.commons.io.IOUtils#toString(byte[])
org.apache.commons.io.IOUtils#toString(java.io.InputStream)
org.apache.commons.io.IOUtils#toString(java.net.URI)
org.apache.commons.io.IOUtils#toString(java.net.URL)
org.apache.commons.io.IOUtils#write(byte[],java.io.Writer)
org.apache.commons.io.IOUtils#write(char[],java.io.OutputStream)
org.apache.commons.io.IOUtils#write(java.lang.CharSequence,java.io.OutputStream)
org.apache.commons.io.IOUtils#write(java.lang.StringBuffer,java.io.OutputStream)
org.apache.commons.io.IOUtils#write(java.lang.String,java.io.OutputStream)
org.apache.commons.io.IOUtils#writeLines(java.util.Collection,java.lang.String,java.io.OutputStream)

View File

@ -1,441 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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 are all deprecated in jdk 6: make them fail the build (java[x].* only)
# http://docs.oracle.com/javase/6/docs/api/deprecated-list.html
# TODO: would be great to find a simple way to autogen this
java.security.Certificate
java.rmi.server.LoaderHandler
java.rmi.registry.RegistryHandler
java.rmi.server.RemoteCall
java.rmi.server.Skeleton
javax.xml.bind.Validator
javax.accessibility.AccessibleResourceBundle
javax.management.DefaultLoaderRepository
javax.management.loading.DefaultLoaderRepository
javax.swing.text.DefaultTextUI
java.security.Identity
java.security.IdentityScope
java.io.LineNumberInputStream
java.rmi.server.LogStream
javax.swing.plaf.metal.MetalComboBoxUI$MetalComboPopup
java.rmi.server.Operation
javax.security.auth.Policy
java.security.Signer
javax.xml.soap.SOAPElementFactory
java.io.StringBufferInputStream
javax.swing.text.TableView$TableCell
java.rmi.RMISecurityException
java.rmi.ServerRuntimeException
java.rmi.server.SkeletonMismatchException
java.rmi.server.SkeletonNotFoundException
javax.jws.soap.InitParam
javax.jws.soap.SOAPMessageHandler
javax.jws.soap.SOAPMessageHandlers
javax.management.openmbean.OpenType#ALLOWED_CLASSNAMES
javax.management.monitor.Monitor#alreadyNotified
javax.swing.JViewport#backingStore
javax.swing.plaf.basic.BasicDesktopPaneUI#closeKey
java.awt.Frame#CROSSHAIR_CURSOR
javax.management.monitor.Monitor#dbgTag
java.awt.Frame#DEFAULT_CURSOR
javax.swing.JRootPane#defaultPressAction
javax.swing.JRootPane#defaultReleaseAction
javax.swing.plaf.basic.BasicSplitPaneUI#dividerResizeToggleKey
javax.swing.plaf.basic.BasicToolBarUI#downKey
javax.swing.plaf.basic.BasicTabbedPaneUI#downKey
javax.swing.plaf.basic.BasicSplitPaneUI#downKey
java.awt.Frame#E_RESIZE_CURSOR
javax.swing.plaf.basic.BasicSplitPaneUI#endKey
java.util.logging.Logger#global
java.awt.Frame#HAND_CURSOR
javax.swing.plaf.basic.BasicSplitPaneUI#homeKey
java.net.HttpURLConnection#HTTP_SERVER_ERROR
java.lang.SecurityManager#inCheck
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.BasicToolBarUI#leftKey
javax.swing.plaf.basic.BasicTabbedPaneUI#leftKey
javax.swing.plaf.basic.BasicSplitPaneUI#leftKey
javax.swing.plaf.basic.BasicDesktopPaneUI#maximizeKey
javax.swing.plaf.basic.BasicDesktopPaneUI#minimizeKey
java.awt.Frame#MOVE_CURSOR
java.awt.Frame#N_RESIZE_CURSOR
javax.swing.plaf.basic.BasicDesktopPaneUI#navigateKey
javax.swing.plaf.basic.BasicDesktopPaneUI#navigateKey2
java.awt.Frame#NE_RESIZE_CURSOR
java.awt.Frame#NW_RESIZE_CURSOR
javax.swing.plaf.basic.BasicInternalFrameUI#openMenuKey
java.awt.datatransfer.DataFlavor#plainTextFlavor
javax.swing.text.html.FormView#RESET
javax.swing.table.TableColumn#resizedPostingDisableCount
javax.swing.plaf.basic.BasicToolBarUI#rightKey
javax.swing.plaf.basic.BasicTabbedPaneUI#rightKey
javax.swing.plaf.basic.BasicSplitPaneUI#rightKey
java.awt.Frame#S_RESIZE_CURSOR
java.awt.Frame#SE_RESIZE_CURSOR
javax.swing.text.html.FormView#SUBMIT
java.lang.Character$UnicodeBlock#SURROGATES_AREA
java.awt.Frame#SW_RESIZE_CURSOR
java.awt.Frame#TEXT_CURSOR
javax.swing.plaf.basic.BasicToolBarUI#upKey
javax.swing.plaf.basic.BasicTabbedPaneUI#upKey
javax.swing.plaf.basic.BasicSplitPaneUI#upKey
java.awt.Frame#W_RESIZE_CURSOR
java.awt.Frame#WAIT_CURSOR
java.awt.Component#action(java.awt.Event,java.lang.Object)
java.awt.List#addItem(java.lang.String)
java.awt.List#addItem(java.lang.String,int)
java.awt.CardLayout#addLayoutComponent(java.lang.String,java.awt.Component)
java.awt.BorderLayout#addLayoutComponent(java.lang.String,java.awt.Component)
java.awt.List#allowsMultipleSelections()
java.lang.ThreadGroup#allowThreadSuspension(boolean)
java.awt.TextArea#appendText(java.lang.String)
java.awt.Window#applyResourceBundle(java.util.ResourceBundle)
java.awt.Window#applyResourceBundle(java.lang.String)
java.awt.Component#bounds()
java.lang.SecurityManager#checkMulticast(java.net.InetAddress,byte)
java.lang.SecurityManager#classDepth(java.lang.String)
java.lang.SecurityManager#classLoaderDepth()
java.awt.List#clear()
java.awt.image.renderable.RenderContext#concetenateTransform(java.awt.geom.AffineTransform)
java.awt.Container#countComponents()
java.awt.Menu#countItems()
java.awt.Choice#countItems()
java.awt.List#countItems()
java.awt.MenuBar#countMenus()
java.lang.Thread#countStackFrames()
javax.xml.soap.SOAPElementFactory#create(javax.xml.soap.Name)
javax.xml.soap.SOAPElementFactory#create(java.lang.String)
javax.xml.soap.SOAPElementFactory#create(java.lang.String,java.lang.String,java.lang.String)
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.JTable#createScrollPaneForTable(javax.swing.JTable)
javax.swing.text.TableView#createTableCell(javax.swing.text.Element)
javax.xml.bind.JAXBContext#createValidator()
java.lang.SecurityManager#currentClassLoader()
java.lang.SecurityManager#currentLoadedClass()
java.net.URLDecoder#decode(java.lang.String)
java.lang.ClassLoader#defineClass(byte[],int,int)
java.awt.List#delItem(int)
java.awt.List#delItems(int,int)
java.awt.Container#deliverEvent(java.awt.Event)
java.awt.Component#deliverEvent(java.awt.Event)
javax.management.MBeanServer#deserialize(javax.management.ObjectName,byte[])
javax.management.MBeanServer#deserialize(java.lang.String,byte[])
javax.management.MBeanServer#deserialize(java.lang.String,javax.management.ObjectName,byte[])
java.lang.Thread#destroy()
java.awt.MenuItem#disable()
java.awt.Component#disable()
javax.swing.JComponent#disable()
javax.swing.table.TableColumn#disableResizedPosting()
javax.swing.FocusManager#disableSwingFocusManager()
java.rmi.server.Skeleton#dispatch(java.rmi.Remote,java.rmi.server.RemoteCall,int,long)
java.rmi.server.RemoteCall#done()
java.rmi.server.RemoteRef#done(java.rmi.server.RemoteCall)
javax.swing.plaf.metal.MetalComboBoxUI#editablePropertyChanged(java.beans.PropertyChangeEvent)
java.awt.MenuItem#enable()
java.awt.Component#enable()
javax.swing.JComponent#enable()
java.awt.MenuItem#enable(boolean)
java.awt.Component#enable(boolean)
javax.swing.table.TableColumn#enableResizedPosting()
java.net.URLEncoder#encode(java.lang.String)
java.security.SignatureSpi#engineGetParameter(java.lang.String)
java.security.SignatureSpi#engineSetParameter(java.lang.String,java.lang.Object)
java.awt.datatransfer.DataFlavor#equals(java.lang.String)
java.rmi.server.RemoteCall#executeCall()
javax.swing.SwingUtilities#findFocusOwner(java.awt.Component)
java.security.Security#getAlgorithmProperty(java.lang.String,java.lang.String)
java.sql.CallableStatement#getBigDecimal(int,int)
java.sql.ResultSet#getBigDecimal(int,int)
java.sql.ResultSet#getBigDecimal(java.lang.String,int)
java.awt.Polygon#getBoundingBox()
java.lang.String#getBytes(int,int,byte[],int)
java.awt.Graphics#getClipRect()
javax.swing.JPopupMenu#getComponentAtIndex(int)
javax.swing.JMenuBar#getComponentAtIndex(int)
java.awt.CheckboxGroup#getCurrent()
java.awt.Frame#getCursorType()
java.sql.Time#getDate()
java.util.Date#getDate()
java.sql.Time#getDay()
java.util.Date#getDay()
java.net.URLConnection#getDefaultRequestProperty(java.lang.String)
java.rmi.server.LogStream#getDefaultStream()
javax.management.monitor.StringMonitorMBean#getDerivedGauge()
javax.management.monitor.StringMonitor#getDerivedGauge()
javax.management.monitor.GaugeMonitorMBean#getDerivedGauge()
javax.management.monitor.GaugeMonitor#getDerivedGauge()
javax.management.monitor.CounterMonitorMBean#getDerivedGauge()
javax.management.monitor.CounterMonitor#getDerivedGauge()
javax.management.monitor.StringMonitorMBean#getDerivedGaugeTimeStamp()
javax.management.monitor.StringMonitor#getDerivedGaugeTimeStamp()
javax.management.monitor.GaugeMonitorMBean#getDerivedGaugeTimeStamp()
javax.management.monitor.GaugeMonitor#getDerivedGaugeTimeStamp()
javax.management.monitor.CounterMonitorMBean#getDerivedGaugeTimeStamp()
javax.management.monitor.CounterMonitor#getDerivedGaugeTimeStamp()
javax.swing.plaf.basic.BasicSplitPaneUI#getDividerBorderSize()
javax.xml.bind.Validator#getEventHandler()
java.awt.Toolkit#getFontList()
javax.swing.text.LabelView#getFontMetrics()
java.awt.Toolkit#getFontMetrics(java.awt.Font)
java.awt.Toolkit#getFontPeer(java.lang.String,int)
java.sql.Date#getHours()
java.util.Date#getHours()
java.lang.SecurityManager#getInCheck()
java.rmi.server.RemoteCall#getInputStream()
javax.swing.KeyStroke#getKeyStroke(char,boolean)
javax.swing.AbstractButton#getLabel()
java.awt.Scrollbar#getLineIncrement()
java.lang.Runtime#getLocalizedInputStream(java.io.InputStream)
java.lang.Runtime#getLocalizedOutputStream(java.io.OutputStream)
java.sql.DriverManager#getLogStream()
java.awt.FontMetrics#getMaxDecent()
javax.swing.JInternalFrame#getMenuBar()
javax.swing.JRootPane#getMenuBar()
java.sql.Date#getMinutes()
java.util.Date#getMinutes()
java.sql.Time#getMonth()
java.util.Date#getMonth()
javax.swing.JComponent#getNextFocusableComponent()
javax.management.monitor.MonitorMBean#getObservedObject()
javax.management.monitor.Monitor#getObservedObject()
java.rmi.server.Operation#getOperation()
java.rmi.server.Skeleton#getOperations()
java.awt.ComponentOrientation#getOrientation(java.util.ResourceBundle)
java.rmi.server.LogStream#getOutputStream()
java.rmi.server.RemoteCall#getOutputStream()
java.awt.Scrollbar#getPageIncrement()
java.security.Signature#getParameter(java.lang.String)
java.awt.MenuComponent#getPeer()
java.awt.Component#getPeer()
java.awt.Font#getPeer()
javax.xml.bind.Validator#getProperty(java.lang.String)
java.rmi.server.RemoteCall#getResultStream(boolean)
java.sql.Date#getSeconds()
java.util.Date#getSeconds()
java.rmi.server.LoaderHandler#getSecurityContext(java.lang.ClassLoader)
java.rmi.server.RMIClassLoader#getSecurityContext(java.lang.ClassLoader)
javax.swing.JPasswordField#getText()
javax.swing.JPasswordField#getText(int,int)
javax.management.monitor.CounterMonitorMBean#getThreshold()
javax.management.monitor.CounterMonitor#getThreshold()
java.util.Date#getTimezoneOffset()
java.net.MulticastSocket#getTTL()
java.net.DatagramSocketImpl#getTTL()
java.sql.ResultSet#getUnicodeStream(int)
java.sql.ResultSet#getUnicodeStream(java.lang.String)
javax.swing.ScrollPaneLayout#getViewportBorderBounds(javax.swing.JScrollPane)
java.awt.Scrollbar#getVisible()
java.sql.Time#getYear()
java.util.Date#getYear()
java.awt.Component#gotFocus(java.awt.Event,java.lang.Object)
java.awt.Component#handleEvent(java.awt.Event)
java.awt.Dialog#hide()
java.awt.Window#hide()
java.awt.Component#hide()
java.lang.SecurityManager#inClass(java.lang.String)
java.lang.SecurityManager#inClassLoader()
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)
java.awt.TextArea#insertText(java.lang.String,int)
java.awt.Container#insets()
java.awt.Rectangle#inside(int,int)
java.awt.Component#inside(int,int)
java.awt.Polygon#inside(int,int)
java.rmi.server.RemoteRef#invoke(java.rmi.server.RemoteCall)
javax.swing.JViewport#isBackingStoreEnabled()
javax.swing.FocusManager#isFocusManagerEnabled()
java.awt.Component#isFocusTraversable()
java.lang.Character#isJavaLetter(char)
java.lang.Character#isJavaLetterOrDigit(char)
javax.swing.JComponent#isManagingFocus()
java.awt.List#isSelected(int)
java.lang.Character#isSpace(char)
java.rmi.dgc.VMID#isUnique()
javax.xml.bind.Unmarshaller#isValidating()
java.awt.Component#keyDown(java.awt.Event,int)
java.awt.Component#keyUp(java.awt.Event,int)
java.awt.Container#layout()
java.awt.ScrollPane#layout()
java.awt.Component#layout()
java.rmi.server.LoaderHandler#loadClass(java.lang.String)
java.rmi.server.RMIClassLoader#loadClass(java.lang.String)
java.rmi.server.LoaderHandler#loadClass(java.net.URL,java.lang.String)
java.awt.Container#locate(int,int)
java.awt.Component#locate(int,int)
java.awt.Component#location()
java.rmi.server.LogStream#log(java.lang.String)
java.awt.Component#lostFocus(java.awt.Event,java.lang.Object)
java.awt.TextArea#minimumSize()
java.awt.Container#minimumSize()
java.awt.List#minimumSize()
java.awt.TextField#minimumSize()
java.awt.Component#minimumSize()
java.awt.List#minimumSize(int)
java.awt.TextField#minimumSize(int)
java.awt.TextArea#minimumSize(int,int)
javax.swing.text.View#modelToView(int,java.awt.Shape)
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.Rectangle#move(int,int)
java.awt.Component#move(int,int)
java.rmi.server.RemoteRef#newCall(java.rmi.server.RemoteObject,java.rmi.server.Operation[],int,long)
javax.xml.stream.XMLOutputFactory#newInstance(java.lang.String,java.lang.ClassLoader)
javax.xml.stream.XMLInputFactory#newInstance(java.lang.String,java.lang.ClassLoader)
javax.xml.stream.XMLEventFactory#newInstance(java.lang.String,java.lang.ClassLoader)
java.awt.Component#nextFocus()
java.awt.datatransfer.DataFlavor#normalizeMimeType(java.lang.String)
javax.activation.ActivationDataFlavor#normalizeMimeType(java.lang.String)
java.awt.datatransfer.DataFlavor#normalizeMimeTypeParameter(java.lang.String,java.lang.String)
javax.activation.ActivationDataFlavor#normalizeMimeTypeParameter(java.lang.String,java.lang.String)
java.util.Date#parse(java.lang.String)
java.rmi.server.LogStream#parseLevel(java.lang.String)
java.awt.MenuComponent#postEvent(java.awt.Event)
java.awt.Window#postEvent(java.awt.Event)
java.awt.Component#postEvent(java.awt.Event)
java.awt.MenuContainer#postEvent(java.awt.Event)
java.awt.image.renderable.RenderContext#preConcetenateTransform(java.awt.geom.AffineTransform)
java.awt.TextArea#preferredSize()
java.awt.Container#preferredSize()
java.awt.List#preferredSize()
java.awt.TextField#preferredSize()
java.awt.Component#preferredSize()
java.awt.List#preferredSize(int)
java.awt.TextField#preferredSize(int)
java.awt.TextArea#preferredSize(int,int)
java.io.DataInputStream#readLine()
java.io.ObjectInputStream#readLine()
java.rmi.registry.RegistryHandler#registryImpl(int)
java.rmi.registry.RegistryHandler#registryStub(java.lang.String,int)
java.rmi.server.RemoteCall#releaseInputStream()
java.rmi.server.RemoteCall#releaseOutputStream()
javax.swing.plaf.metal.MetalComboBoxUI#removeListeners()
java.awt.TextArea#replaceText(java.lang.String,int,int)
javax.swing.JComponent#requestDefaultFocus()
java.awt.Window#reshape(int,int,int,int)
java.awt.Rectangle#reshape(int,int,int,int)
java.awt.Component#reshape(int,int,int,int)
javax.swing.JComponent#reshape(int,int,int,int)
java.awt.Component#resize(java.awt.Dimension)
java.awt.Rectangle#resize(int,int)
java.awt.Component#resize(int,int)
java.lang.Thread#resume()
java.lang.ThreadGroup#resume()
java.lang.System#runFinalizersOnExit(boolean)
java.lang.Runtime#runFinalizersOnExit(boolean)
java.util.Properties#save(java.io.OutputStream,java.lang.String)
java.net.MulticastSocket#send(java.net.DatagramPacket,byte)
javax.swing.JViewport#setBackingStoreEnabled(boolean)
java.awt.CheckboxGroup#setCurrent(java.awt.Checkbox)
java.awt.Frame#setCursor(int)
java.sql.Time#setDate(int)
java.util.Date#setDate(int)
java.net.URLConnection#setDefaultRequestProperty(java.lang.String,java.lang.String)
java.rmi.server.LogStream#setDefaultStream(java.io.PrintStream)
java.awt.TextField#setEchoCharacter(char)
javax.xml.bind.Validator#setEventHandler(javax.xml.bind.ValidationEventHandler)
java.sql.Date#setHours(int)
java.util.Date#setHours(int)
javax.swing.AbstractButton#setLabel(java.lang.String)
java.awt.Scrollbar#setLineIncrement(int)
java.sql.DriverManager#setLogStream(java.io.PrintStream)
javax.management.ValueExp#setMBeanServer(javax.management.MBeanServer)
javax.swing.JInternalFrame#setMenuBar(javax.swing.JMenuBar)
javax.swing.JRootPane#setMenuBar(javax.swing.JMenuBar)
java.sql.Date#setMinutes(int)
java.util.Date#setMinutes(int)
java.awt.event.KeyEvent#setModifiers(int)
java.sql.Time#setMonth(int)
java.util.Date#setMonth(int)
java.awt.List#setMultipleSelections(boolean)
javax.swing.JComponent#setNextFocusableComponent(java.awt.Component)
javax.management.monitor.MonitorMBean#setObservedObject(javax.management.ObjectName)
javax.management.monitor.Monitor#setObservedObject(javax.management.ObjectName)
java.rmi.server.LogStream#setOutputStream(java.io.OutputStream)
java.awt.Scrollbar#setPageIncrement(int)
java.security.Signature#setParameter(java.lang.String,java.lang.Object)
javax.xml.bind.Validator#setProperty(java.lang.String,java.lang.Object)
java.rmi.server.RemoteStub#setRef(java.rmi.server.RemoteStub,java.rmi.server.RemoteRef)
java.sql.Date#setSeconds(int)
java.util.Date#setSeconds(int)
javax.management.monitor.CounterMonitorMBean#setThreshold(java.lang.Number)
javax.management.monitor.CounterMonitor#setThreshold(java.lang.Number)
java.net.MulticastSocket#setTTL(byte)
java.net.DatagramSocketImpl#setTTL(byte)
java.sql.PreparedStatement#setUnicodeStream(int,java.io.InputStream,int)
javax.sql.rowset.BaseRowSet#setUnicodeStream(int,java.io.InputStream,int)
java.net.URLStreamHandler#setURL(java.net.URL,java.lang.String,java.lang.String,int,java.lang.String,java.lang.String)
javax.xml.bind.Unmarshaller#setValidating(boolean)
java.sql.Time#setYear(int)
java.util.Date#setYear(int)
java.awt.Dialog#show()
java.awt.Window#show()
java.awt.Component#show()
java.awt.Component#show(boolean)
java.awt.Component#size()
javax.swing.JTable#sizeColumnsToFit(boolean)
java.lang.Thread#stop()
java.lang.ThreadGroup#stop()
java.lang.Thread#stop(java.lang.Throwable)
java.lang.Thread#suspend()
java.lang.ThreadGroup#suspend()
java.util.Date#toGMTString()
java.util.Date#toLocaleString()
java.rmi.server.LogStream#toString()
java.rmi.server.Operation#toString()
java.io.ByteArrayOutputStream#toString(int)
java.util.Date#UTC(int,int,int,int,int,int)
javax.xml.bind.Validator#validate(java.lang.Object)
javax.xml.bind.Validator#validateRoot(java.lang.Object)
javax.swing.text.View#viewToModel(float,float,java.awt.Shape)
java.rmi.server.LogStream#write(byte[],int,int)
java.rmi.server.LogStream#write(int)
java.io.ObjectOutputStream$PutField#write(java.io.ObjectOutput)
javax.management.AttributeValueExp#<init>()
java.sql.Date#<init>(int,int,int)
java.util.Date#<init>(int,int,int)
java.util.Date#<init>(int,int,int,int,int)
java.util.Date#<init>(int,int,int,int,int,int)
java.util.Date#<init>(java.lang.String)
java.awt.event.KeyEvent#<init>(java.awt.Component,int,long,int,int)
java.rmi.server.Operation#<init>(java.lang.String)
java.rmi.RMISecurityException#<init>(java.lang.String)
java.rmi.RMISecurityException#<init>(java.lang.String,java.lang.String)
java.rmi.ServerRuntimeException#<init>(java.lang.String,java.lang.Exception)
java.rmi.server.SkeletonMismatchException#<init>(java.lang.String)
java.net.Socket#<init>(java.net.InetAddress,int,boolean)
java.net.Socket#<init>(java.lang.String,int,boolean)
java.io.StreamTokenizer#<init>(java.io.InputStream)
java.lang.String#<init>(byte[],int)
java.lang.String#<init>(byte[],int,int,int)
java.sql.Time#<init>(int,int,int)
java.sql.Timestamp#<init>(int,int,int,int,int,int,int)

View File

@ -1,95 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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 Lucene classes (unsafe, no charset,...):
java.lang.String#<init>(byte[])
java.lang.String#<init>(byte[],int)
java.lang.String#<init>(byte[],int,int)
java.lang.String#<init>(byte[],int,int,int)
java.lang.String#getBytes()
java.lang.String#getBytes(int,int,byte[],int)
java.lang.String#toLowerCase()
java.lang.String#toUpperCase()
java.lang.String#format(java.lang.String,java.lang.Object[])
java.io.FileReader
java.io.FileWriter
java.io.ByteArrayOutputStream#toString()
java.io.InputStreamReader#<init>(java.io.InputStream)
java.io.OutputStreamWriter#<init>(java.io.OutputStream)
java.io.PrintStream#<init>(java.io.File)
java.io.PrintStream#<init>(java.io.OutputStream)
java.io.PrintStream#<init>(java.io.OutputStream,boolean)
java.io.PrintStream#<init>(java.lang.String)
java.io.PrintWriter#<init>(java.io.File)
java.io.PrintWriter#<init>(java.io.OutputStream)
java.io.PrintWriter#<init>(java.io.OutputStream,boolean)
java.io.PrintWriter#<init>(java.lang.String)
java.io.PrintWriter#format(java.lang.String,java.lang.Object[])
java.io.PrintWriter#printf(java.lang.String,java.lang.Object[])
java.nio.charset.Charset#displayName()
java.text.BreakIterator#getCharacterInstance()
java.text.BreakIterator#getLineInstance()
java.text.BreakIterator#getSentenceInstance()
java.text.BreakIterator#getWordInstance()
java.text.Collator#getInstance()
java.text.DateFormat#getTimeInstance()
java.text.DateFormat#getTimeInstance(int)
java.text.DateFormat#getDateInstance()
java.text.DateFormat#getDateInstance(int)
java.text.DateFormat#getDateTimeInstance()
java.text.DateFormat#getDateTimeInstance(int,int)
java.text.DateFormat#getInstance()
java.text.DateFormatSymbols#<init>()
java.text.DateFormatSymbols#getInstance()
java.text.DecimalFormat#<init>()
java.text.DecimalFormat#<init>(java.lang.String)
java.text.DecimalFormatSymbols#<init>()
java.text.DecimalFormatSymbols#getInstance()
java.text.MessageFormat#<init>(java.lang.String)
java.text.NumberFormat#getInstance()
java.text.NumberFormat#getNumberInstance()
java.text.NumberFormat#getIntegerInstance()
java.text.NumberFormat#getCurrencyInstance()
java.text.NumberFormat#getPercentInstance()
java.text.SimpleDateFormat#<init>()
java.text.SimpleDateFormat#<init>(java.lang.String)
java.util.Calendar#<init>()
java.util.Calendar#getInstance()
java.util.Calendar#getInstance(java.util.Locale)
java.util.Calendar#getInstance(java.util.TimeZone)
java.util.Currency#getSymbol()
java.util.GregorianCalendar#<init>()
java.util.GregorianCalendar#<init>(int,int,int)
java.util.GregorianCalendar#<init>(int,int,int,int,int)
java.util.GregorianCalendar#<init>(int,int,int,int,int,int)
java.util.GregorianCalendar#<init>(java.util.Locale)
java.util.GregorianCalendar#<init>(java.util.TimeZone)
java.util.Scanner#<init>(java.io.InputStream)
java.util.Scanner#<init>(java.io.File)
java.util.Scanner#<init>(java.nio.channels.ReadableByteChannel)
java.util.Formatter#<init>()
java.util.Formatter#<init>(java.lang.Appendable)
java.util.Formatter#<init>(java.io.File)
java.util.Formatter#<init>(java.io.File,java.lang.String)
java.util.Formatter#<init>(java.io.OutputStream)
java.util.Formatter#<init>(java.io.OutputStream,java.lang.String)
java.util.Formatter#<init>(java.io.PrintStream)
java.util.Formatter#<init>(java.lang.String)
java.util.Formatter#<init>(java.lang.String,java.lang.String)

View File

@ -1,22 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
# Don't allow System.out/System.err usage in non-test Lucene code
java.lang.System#out
java.lang.System#err
java.lang.Thread#dumpStack()
# eclipse autogenerated stubs!
java.lang.Throwable#printStackTrace()

View File

@ -18,12 +18,4 @@
-->
<ivy-module version="2.0">
<info organisation="org.apache.lucene" module="core-tools"/>
<dependencies>
<!--
We use the asm-debug-all library, as the as-all has no generics.
It's not really debug, just not "stripped":
-->
<dependency org="org.ow2.asm" name="asm-debug-all" rev="4.1" transitive="false"/>
<exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/>
</dependencies>
</ivy-module>

View File

@ -18,7 +18,4 @@
<taskdef
name="licenses"
classname="org.apache.lucene.validation.LicenseCheckTask" />
<taskdef
name="forbidden-apis"
classname="org.apache.lucene.validation.ForbiddenApisCheckTask" />
</antlib>

View File

@ -1,498 +0,0 @@
package org.apache.lucene.validation;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.objectweb.asm.ClassReader;
import org.objectweb.asm.Label;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.ant.types.resources.Resources;
import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.ant.types.resources.StringResource;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.Reader;
import java.io.File;
import java.io.StringReader;
import java.util.Arrays;
import java.util.Collections;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.HashSet;
import java.util.Set;
/**
* Task to check if a set of class files contains calls to forbidden APIs
* from a given classpath and list of API signatures (either inline or as pointer to files).
* In contrast to other ANT tasks, this tool does only visit the given classpath
* and the system classloader. It uses the local classpath in preference to the system classpath
* (which violates the spec).
*/
public class ForbiddenApisCheckTask extends Task {
private final Resources classFiles = new Resources();
private final Resources apiSignatures = new Resources();
private Path classpath = null;
private boolean failOnUnsupportedJava = false;
ClassLoader loader = null;
final Map<String,ClassSignatureLookup> classesToCheck = new HashMap<String,ClassSignatureLookup>();
final Map<String,ClassSignatureLookup> classpathClassCache = new HashMap<String,ClassSignatureLookup>();
final Map<String,String> forbiddenFields = new HashMap<String,String>();
final Map<String,String> forbiddenMethods = new HashMap<String,String>();
final Map<String,String> forbiddenClasses = new HashMap<String,String>();
/** Reads a class (binary name) from the given {@link ClassLoader}. */
ClassSignatureLookup getClassFromClassLoader(final String clazz) throws BuildException {
ClassSignatureLookup c = classpathClassCache.get(clazz);
if (c == null) {
try {
final InputStream in = loader.getResourceAsStream(clazz.replace('.', '/') + ".class");
if (in == null) {
throw new BuildException("Loading of class " + clazz + " failed: Not found");
}
try {
classpathClassCache.put(clazz, c = new ClassSignatureLookup(new ClassReader(in)));
} finally {
in.close();
}
} catch (IOException ioe) {
throw new BuildException("Loading of class " + clazz + " failed.", ioe);
}
}
return c;
}
/** Adds the method signature to the list of disallowed methods. The Signature is checked against the given ClassLoader. */
private void addSignature(final String signature) throws BuildException {
final String clazz, field;
final Method method;
int p = signature.indexOf('#');
if (p >= 0) {
clazz = signature.substring(0, p);
final String s = signature.substring(p + 1);
p = s.indexOf('(');
if (p >= 0) {
if (p == 0) {
throw new BuildException("Invalid method signature (method name missing): " + signature);
}
// we ignore the return type, its just to match easier (so return type is void):
try {
method = Method.getMethod("void " + s, true);
} catch (IllegalArgumentException iae) {
throw new BuildException("Invalid method signature: " + signature);
}
field = null;
} else {
field = s;
method = null;
}
} else {
clazz = signature;
method = null;
field = null;
}
// check class & method/field signature, if it is really existent (in classpath), but we don't really load the class into JVM:
final ClassSignatureLookup c = getClassFromClassLoader(clazz);
if (method != null) {
assert field == null;
// list all methods with this signature:
boolean found = false;
for (final Method m : c.methods) {
if (m.getName().equals(method.getName()) && Arrays.equals(m.getArgumentTypes(), method.getArgumentTypes())) {
found = true;
forbiddenMethods.put(c.reader.getClassName() + '\000' + m, signature);
// don't break when found, as there may be more covariant overrides!
}
}
if (!found) {
throw new BuildException("No method found with following signature: " + signature);
}
} else if (field != null) {
assert method == null;
if (!c.fields.contains(field)) {
throw new BuildException("No field found with following name: " + signature);
}
forbiddenFields.put(c.reader.getClassName() + '\000' + field, signature);
} else {
assert field == null && method == null;
// only add the signature as class name
forbiddenClasses.put(c.reader.getClassName(), signature);
}
}
/** Reads a list of API signatures. Closes the Reader when done (on Exception, too)! */
private void parseApiFile(Reader reader) throws IOException {
final BufferedReader r = new BufferedReader(reader);
try {
String line;
while ((line = r.readLine()) != null) {
line = line.trim();
if (line.length() == 0 || line.startsWith("#"))
continue;
addSignature(line);
}
} finally {
r.close();
}
}
/** Parses a class given as (FileSet) Resource */
private ClassReader loadClassFromResource(final Resource res) throws BuildException {
try {
final InputStream stream = res.getInputStream();
try {
return new ClassReader(stream);
} finally {
stream.close();
}
} catch (IOException ioe) {
throw new BuildException("IO problem while reading class file " + res, ioe);
}
}
/** Parses a class given as Resource and checks for valid method invocations */
private int checkClass(final ClassReader reader) {
final int[] violations = new int[1];
reader.accept(new ClassVisitor(Opcodes.ASM4) {
final String className = Type.getObjectType(reader.getClassName()).getClassName();
String source = null;
@Override
public void visitSource(String source, String debug) {
this.source = source;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
return new MethodVisitor(Opcodes.ASM4) {
private int lineNo = -1;
private ClassSignatureLookup lookupRelatedClass(String internalName) {
ClassSignatureLookup c = classesToCheck.get(internalName);
if (c == null) try {
c = getClassFromClassLoader(internalName);
} catch (BuildException be) {
// we ignore lookup errors and simply ignore this related class
c = null;
}
return c;
}
private boolean checkClassUse(String owner) {
final String printout = forbiddenClasses.get(owner);
if (printout != null) {
log("Forbidden class use: " + printout, Project.MSG_ERR);
return true;
}
return false;
}
private boolean checkMethodAccess(String owner, Method method) {
if (checkClassUse(owner)) {
return true;
}
final String printout = forbiddenMethods.get(owner + '\000' + method);
if (printout != null) {
log("Forbidden method invocation: " + printout, Project.MSG_ERR);
return true;
}
final ClassSignatureLookup c = lookupRelatedClass(owner);
if (c != null && !c.methods.contains(method)) {
final String superName = c.reader.getSuperName();
if (superName != null && checkMethodAccess(superName, method)) {
return true;
}
final String[] interfaces = c.reader.getInterfaces();
if (interfaces != null) {
for (String intf : interfaces) {
if (intf != null && checkMethodAccess(intf, method)) {
return true;
}
}
}
}
return false;
}
private boolean checkFieldAccess(String owner, String field) {
if (checkClassUse(owner)) {
return true;
}
final String printout = forbiddenFields.get(owner + '\000' + field);
if (printout != null) {
log("Forbidden field access: " + printout, Project.MSG_ERR);
return true;
}
final ClassSignatureLookup c = lookupRelatedClass(owner);
if (c != null && !c.fields.contains(field)) {
final String superName = c.reader.getSuperName();
if (superName != null && checkFieldAccess(superName, field)) {
return true;
}
final String[] interfaces = c.reader.getInterfaces();
if (interfaces != null) {
for (String intf : interfaces) {
if (intf != null && checkFieldAccess(intf, field)) {
return true;
}
}
}
}
return false;
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
if (checkMethodAccess(owner, new Method(name, desc))) {
violations[0]++;
reportSourceAndLine();
}
}
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
if (checkFieldAccess(owner, name)) {
violations[0]++;
reportSourceAndLine();
}
}
private void reportSourceAndLine() {
final StringBuilder sb = new StringBuilder(" in ").append(className);
if (source != null && lineNo >= 0) {
new Formatter(sb, Locale.ROOT).format(" (%s:%d)", source, lineNo).flush();
}
log(sb.toString(), Project.MSG_ERR);
}
@Override
public void visitLineNumber(int lineNo, Label start) {
this.lineNo = lineNo;
}
};
}
}, ClassReader.SKIP_FRAMES);
return violations[0];
}
@Override
public void execute() throws BuildException {
AntClassLoader antLoader = null;
try {
if (classpath != null) {
classpath.setProject(getProject());
this.loader = antLoader = getProject().createClassLoader(ClassLoader.getSystemClassLoader(), classpath);
// force that loading from this class loader is done first, then parent is asked.
// This violates spec, but prevents classes in any system classpath to be used if a local one is available:
antLoader.setParentFirst(false);
} else {
this.loader = ClassLoader.getSystemClassLoader();
}
classFiles.setProject(getProject());
apiSignatures.setProject(getProject());
final long start = System.currentTimeMillis();
// check if we can load runtime classes (e.g. java.lang.String).
// If this fails, we have a newer Java version than ASM supports:
try {
getClassFromClassLoader(String.class.getName());
} catch (IllegalArgumentException iae) {
final String msg = String.format(Locale.ROOT,
"Your Java version (%s) is not supported by <%s/>. Please run the checks with a supported JDK!",
System.getProperty("java.version"), getTaskName());
if (failOnUnsupportedJava) {
throw new BuildException(msg);
} else {
log("WARNING: " + msg, Project.MSG_WARN);
return;
}
}
try {
@SuppressWarnings("unchecked")
Iterator<Resource> iter = (Iterator<Resource>) apiSignatures.iterator();
if (!iter.hasNext()) {
throw new BuildException("You need to supply at least one API signature definition through apiFile=, <apiFileSet/>, or inner text.");
}
while (iter.hasNext()) {
final Resource r = iter.next();
if (!r.isExists()) {
throw new BuildException("Resource does not exist: " + r);
}
if (r instanceof StringResource) {
final String s = ((StringResource) r).getValue();
if (s != null && s.trim().length() > 0) {
log("Reading inline API signatures...", Project.MSG_INFO);
parseApiFile(new StringReader(s));
}
} else {
log("Reading API signatures: " + r, Project.MSG_INFO);
parseApiFile(new InputStreamReader(r.getInputStream(), "UTF-8"));
}
}
} catch (IOException ioe) {
throw new BuildException("IO problem while reading files with API signatures.", ioe);
}
if (forbiddenMethods.isEmpty() && forbiddenClasses.isEmpty()) {
throw new BuildException("No API signatures found; use apiFile=, <apiFileSet/>, or inner text to define those!");
}
log("Loading classes to check...", Project.MSG_INFO);
@SuppressWarnings("unchecked")
Iterator<Resource> iter = (Iterator<Resource>) classFiles.iterator();
if (!iter.hasNext()) {
throw new BuildException("There is no <fileset/> given or the fileset does not contain any class files to check.");
}
while (iter.hasNext()) {
final Resource r = iter.next();
if (!r.isExists()) {
throw new BuildException("Class file does not exist: " + r);
}
ClassReader reader = loadClassFromResource(r);
classesToCheck.put(reader.getClassName(), new ClassSignatureLookup(reader));
}
log("Scanning for API signatures and dependencies...", Project.MSG_INFO);
int errors = 0;
for (final ClassSignatureLookup c : classesToCheck.values()) {
errors += checkClass(c.reader);
}
log(String.format(Locale.ROOT,
"Scanned %d (and %d related) class file(s) for forbidden API invocations (in %.2fs), %d error(s).",
classesToCheck.size(), classpathClassCache.size(), (System.currentTimeMillis() - start) / 1000.0, errors),
errors > 0 ? Project.MSG_ERR : Project.MSG_INFO);
if (errors > 0) {
throw new BuildException("Check for forbidden API calls failed, see log.");
}
} finally {
this.loader = null;
if (antLoader != null) antLoader.cleanup();
antLoader = null;
classesToCheck.clear();
classpathClassCache.clear();
forbiddenFields.clear();
forbiddenMethods.clear();
forbiddenClasses.clear();
}
}
/** Set of class files to check */
public void add(ResourceCollection rc) {
classFiles.add(rc);
}
/** A file with API signatures apiFile= attribute */
public void setApiFile(File file) {
apiSignatures.add(new FileResource(getProject(), file));
}
/** Set of files with API signatures as <apiFileSet/> nested element */
public FileSet createApiFileSet() {
final FileSet fs = new FileSet();
fs.setProject(getProject());
apiSignatures.add(fs);
return fs;
}
/** Support for API signatures list as nested text */
public void addText(String text) {
apiSignatures.add(new StringResource(getProject(), text));
}
/** Classpath as classpath= attribute */
public void setClasspath(Path classpath) {
createClasspath().append(classpath);
}
/** Classpath as classpathRef= attribute */
public void setClasspathRef(Reference r) {
createClasspath().setRefid(r);
}
/** Classpath as <classpath/> nested element */
public Path createClasspath() {
if (this.classpath == null) {
this.classpath = new Path(getProject());
}
return this.classpath.createPath();
}
public void setFailOnUnsupportedJava(boolean failOnUnsupportedJava) {
this.failOnUnsupportedJava = failOnUnsupportedJava;
}
static final class ClassSignatureLookup {
public final ClassReader reader;
public final Set<Method> methods;
public final Set<String> fields;
public ClassSignatureLookup(final ClassReader reader) {
this.reader = reader;
final Set<Method> methods = new HashSet<Method>();
final Set<String> fields = new HashSet<String>();
reader.accept(new ClassVisitor(Opcodes.ASM4) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
final Method m = new Method(name, desc);
methods.add(m);
return null;
}
@Override
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
fields.add(name);
return null;
}
}, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
this.methods = Collections.unmodifiableSet(methods);
this.fields = Collections.unmodifiableSet(fields);
}
}
}

View File

@ -236,19 +236,29 @@
</license-check-macro>
</target>
<target name="check-forbidden-apis" depends="compile-tools,compile-test,load-custom-tasks,-check-forbidden-java-apis,-check-forbidden-test-apis"
<target name="check-forbidden-apis" depends="compile-tools,compile-test,install-forbidden-apis,-forbidden-apis-classpath,-check-forbidden-java-apis,-check-forbidden-test-apis"
description="Check forbidden API calls in compiled class files."/>
<!-- TODO: Make the forbidden API checks per module! Also remove failOnMissingClasses="false" below!!! -->
<target name="-forbidden-apis-classpath">
<path id="forbidden-apis.classpath">
<fileset dir="${basedir}" includes="**/lib/*.jar"/>
<dirset dir="${basedir}/build" includes="**/classes/*"/>
<path refid="solr.lucene.libs"/>
<path refid="classpath"/>
<path refid="test.classpath"/>
</path>
</target>
<target name="-check-forbidden-java-apis">
<forbidden-apis>
<classpath refid="additional.dependencies"/>
<apiFileSet dir="${custom-tasks.dir}/forbiddenApis">
<include name="jdk.txt" />
<include name="jdk-deprecated.txt" />
<include name="commons-io.txt" />
<forbidden-apis internalRuntimeForbidden="true" classpathref="forbidden-apis.classpath" failOnMissingClasses="false">
<bundledSignatures name="jdk-unsafe-${javac.target}"/>
<bundledSignatures name="jdk-deprecated-${javac.target}"/>
<bundledSignatures name="commons-io-unsafe-${commons-io.version}"/>
<signaturesFileSet dir="${common.dir}/tools/forbiddenApis">
<include name="executors.txt" />
<include name="servlet-api.txt" />
</apiFileSet>
</signaturesFileSet>
<fileset dir="${basedir}/build">
<include name="**/*.class" />
<!-- violates the servlet-api restrictions, but it is safe to do so in this test: -->
@ -258,8 +268,7 @@
</target>
<target name="-check-forbidden-test-apis">
<forbidden-apis apiFile="${custom-tasks.dir}/forbiddenApis/tests.txt">
<classpath refid="junit-path"/>
<forbidden-apis signaturesFile="${common.dir}/tools/forbiddenApis/tests.txt" classpathref="forbidden-apis.classpath" failOnMissingClasses="false">
<fileset dir="${basedir}/build">
<include name="**/classes/test/**/*.class"/>
<include name="solr-test-framework/**/*.class"/>

View File

@ -68,6 +68,10 @@
where X.Y.M is the last version released (on this branch).
-->
<property name="solr.spec.version" value="5.0.0.${dateversion}" />
<!-- defined here to be able to make the forbidden-api checker correctly
reference it. 'ivy.xml' is also referencing this property. -->
<property name="commons-io.version" value="2.1" />
<path id="solr.lucene.libs">
<!-- List of jars that will be used as the foundation for both

View File

@ -24,7 +24,7 @@
<dependency org="org.apache.httpcomponents" name="httpcore" rev="4.1.4" transitive="false"/>
<dependency org="org.apache.httpcomponents" name="httpclient" rev="4.1.3" transitive="false"/>
<dependency org="org.apache.httpcomponents" name="httpmime" rev="4.1.3" transitive="false"/>
<dependency org="commons-io" name="commons-io" rev="2.1" transitive="false"/>
<dependency org="commons-io" name="commons-io" rev="${commons-io.version}" transitive="false"/>
<dependency org="org.slf4j" name="jcl-over-slf4j" rev="1.6.4" transitive="false"/>
<dependency org="org.codehaus.woodstox" name="wstx-asl" rev="3.2.7" transitive="false"/>
<dependency org="org.slf4j" name="slf4j-api" rev="1.6.4" transitive="false"/>