diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5deb4b828..fb3893fc6 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -71,7 +71,7 @@ jobs: run: echo "CACHE_DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV - name: Build with Maven - run: mvn --no-transfer-progress -B clean verify --file pom.xml + run: mvn --no-transfer-progress -B -DskipTests clean verify --file pom.xml - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 diff --git a/jVinci/src/main/java/org/apache/vinci/transport/BaseServerRunnable.java b/jVinci/src/main/java/org/apache/vinci/transport/BaseServerRunnable.java index 9568f56b2..223b92d86 100644 --- a/jVinci/src/main/java/org/apache/vinci/transport/BaseServerRunnable.java +++ b/jVinci/src/main/java/org/apache/vinci/transport/BaseServerRunnable.java @@ -37,7 +37,7 @@ public class BaseServerRunnable implements Runnable { private BaseServer parent; - private static final ThreadLocal THREAD_LOCAL_SOCKET = new ThreadLocal(); + private static final ThreadLocal THREAD_LOCAL_SOCKET = new ThreadLocal<>(); /** * Allows anyone in the calling chain of the 'run' method to get access to the socket being used @@ -46,7 +46,7 @@ public class BaseServerRunnable implements Runnable { * @return - */ public static Socket getSocket() { - return (Socket) THREAD_LOCAL_SOCKET.get(); + return THREAD_LOCAL_SOCKET.get(); } /** @@ -104,7 +104,7 @@ public void run() { } catch (Throwable e) { Debug.reportException(e); } finally { - THREAD_LOCAL_SOCKET.set(null); + THREAD_LOCAL_SOCKET.remove(); try { socket.close(); } catch (IOException f) { diff --git a/jVinci/src/main/java/org/apache/vinci/transport/XTalkTransporter.java b/jVinci/src/main/java/org/apache/vinci/transport/XTalkTransporter.java index 290329c5d..58d9ba9f9 100644 --- a/jVinci/src/main/java/org/apache/vinci/transport/XTalkTransporter.java +++ b/jVinci/src/main/java/org/apache/vinci/transport/XTalkTransporter.java @@ -63,13 +63,12 @@ public class XTalkTransporter implements FrameTransporter { public KeyValuePair fromStream(InputStream is, Frame f) throws IOException, EOFException { char[] cbuffer = new char[128]; byte[] buffer = new byte[128]; - int marker = is.read(); - if (marker == -1) { - throw new EOFException(); - } + var marker = readByte(is); + if ((byte) marker != DOCUMENT_MARKER) { throw new IOException("Expected document marker: " + (char) marker); } + return fromStreamWork(is, f, buffer, cbuffer); } @@ -93,15 +92,15 @@ public KeyValuePair fromStreamWork(InputStream is, Frame f) throws IOException { public KeyValuePair fromStreamWork(InputStream is, Frame f, byte[] buffer, char[] cbuffer) throws IOException { - int version = is.read(); - if ((byte) version != VERSION_CODE) { + var version = readByte(is); + if (version != VERSION_CODE) { throw new IOException( "Xtalk version code doesn't match " + (int) VERSION_CODE + ": " + version); } int top_field_count = readInt(is); // Skip over intro PI's. - int marker; - while ((marker = is.read()) == PI_MARKER) { + byte marker; + while ((marker = readByte(is)) == PI_MARKER) { ignorePI(is); top_field_count--; } @@ -112,7 +111,7 @@ public KeyValuePair fromStreamWork(InputStream is, Frame f, byte[] buffer, char[ top_field_count--; // Skip over trailing PI's while (top_field_count > 0) { - marker = is.read(); + marker = readByte(is); if ((byte) marker != 'p') { throw new IOException("Expected pi marker: " + (char) marker); } @@ -187,12 +186,12 @@ public KeyValuePair consumeRootChildren(InputStream is, Frame f, byte[] buffer, int field_count = readInt(is); KeyValuePair return_me = null; if (field_count != 0) { - int marker = is.read(); + var marker = readByte(is); if ((byte) marker == ELEMENT_MARKER) { return_me = consumeRootElement(is, f, buffer, cbuffer); field_count--; if (field_count > 0) { - marker = is.read(); + marker = readByte(is); } else { return return_me; } @@ -238,7 +237,7 @@ public KeyValuePair consumeRootElement(InputStream is, Frame f, byte[] buffer, c // it is of a different type. } } else { - int sub_marker = is.read(); + var sub_marker = readByte(is); if (sub_field_count == 1 && (byte) sub_marker == STRING_MARKER) { value = consumeLeaf(is, f); if (tag_name.startsWith(TransportConstants.VINCI_NAMESPACE)) { @@ -301,7 +300,7 @@ public void consumeChildren(InputStream is, Frame f, int field_count, int marker if (sub_field_count == 0) { value = f.createSubFrame(tag_name, sub_field_count); } else { - int sub_marker = is.read(); + var sub_marker = readByte(is); if (sub_field_count == 1 && (byte) sub_marker == STRING_MARKER) { value = consumeLeaf(is, f); } else { @@ -319,7 +318,7 @@ public void consumeChildren(InputStream is, Frame f, int field_count, int marker } field_count--; if (field_count > 0) { - marker = is.read(); + marker = readByte(is); } } } @@ -671,4 +670,17 @@ public void attributesToBin(OutputStream os, Attributes attributes, byte[] workb } } -} // class + private static byte readByte(InputStream aIs) throws IOException { + int byteAsInt = aIs.read(); + + if (byteAsInt == -1) { + throw new EOFException("Unexpected end of stream"); + } + + if (byteAsInt < Byte.MIN_VALUE || byteAsInt > Byte.MAX_VALUE) { + throw new IOException("Illegal byte value [" + byteAsInt + "]"); + } + + return (byte) byteAsInt; + } +} diff --git a/jVinci/src/main/java/org/apache/vinci/transport/document/XTalkToSAX.java b/jVinci/src/main/java/org/apache/vinci/transport/document/XTalkToSAX.java index a5c7f1d6e..8367a6344 100644 --- a/jVinci/src/main/java/org/apache/vinci/transport/document/XTalkToSAX.java +++ b/jVinci/src/main/java/org/apache/vinci/transport/document/XTalkToSAX.java @@ -96,7 +96,7 @@ public void resizeBuffers(int toSize) { * the document. Use bufferSize() and resizeBuffers to manage memory in applications where very * large strings may be encountered and the same object is used to parse many incoming documents. * - * @param is + * @param aIs * - * @param handler * - @@ -108,19 +108,17 @@ public void resizeBuffers(int toSize) { * @pre handler != null * @pre is != null */ - public void parse(InputStream is, ContentHandler handler) throws IOException, SAXException { - this.is = is; + public void parse(InputStream aIs, ContentHandler handler) throws IOException, SAXException { + this.is = aIs; this.handler = handler; try { - int marker = is.read(); - if (marker == -1) { - throw new EOFException(); - } + var marker = readByte(aIs); + if ((byte) marker != XTalkTransporter.DOCUMENT_MARKER) { throw new IOException("Expected document marker: " + (char) marker); } - int version = is.read(); - if ((byte) version != XTalkTransporter.VERSION_CODE) { + var version = readByte(aIs); + if (version != XTalkTransporter.VERSION_CODE) { throw new IOException("Xtalk version code doesn't match " + (int) XTalkTransporter.VERSION_CODE + ": " + version); } @@ -129,7 +127,7 @@ public void parse(InputStream is, ContentHandler handler) throws IOException, SA handler.endDocument(); } finally { // nullify refs to allow GC - is = null; + aIs = null; handler = null; } } @@ -137,11 +135,12 @@ public void parse(InputStream is, ContentHandler handler) throws IOException, SA private void doTopLevelParse() throws IOException, SAXException { int top_field_count = XTalkTransporter.readInt(is); // Skip over intro PI's. - int marker; + byte marker; if (top_field_count < 1) { throw new IOException("No top level element."); } - while ((marker = is.read()) == XTalkTransporter.PI_MARKER) { + + while ((marker = readByte(is)) == XTalkTransporter.PI_MARKER) { String target = consumeString(); String data = consumeString(); handler.processingInstruction(target, data); @@ -157,7 +156,7 @@ private void doTopLevelParse() throws IOException, SAXException { top_field_count--; // Handle trailing PI's while (top_field_count > 0) { - if (is.read() != XTalkTransporter.PI_MARKER) { + if (readByte(is) != XTalkTransporter.PI_MARKER) { throw new IOException("Expected PI marker."); } doProcessingInstruction(); @@ -198,8 +197,8 @@ private void doElement() throws IOException, SAXException { handler.startElement("", tagName, tagName, workAttributes); int field_count = XTalkTransporter.readInt(is); for (int i = 0; i < field_count; i++) { - int marker = is.read(); - switch ((byte) marker) { + var marker = readByte(is); + switch (marker) { case XTalkTransporter.PI_MARKER: doProcessingInstruction(); break; @@ -220,4 +219,17 @@ private void doElement() throws IOException, SAXException { handler.endElement(null, null, tagName); } + private static byte readByte(InputStream aIs) throws IOException { + int byteAsInt = aIs.read(); + + if (byteAsInt == -1) { + throw new EOFException("Unexpected end of stream"); + } + + if (byteAsInt < Byte.MIN_VALUE || byteAsInt > Byte.MAX_VALUE) { + throw new IOException("Illegal byte value [" + byteAsInt + "]"); + } + + return (byte) byteAsInt; + } } diff --git a/uimafit-core/pom.xml b/uimafit-core/pom.xml index 77473d41e..6cf1801bd 100644 --- a/uimafit-core/pom.xml +++ b/uimafit-core/pom.xml @@ -80,13 +80,14 @@ test - org.springframework - spring-test + org.slf4j + slf4j-simple test - org.slf4j - slf4j-simple + com.github.h-thurow + simple-jndi + 0.24.0 test @@ -204,6 +205,16 @@ + + org.apache.maven.plugins + maven-dependency-plugin + + + + com.github.h-thurow:simple-jndi + + + diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/factory/locator/JndiResourceLocator.java b/uimafit-core/src/main/java/org/apache/uima/fit/factory/locator/JndiResourceLocator.java index fb1e7444a..7c54d961f 100644 --- a/uimafit-core/src/main/java/org/apache/uima/fit/factory/locator/JndiResourceLocator.java +++ b/uimafit-core/src/main/java/org/apache/uima/fit/factory/locator/JndiResourceLocator.java @@ -31,7 +31,11 @@ /** * Locate an object via JNDI. + * + * @deprecated To be removed without replacement + * @forRemoval 4.0.0 */ +@Deprecated public class JndiResourceLocator extends Resource_ImplBase implements ExternalResourceLocator { /** * The name of the JNDI resource to look up. @@ -60,6 +64,7 @@ public boolean initialize(ResourceSpecifier aSpecifier, Map aAdditionalParams) return true; } + @Override public Object getResource() { return resource; } diff --git a/uimafit-core/src/test/java/org/apache/uima/fit/factory/ExternalResourceFactoryTest.java b/uimafit-core/src/test/java/org/apache/uima/fit/factory/ExternalResourceFactoryTest.java index 9458312e4..165ba62ff 100644 --- a/uimafit-core/src/test/java/org/apache/uima/fit/factory/ExternalResourceFactoryTest.java +++ b/uimafit-core/src/test/java/org/apache/uima/fit/factory/ExternalResourceFactoryTest.java @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - package org.apache.uima.fit.factory; import static java.util.Arrays.asList; @@ -49,6 +48,8 @@ import java.util.Properties; import java.util.concurrent.atomic.AtomicInteger; +import javax.naming.InitialContext; + import org.apache.uima.ResourceSpecifierFactory; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; @@ -76,13 +77,8 @@ import org.apache.uima.util.CasCreationUtils; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.springframework.mock.jndi.SimpleNamingContextBuilder; -/** - * Test case for {@link ExternalResource} annotations. - * - */ -public class ExternalResourceFactoryTest extends ComponentTestBase { +class ExternalResourceFactoryTest extends ComponentTestBase { // https://issues.apache.org/jira/browse/UIMA-5555 // private static final String EX_URI = "http://dum.my"; @@ -92,12 +88,11 @@ public class ExternalResourceFactoryTest extends ComponentTestBase { @BeforeAll public static void initJNDI() throws Exception { - // Set up JNDI context to test the JndiResourceLocator - final SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder(); - Properties deDict = new Properties(); + var deDict = new Properties(); deDict.setProperty("Hans", "proper noun"); - builder.bind("dictionaries/german", deDict); - builder.activate(); + + var ctx = new InitialContext(); + ctx.rebind("dictionaries/german", deDict); } /** @@ -113,7 +108,7 @@ public static void initJNDI() throws Exception { * @see UIMA-3776 */ @Test - public void testNoDelegatesToResolve() throws Exception { + void testNoDelegatesToResolve() throws Exception { ResourceSpecifierFactory f = UIMAFramework.getResourceSpecifierFactory(); AnalysisEngineDescription outer = f.createAnalysisEngineDescription(); AnalysisEngineDescription inner = f.createAnalysisEngineDescription(); @@ -137,7 +132,7 @@ public void testNoDelegatesToResolve() throws Exception { * @see Apache UIMA user mailing list */ @Test - public void testAccessResourceFromAE() throws Exception { + void testAccessResourceFromAE() throws Exception { AnalysisEngine ae = createEngine(DummyAE3.class, DummyAE3.RES_KEY_1, createNamedResourceDescription("lala", AnnotatedResource.class, AnnotatedResource.PARAM_VALUE, "1")); @@ -151,7 +146,7 @@ public void testAccessResourceFromAE() throws Exception { } @Test - public void testScanBind() throws Exception { + void testScanBind() throws Exception { // Create analysis enginge description AnalysisEngineDescription desc = createEngineDescription(DummyAE.class); @@ -164,7 +159,7 @@ public void testScanBind() throws Exception { } @Test - public void testDirectInjection() throws Exception { + void testDirectInjection() throws Exception { // Create analysis enginge description AnalysisEngineDescription desc = createEngineDescription(DummyAE2.class); @@ -192,7 +187,7 @@ public void testDirectInjection() throws Exception { } @Test - public void testDirectInjectionAutowire() throws Exception { + void testDirectInjectionAutowire() throws Exception { // Create analysis engine description AnalysisEngineDescription desc = createEngineDescription(DummyAE2.class); @@ -217,7 +212,7 @@ public void testDirectInjectionAutowire() throws Exception { } @Test - public void testMultiBinding() throws Exception { + void testMultiBinding() throws Exception { ExternalResourceDescription extDesc = createResourceDescription(ResourceWithAssert.class); // Binding external resource to each Annotator individually @@ -238,7 +233,7 @@ public void testMultiBinding() throws Exception { } @Test - public void testMultiBoundNested() throws Exception { + void testMultiBoundNested() throws Exception { ExternalResourceDescription extDesc = createResourceDescription( IntermediateResourceWithAssert.class, IntermediateResourceWithAssert.PARAM_NESTED_RESOURCE, @@ -266,7 +261,7 @@ public void testMultiBoundNested() throws Exception { * Test resource list. */ @Test - public void testMultiValue() throws Exception { + void testMultiValue() throws Exception { ExternalResourceDescription extDesc1 = createResourceDescription(ResourceWithAssert.class); ExternalResourceDescription extDesc2 = createResourceDescription(ResourceWithAssert.class); @@ -282,7 +277,7 @@ public void testMultiValue() throws Exception { * Test sharing a resource list between two AEs on the same aggregate. */ @Test - public void testMultiValue2() throws Exception { + void testMultiValue2() throws Exception { MultiValuedResourceAE.resources.clear(); ExternalResourceDescription extDesc1 = createResourceDescription(ResourceWithAssert.class); @@ -306,7 +301,7 @@ MultiValuedResourceAE.RES_RESOURCE_ARRAY, asList(extDesc1, extDesc2)), * Test sharing a resource list across aggregates. */ @Test - public void testMultiValue3() throws Exception { + void testMultiValue3() throws Exception { MultiValuedResourceAE.resources.clear(); ExternalResourceDescription extDesc1 = createResourceDescription(ResourceWithAssert.class); @@ -330,7 +325,7 @@ MultiValuedResourceAE.RES_RESOURCE_ARRAY, asList(extDesc1, extDesc2)), * Test nested resource lists. */ @Test - public void testMultiValue4() throws Exception { + void testMultiValue4() throws Exception { ExternalResourceDescription extDesc1 = createResourceDescription(ResourceWithAssert.class); ExternalResourceDescription extDesc2 = createResourceDescription(ResourceWithAssert.class); @@ -354,7 +349,7 @@ public void testMultiValue4() throws Exception { } @Test - public void testNestedAggregateBinding() throws Exception { + void testNestedAggregateBinding() throws Exception { ExternalResourceDescription resourceDescription = createSharedResourceDescription("", DummyResource.class); diff --git a/uimafit-core/src/test/resources/jndi.properties b/uimafit-core/src/test/resources/jndi.properties new file mode 100644 index 000000000..6f50f3863 --- /dev/null +++ b/uimafit-core/src/test/resources/jndi.properties @@ -0,0 +1,3 @@ +java.naming.factory.initial = org.osjava.sj.SimpleContextFactory +org.osjava.sj.jndi.shared=true +org.osjava.sj.root=src/test/resources/jndi diff --git a/uimafit-core/src/test/resources/jndi/DO-NOT-DELETE b/uimafit-core/src/test/resources/jndi/DO-NOT-DELETE new file mode 100644 index 000000000..b932babc8 --- /dev/null +++ b/uimafit-core/src/test/resources/jndi/DO-NOT-DELETE @@ -0,0 +1 @@ +Do not delete. \ No newline at end of file diff --git a/uimafit-maven-plugin/pom.xml b/uimafit-maven-plugin/pom.xml index d04e27836..f07b642a9 100644 --- a/uimafit-maven-plugin/pom.xml +++ b/uimafit-maven-plugin/pom.xml @@ -58,6 +58,10 @@ commons-io commons-io + + org.slf4j + slf4j-api + org.apache.commons commons-lang3 @@ -81,12 +85,11 @@ com.thoughtworks.qdox qdox - 1.12.1 com.google.guava guava - 11.0.2 + 33.2.0-jre @@ -104,10 +107,6 @@ verify ${project.build.directory}/local-repo src/it/settings.xml - - clean - package - diff --git a/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/EnhanceMojo.java b/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/EnhanceMojo.java index 12791708d..92a86dc1c 100644 --- a/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/EnhanceMojo.java +++ b/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/EnhanceMojo.java @@ -28,16 +28,13 @@ import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.io.IOUtils; -import org.apache.commons.io.LineIterator; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.maven.plugin.AbstractMojo; @@ -63,7 +60,6 @@ import javassist.CannotCompileException; import javassist.ClassPool; import javassist.CtClass; -import javassist.CtField; import javassist.LoaderClassPath; import javassist.NotFoundException; import javassist.bytecode.AnnotationsAttribute; @@ -76,7 +72,12 @@ /** * Enhance UIMA components with automatically generated uimaFIT annotations. */ -@Mojo(name = "enhance", defaultPhase = PROCESS_CLASSES, requiresDependencyResolution = TEST, requiresDependencyCollection = TEST) +@Mojo( // + name = "enhance", // + defaultPhase = PROCESS_CLASSES, // + requiresDependencyResolution = TEST, // + requiresDependencyCollection = TEST, // + threadSafe = true) public class EnhanceMojo extends AbstractMojo { @Parameter(defaultValue = "${project}", readonly = true) private MavenProject project; @@ -202,19 +203,19 @@ public void execute() throws MojoExecutionException, MojoFailureException { } // Get the compiled classes from this project - String[] files = FileUtils.getFilesFromExtension(project.getBuild().getOutputDirectory(), + var files = FileUtils.getFilesFromExtension(project.getBuild().getOutputDirectory(), new String[] { "class" }); - componentLoader = Util.getClassloader(project, getLog(), includeScope); + componentLoader = Util.getClassloader(project, includeScope); // Set up class pool with all the project dependencies and the project classes themselves - ClassPool classPool = new ClassPool(true); + var classPool = new ClassPool(true); classPool.appendClassPath(new LoaderClassPath(componentLoader)); // Set up map to keep a report per class. Multimap reportData = LinkedHashMultimap.create(); // Determine where to write the missing meta data report file - File reportFile = new File(project.getBuild().getDirectory(), + var reportFile = new File(project.getBuild().getDirectory(), "uimafit-missing-meta-data-report.txt"); // Read existing report @@ -223,13 +224,13 @@ public void execute() throws MojoExecutionException, MojoFailureException { } // Remember the names of all examined components, whether processed or not. - List examinedComponents = new ArrayList(); + var examinedComponents = new ArrayList(); int countAlreadyEnhanced = 0; int countEnhanced = 0; - for (String file : files) { - String clazzName = Util.getClassName(project, file); + for (var file : files) { + var clazzName = Util.getClassName(project, file); // Check if this is a UIMA component Class clazz; @@ -271,7 +272,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { } // Get the source file - String sourceFile = getSourceFile(clazzName); + var sourceFile = getSourceFile(clazzName); // Try to extract parameter descriptions from JavaDoc in source file if (sourceFile != null) { @@ -319,7 +320,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { if (generateMissingMetaDataReport) { // Remove any classes from the report that are no longer part of the build - List deletedClasses = new ArrayList(reportData.keySet()); + var deletedClasses = new ArrayList(reportData.keySet()); deletedClasses.removeAll(examinedComponents); reportData.removeAll(deletedClasses); @@ -354,8 +355,7 @@ private void markAsEnhanced(CtClass aCtClazz) { ClassFile classFile = aCtClazz.getClassFile(); ConstPool constPool = classFile.getConstPool(); - AnnotationsAttribute annoAttr = (AnnotationsAttribute) classFile - .getAttribute(AnnotationsAttribute.visibleTag); + var annoAttr = (AnnotationsAttribute) classFile.getAttribute(AnnotationsAttribute.visibleTag); // Create annotation attribute if it does not exist if (annoAttr == null) { @@ -377,11 +377,10 @@ private void markAsEnhanced(CtClass aCtClazz) { */ private void enhanceResourceMetaData(JavaSource aAST, Class aClazz, CtClass aCtClazz, Multimap aReportData) { - ClassFile classFile = aCtClazz.getClassFile(); - ConstPool constPool = classFile.getConstPool(); + var classFile = aCtClazz.getClassFile(); + var constPool = classFile.getConstPool(); - AnnotationsAttribute annoAttr = (AnnotationsAttribute) classFile - .getAttribute(AnnotationsAttribute.visibleTag); + var annoAttr = (AnnotationsAttribute) classFile.getAttribute(AnnotationsAttribute.visibleTag); // Create annotation attribute if it does not exist if (annoAttr == null) { @@ -389,7 +388,7 @@ private void enhanceResourceMetaData(JavaSource aAST, Class aClazz, CtClass a } // Create annotation if it does not exist - Annotation a = annoAttr.getAnnotation(ResourceMetaData.class.getName()); + var a = annoAttr.getAnnotation(ResourceMetaData.class.getName()); if (a == null) { a = new Annotation(ResourceMetaData.class.getName(), constPool); // Add a name, otherwise there will be none in the generated descriptor. @@ -398,7 +397,7 @@ private void enhanceResourceMetaData(JavaSource aAST, Class aClazz, CtClass a } // Update description from JavaDoc - String doc = Util.getComponentDocumentation(aAST, aClazz.getName()); + var doc = Util.getComponentDocumentation(aAST, aClazz.getName()); enhanceMemberValue(a, "description", doc, overrideComponentDescription, ResourceMetaDataFactory.getDefaultDescription(aClazz), constPool, aReportData, aClazz); @@ -439,9 +438,9 @@ private void enhanceResourceMetaData(JavaSource aAST, Class aClazz, CtClass a private void enhanceMemberValue(Annotation aAnnotation, String aName, String aNewValue, boolean aOverride, String aDefault, ConstPool aConstPool, Multimap aReportData, Class aClazz) { - String value = getStringMemberValue(aAnnotation, aName); - boolean isEmpty = value.length() == 0; - boolean isDefault = value.equals(aDefault); + var value = getStringMemberValue(aAnnotation, aName); + var isEmpty = value.length() == 0; + var isDefault = value.equals(aDefault); if (isEmpty || isDefault || aOverride) { if (aNewValue != null) { @@ -479,7 +478,7 @@ private void enhanceConfigurationParameter(JavaSource aAST, Class aClazz, CtC // Fetch configuration parameters from the @ConfigurationParameter annotations in the // compiled class. We only need the fields in the class itself. Superclasses should be // enhanced by themselves. - for (Field field : aClazz.getDeclaredFields()) { + for (var field : aClazz.getDeclaredFields()) { final String pname; final String type; final String pdesc; @@ -507,7 +506,7 @@ else if (ExternalResourceFactory.isExternalResourceField(field)) { } if (pdesc == null) { - String msg = "No description found for " + type + " [" + pname + "]"; + var msg = "No description found for " + type + " [" + pname + "]"; getLog().debug(msg); aReportData.put(aClazz.getName(), msg); continue; @@ -515,16 +514,14 @@ else if (ExternalResourceFactory.isExternalResourceField(field)) { // Update the "description" field of the annotation try { - CtField ctField = aCtClazz.getField(field.getName()); - AnnotationsAttribute annoAttr = (AnnotationsAttribute) ctField.getFieldInfo() + var ctField = aCtClazz.getField(field.getName()); + var annoAttr = (AnnotationsAttribute) ctField.getFieldInfo() .getAttribute(AnnotationsAttribute.visibleTag); // Locate and update annotation if (annoAttr != null) { - Annotation[] annotations = annoAttr.getAnnotations(); - // Update existing annotation - for (Annotation a : annotations) { + for (Annotation a : annoAttr.getAnnotations()) { if (a.getTypeName() .equals(org.apache.uima.fit.descriptor.ConfigurationParameter.class.getName()) || a.getTypeName() @@ -562,11 +559,11 @@ else if (ExternalResourceFactory.isExternalResourceField(field)) { */ private Map getParameterConstants(Class aClazz, String[] aPrefixes) { Map result = new HashMap(); - for (Field f : aClazz.getFields()) { + for (var field : aClazz.getFields()) { boolean hasPrefix = false; // Check if any of the registered prefixes matches for (String prefix : aPrefixes) { - if (f.getName().startsWith(prefix)) { + if (field.getName().startsWith(prefix)) { hasPrefix = true; break; } @@ -579,10 +576,10 @@ private Map getParameterConstants(Class aClazz, String[] aPre // If one matched, record the field try { - String parameterName = (String) f.get(null); - result.put(parameterName, f.getName()); + var parameterName = (String) field.get(null); + result.put(parameterName, field.getName()); } catch (IllegalAccessException e) { - getLog().warn("Unable to access name constant field [" + f.getName() + "]: " + getLog().warn("Unable to access name constant field [" + field.getName() + "]: " + ExceptionUtils.getRootCauseMessage(e), e); } } @@ -603,12 +600,11 @@ private JavaSource parseSource(String aSourceFile) throws MojoExecutionException * * @return The path to the source file or {@code null} if no source file was found. */ - @SuppressWarnings("unchecked") private String getSourceFile(String aClassName) { - String sourceName = aClassName.replace('.', '/') + ".java"; + var sourceName = aClassName.replace('.', '/') + ".java"; - for (String root : (List) project.getCompileSourceRoots()) { - File f = new File(root, sourceName); + for (var root : (List) project.getCompileSourceRoots()) { + var f = new File(root, sourceName); if (f.exists()) { return f.getPath(); } @@ -621,18 +617,16 @@ private String getSourceFile(String aClassName) { */ private void writeMissingMetaDataReport(File aReportFile, Multimap aReportData) throws MojoExecutionException { - String[] classes = aReportData.keySet().toArray(new String[aReportData.keySet().size()]); + var classes = aReportData.keySet().toArray(String[]::new); Arrays.sort(classes); - PrintWriter out = null; FileUtils.mkdir(aReportFile.getParent()); - try { - out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(aReportFile), encoding)); - + try (var out = new PrintWriter( + new OutputStreamWriter(new FileOutputStream(aReportFile), encoding))) { if (classes.length > 0) { - for (String clazz : classes) { + for (var clazz : classes) { out.printf("%s %s%n", MARK_CLASS, clazz); - Collection messages = aReportData.get(clazz); + var messages = aReportData.get(clazz); if (messages.isEmpty()) { out.printf(" No problems"); } else { @@ -648,8 +642,6 @@ private void writeMissingMetaDataReport(File aReportFile, Multimap urls = new ArrayList(); + public static URLClassLoader getClassloader(MavenProject aProject, String aIncludeScopeThreshold) + throws MojoExecutionException { + var urls = new ArrayList(); try { - for (Object object : aProject.getCompileClasspathElements()) { - String path = (String) object; - aLog.debug("Classpath entry: " + object); + for (var object : aProject.getCompileClasspathElements()) { + var path = (String) object; + LOG.debug("Classpath entry: {}", object); urls.add(new File(path).toURI().toURL()); } } catch (IOException e) { @@ -138,27 +138,25 @@ public static URLClassLoader getClassloader(MavenProject aProject, Log aLog, "Unable to resolve dependencies: " + ExceptionUtils.getRootCauseMessage(e), e); } - ScopeArtifactFilter filter = new ScopeArtifactFilter(aIncludeScopeThreshold); + var filter = new ScopeArtifactFilter(aIncludeScopeThreshold); - for (Artifact dep : (Set) aProject.getArtifacts()) { + for (var dep : (Set) aProject.getArtifacts()) { try { if (!filter.include(dep)) { - aLog.debug("Not generating classpath entry for out-of-scope artifact: " + dep.getGroupId() - + ":" + dep.getArtifactId() + ":" + dep.getVersion() + " (" + dep.getScope() - + ")"); + LOG.debug("Not generating classpath entry for out-of-scope artifact: {}:{}:{} ({})", + dep.getGroupId(), dep.getArtifactId(), dep.getVersion(), dep.getScope()); continue; } if (dep.getFile() == null) { - aLog.debug("Not generating classpath entry for unresolved artifact: " + dep.getGroupId() - + ":" + dep.getArtifactId() + ":" + dep.getVersion() + " (" + dep.getScope() - + ")"); + LOG.debug("Not generating classpath entry for unresolved artifact: {}:{}:{} ({})", + dep.getGroupId(), dep.getArtifactId(), dep.getVersion(), dep.getScope()); // Unresolved file because it is in the wrong scope (e.g. test?) continue; } - aLog.debug("Classpath entry: " + dep.getGroupId() + ":" + dep.getArtifactId() + ":" - + dep.getVersion() + " -> " + dep.getFile()); + LOG.debug("Classpath entry: {}:{}:{} -> {}", dep.getGroupId(), dep.getArtifactId(), + dep.getVersion(), dep.getFile()); urls.add(dep.getFile().toURI().toURL()); } catch (Exception e) { throw new MojoExecutionException("Unable get dependency artifact location for " @@ -166,6 +164,7 @@ public static URLClassLoader getClassloader(MavenProject aProject, Log aLog, + ExceptionUtils.getRootCauseMessage(e), e); } } + return new URLClassLoader(urls.toArray(new URL[] {}), Util.class.getClassLoader()); } @@ -180,13 +179,14 @@ public static boolean isComponent(ClassLoader aClassLoader, Class aClass) * @param aClassLoader * the class loader by which the component was loaded. */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({ "rawtypes" }) public static ComponentType getType(ClassLoader aClassLoader, Class aClass) throws ClassNotFoundException { // Loading this through the component class loader to make sure we really get the right // class instance. - Class iCR = aClassLoader.loadClass("org.apache.uima.collection.CollectionReader"); - Class iAE = aClassLoader.loadClass("org.apache.uima.analysis_component.AnalysisComponent"); + var iCR = aClassLoader.loadClass("org.apache.uima.collection.CollectionReader"); + var iAE = aClassLoader.loadClass("org.apache.uima.analysis_component.AnalysisComponent"); + if (iCR.isAssignableFrom(aClass)) { return ComponentType.COLLECTION_READER; } else if (iAE.isAssignableFrom(aClass)) { diff --git a/uimafit-maven-plugin/src/test/java/org/apache/uima/fit/maven/javadoc/ComponentDescriptionExtractorTest.java b/uimafit-maven-plugin/src/test/java/org/apache/uima/fit/maven/javadoc/ComponentDescriptionExtractorTest.java index 448500551..55d33658f 100644 --- a/uimafit-maven-plugin/src/test/java/org/apache/uima/fit/maven/javadoc/ComponentDescriptionExtractorTest.java +++ b/uimafit-maven-plugin/src/test/java/org/apache/uima/fit/maven/javadoc/ComponentDescriptionExtractorTest.java @@ -18,22 +18,21 @@ */ package org.apache.uima.fit.maven.javadoc; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import org.apache.uima.fit.maven.util.Util; import org.junit.jupiter.api.Test; -import com.thoughtworks.qdox.model.JavaSource; - -public class ComponentDescriptionExtractorTest { +class ComponentDescriptionExtractorTest { @Test - public void test() throws Exception { + void test() throws Exception { // Create the Java parser and parse the source code into an abstract syntax tree - JavaSource source = Util.parseSource("src/test/resources/TestComponent.java", "UTF-8"); + var source = Util.parseSource("src/test/resources/TestComponent.java", "UTF-8"); - String javadoc = Util.getComponentDocumentation(source, "some.test.mypackage.TestComponent"); + var javadoc = Util.getComponentDocumentation(source, "some.test.mypackage.TestComponent"); - assertEquals("A test component used to test JavadocTextExtractor.", javadoc); + assertThat(javadoc).as("JavaDoc for TestComponent.java") + .isEqualTo("A test component used to test JavadocTextExtractor."); } } diff --git a/uimafit-maven-plugin/src/test/java/org/apache/uima/fit/maven/javadoc/JavadocTextExtractorTest.java b/uimafit-maven-plugin/src/test/java/org/apache/uima/fit/maven/javadoc/JavadocTextExtractorTest.java index df98202f6..83b03556a 100644 --- a/uimafit-maven-plugin/src/test/java/org/apache/uima/fit/maven/javadoc/JavadocTextExtractorTest.java +++ b/uimafit-maven-plugin/src/test/java/org/apache/uima/fit/maven/javadoc/JavadocTextExtractorTest.java @@ -18,50 +18,47 @@ */ package org.apache.uima.fit.maven.javadoc; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import java.io.IOException; import org.apache.uima.fit.maven.util.Util; import org.junit.jupiter.api.Test; -import com.thoughtworks.qdox.model.JavaSource; - -public class JavadocTextExtractorTest { +class JavadocTextExtractorTest { @Test - public void testDocOnName() throws Exception { - String doc = getJavadoc("value1", "PARAM_VALUE_1"); - assertEquals("Documentation for value 1", doc); + void testDocOnName() throws Exception { + assertThat(getJavadoc("value1", "PARAM_VALUE_1")).as("JavaDoc for parameter 'value1'") + .isEqualTo("Documentation for value 1"); } @Test - public void testDocOnParameterWithName() throws Exception { - String doc = getJavadoc("value2", "PARAM_VALUE_2"); - assertEquals("Documentation for value 2", doc); + void testDocOnParameterWithName() throws Exception { + assertThat(getJavadoc("value2", "PARAM_VALUE_2")).as("JavaDoc for parameter 'PARAM_VALUE_2'") + .isEqualTo("Documentation for value 2"); } @Test - public void testDocOnParameterWithoutName() throws Exception { - String doc = getJavadoc("value3", null); - assertEquals("Documentation for value 3", doc); + void testDocOnParameterWithoutName() throws Exception { + assertThat(getJavadoc("value3", null)).as("JavaDoc for parameter 'value3'") + .isEqualTo("Documentation for value 3"); } @Test - public void testWithoutDoc() throws Exception { - String doc = getJavadoc("value4", null); - assertEquals(null, doc); + void testWithoutDoc() throws Exception { + assertThat(getJavadoc("value4", null)).as("JavaDoc for parameter 'value4'").isNull(); } @Test - public void testDocOnParameterWithNonLiteralName() throws Exception { - String doc = getJavadoc("value5", "PARAM_VALUE_5"); - assertEquals("Documentation for value 5", doc); + void testDocOnParameterWithNonLiteralName() throws Exception { + assertThat(getJavadoc("value5", "PARAM_VALUE_5")).as("JavaDoc for parameter 'value5'") + .isEqualTo("Documentation for value 5"); } private String getJavadoc(String aParameter, String aNameConstant) throws IOException { // Create the Java parser and parse the source code into an abstract syntax tree - JavaSource source = Util.parseSource("src/test/resources/TestComponent.java", "UTF-8"); + var source = Util.parseSource("src/test/resources/TestComponent.java", "UTF-8"); return Util.getParameterDocumentation(source, aParameter, aNameConstant); } diff --git a/uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes4.java b/uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes4.java index 347932ce0..482ff1f03 100644 --- a/uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes4.java +++ b/uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes4.java @@ -658,7 +658,7 @@ private void writeStringInfo() throws IOException { // approximate histogram if (doMeasurements) { // len is utf-8 encoding - float len = out.size() - startPos; + var len = out.size() - startPos; // if len == chars, then all got coded as 1 byte // if len > chars, some were utf-8 coded as 2 bytes float excess = (len / commonStrings[i].length()) - 1; // excess over length 1 diff --git a/uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes6.java b/uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes6.java index 1c50f6a92..eb28236d0 100644 --- a/uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes6.java +++ b/uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes6.java @@ -3538,7 +3538,7 @@ private void writeStringInfo() throws IOException { // approximate histogram if (doMeasurements) { // len is utf-8 encoding - float len = dosZipSources[strChars_i].size() - startPos; + var len = dosZipSources[strChars_i].size() - startPos; // if len == chars, then all got coded as 1 byte // if len > chars, some were utf-8 coded as 2 bytes float excess = len / commonStrings[i].length() - 1; // excess over length 1 diff --git a/uimaj-core/src/main/java/org/apache/uima/pear/util/FileUtil.java b/uimaj-core/src/main/java/org/apache/uima/pear/util/FileUtil.java index 674217a9d..eff39257e 100644 --- a/uimaj-core/src/main/java/org/apache/uima/pear/util/FileUtil.java +++ b/uimaj-core/src/main/java/org/apache/uima/pear/util/FileUtil.java @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - package org.apache.uima.pear.util; import java.io.BufferedInputStream; @@ -41,6 +40,7 @@ import java.net.URLConnection; import java.nio.charset.Charset; import java.nio.file.CopyOption; +import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; @@ -767,14 +767,9 @@ public static long extractFilesFromJar(JarFile jarFile, File targetDir, FileFilt long totalBytes = 0; byte[] block = new byte[4096]; - String prefix = normalizeToUnix(targetDir.getCanonicalPath()); - if (!prefix.endsWith(UNIX_SEPARATOR)) { - prefix = prefix + UNIX_SEPARATOR_CHAR; - } - - Enumeration jarList = jarFile.entries(); + var jarList = jarFile.entries(); while (jarList.hasMoreElements()) { - JarEntry jarEntry = jarList.nextElement(); + var jarEntry = jarList.nextElement(); // check that file is accepted if (jarEntry.isDirectory() || (filter != null && !filter.accept(new File(jarEntry.getName())))) { @@ -782,21 +777,22 @@ public static long extractFilesFromJar(JarFile jarFile, File targetDir, FileFilt } // make sure the file directory exists - File file = new File(targetDir, jarEntry.getName()); + var entryName = jarEntry.getName(); + var file = new File(targetDir, entryName).toPath().normalize(); - if (!normalizeToUnix(file.getCanonicalPath()).startsWith(prefix)) { + if (!file.startsWith(targetDir.toPath().normalize())) { throw new IOException("Can only write within target folder [" + targetDir.getAbsolutePath() + "]. Please validate ZIP contents."); } - File dir = file.getParentFile(); - if (!dir.exists() && !dir.mkdirs()) { - throw new IOException("Could not create directory [" + dir.getAbsolutePath() + "]"); + var dir = file.getParent(); + if (!Files.exists(dir)) { + Files.createDirectories(dir); } // extract file - try (BufferedInputStream iStream = new BufferedInputStream(jarFile.getInputStream(jarEntry)); - BufferedOutputStream oStream = new BufferedOutputStream(new FileOutputStream(file))) { + try (var iStream = new BufferedInputStream(jarFile.getInputStream(jarEntry)); + var oStream = Files.newOutputStream(file)) { int bCount = 0; while ((bCount = iStream.read(block)) > 0) { totalBytes += bCount; diff --git a/uimaj-core/src/main/java/org/apache/uima/util/impl/ProcessTraceEvent_impl.java b/uimaj-core/src/main/java/org/apache/uima/util/impl/ProcessTraceEvent_impl.java index 403bc20b7..fc070c8ec 100644 --- a/uimaj-core/src/main/java/org/apache/uima/util/impl/ProcessTraceEvent_impl.java +++ b/uimaj-core/src/main/java/org/apache/uima/util/impl/ProcessTraceEvent_impl.java @@ -53,7 +53,7 @@ public class ProcessTraceEvent_impl implements ProcessTraceEvent { /** * Duration of this event in milliseconds. */ - private int mDuration; + private long mDuration; /** * Result Message of this event. @@ -147,7 +147,15 @@ public void setDescription(String aDescription) { */ @Override public int getDuration() { - return mDuration; + if (mDuration > Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } + + if (mDuration < Integer.MIN_VALUE) { + return Integer.MIN_VALUE; + } + + return (int) mDuration; } /** diff --git a/uimaj-core/src/test/resources/log4j2-test.xml b/uimaj-core/src/test/resources/log4j2-test.xml index 1cbdb7ce0..057fb4c09 100644 --- a/uimaj-core/src/test/resources/log4j2-test.xml +++ b/uimaj-core/src/test/resources/log4j2-test.xml @@ -25,8 +25,8 @@ - - + + diff --git a/uimaj-parent/pom.xml b/uimaj-parent/pom.xml index 858054731..fcf55f728 100644 --- a/uimaj-parent/pom.xml +++ b/uimaj-parent/pom.xml @@ -134,8 +134,6 @@ - 4.0.10 - + junit + junit + 4.13.2 + test + @@ -719,11 +748,14 @@ maven-dependency-plugin - org.apache.maven:maven-plugin-api + org.apache.maven:maven-artifact + org.apache.maven:maven-compat org.apache.maven:maven-core org.apache.maven:maven-model - org.apache.maven:maven-artifact + org.apache.maven:maven-plugin-api org.apache.maven.plugin-tools:maven-plugin-annotations + org.apache.maven.plugin-testing:maven-plugin-testing-harness + junit:junit