This commit is contained in:
Looly 2023-04-23 00:05:39 +08:00
parent 20636feb85
commit f226b8418a
11 changed files with 103 additions and 66 deletions

View File

@ -6,6 +6,7 @@ install: true
jdk:
- openjdk8
- openjdk17
notifications:
email: false
@ -14,7 +15,7 @@ cache:
directories:
- '$HOME/.m2'
script:
script:
- export TZ=Asia/Shanghai
- mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V
- mvn cobertura:cobertura -Dcobertura.report.format=xml -Dmaven.javadoc.skip.true

View File

@ -83,7 +83,8 @@ public class AnnotationProxy<T extends Annotation> implements Annotation, Invoca
* @return 属性方法结果映射
*/
private Map<String, Object> initAttributes() {
final Method[] methods = MethodUtil.getMethods(this.type);
// 只缓存注解定义的方法
final Method[] methods = MethodUtil.getDeclaredMethods(this.type);
final Map<String, Object> attributes = new HashMap<>(methods.length, 1);
for (final Method method : methods) {

View File

@ -324,7 +324,8 @@ public class AnnotationUtil {
}
/**
* 设置新的注解的属性字段
* 设置新的注解的属性字段<br>
* 注意此方法在jdk9+中抛出异常须添加`--add-opens=java.base/java.lang=ALL-UNNAMED`启动参数
*
* @param annotation 注解对象
* @param annotationField 注解属性字段名称

View File

@ -37,6 +37,24 @@ import java.lang.reflect.*;
*/
public class ReflectUtil {
/**
* 设置方法为可访问私有方法可以被外部调用静默调用抛出异常则跳过<br>
* 注意此方法在jdk9+中抛出异常须添加`--add-opens=java.base/java.lang=ALL-UNNAMED`启动参数
*
* @param <T> AccessibleObject的子类比如ClassMethodField等
* @param accessibleObject 可设置访问权限的对象比如ClassMethodField等
* @return 被设置可访问的对象
* @throws SecurityException 访问被禁止抛出此异常
*/
public static <T extends AccessibleObject> T setAccessibleQuietly(final T accessibleObject) {
try{
setAccessible(accessibleObject);
} catch (final RuntimeException ignore){
// ignore
}
return accessibleObject;
}
/**
* 设置方法为可访问私有方法可以被外部调用<br>
* 注意此方法在jdk9+中抛出异常须添加`--add-opens=java.base/java.lang=ALL-UNNAMED`启动参数
@ -50,7 +68,6 @@ public class ReflectUtil {
public static <T extends AccessibleObject> T setAccessible(final T accessibleObject) throws SecurityException {
if (null != accessibleObject && !accessibleObject.isAccessible()) {
accessibleObject.setAccessible(true);
return accessibleObject;
}
return accessibleObject;
}

View File

@ -361,15 +361,26 @@ public class ObjUtil {
* @see #cloneByStream(Object)
*/
public static <T> T clone(final T obj) {
T result = ArrayUtil.clone(obj);
if (null == result) {
if (obj instanceof Cloneable) {
result = MethodUtil.invoke(obj, "clone");
} else {
result = cloneByStream(obj);
final T result = ArrayUtil.clone(obj);
if(null != result){
// 数组
return result;
}
if (obj instanceof Cloneable) {
try{
return MethodUtil.invoke(obj, "clone");
} catch (final HutoolException e){
if(e.getCause() instanceof IllegalAccessException){
// JDK9+下可能无权限
return cloneByStream(obj);
}else {
throw e;
}
}
}
return result;
return cloneByStream(obj);
}
/**

View File

@ -5,6 +5,8 @@ import org.dromara.hutool.core.util.ObjUtil;
import lombok.SneakyThrows;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import java.lang.annotation.*;
import java.lang.reflect.Method;
@ -113,7 +115,9 @@ public class AnnotationUtilTest {
}
@Test
@EnabledForJreRange(max = JRE.JAVA_8)
public void testSetValue() {
// jdk9+中抛出异常须添加`--add-opens=java.base/java.lang=ALL-UNNAMED`启动参数
final AnnotationForTest annotation = ClassForTest.class.getAnnotation(AnnotationForTest.class);
final String newValue = "is a new value";
Assertions.assertNotEquals(newValue, annotation.value());
@ -124,6 +128,7 @@ public class AnnotationUtilTest {
@Test
public void testGetAnnotationAlias() {
final MetaAnnotationForTest annotation = AnnotationUtil.getAnnotationAlias(AnnotationForTest.class, MetaAnnotationForTest.class);
Assertions.assertNotNull(annotation);
Assertions.assertEquals(annotation.value(), annotation.alias());
Assertions.assertEquals(MetaAnnotationForTest.class, annotation.annotationType());
}

View File

@ -20,6 +20,8 @@ import org.dromara.hutool.core.lang.tuple.Tuple;
import org.dromara.hutool.core.reflect.MethodUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import java.io.Serializable;
import java.lang.reflect.Method;
@ -181,17 +183,16 @@ public class LambdaUtilTest {
final BiConsumer<Bean, Long> setId = LambdaUtil.buildSetter(MethodUtil.getMethod(Bean.class, "setId", Long.class));
final BiConsumer<Bean, Long> setId2 = LambdaUtil.buildSetter(Bean.class, Bean.Fields.id);
final BiConsumer<Bean, Boolean> setFlag = LambdaUtil.buildSetter(Bean.class, Bean.Fields.flag);
Assertions.assertEquals(setId, setId2);
setId.accept(bean, 3L);
setFlag.accept(bean, true);
Assertions.assertEquals(3L, (long) bean.getId());
Assertions.assertTrue(bean.isFlag());
}
@Test
void buildSetterTest() {
@EnabledForJreRange(max = JRE.JAVA_8)
void buildSetterWithPrimitiveTest() {
// 原始类型参数在jdk9+中构建setter异常
final Bean bean = new Bean();
bean.setId(2L);
bean.setFlag(false);
@ -339,7 +340,7 @@ public class LambdaUtilTest {
@Test
void getInvokeMethodErrorTest() {
// 非函数接口返回异常
Assertions.assertThrows(IllegalArgumentException.class, ()->{
Assertions.assertThrows(IllegalArgumentException.class, () -> {
LambdaUtil.getInvokeMethod(LambdaUtilTest.class);
});
}

View File

@ -16,10 +16,13 @@ import lombok.Data;
import org.dromara.hutool.core.convert.Convert;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
public class CglibUtilTest {
@Test
@EnabledForJreRange(max = JRE.JAVA_8)
public void copyTest() {
final SampleBean bean = new SampleBean();
OtherSampleBean otherBean = new OtherSampleBean();

View File

@ -12,10 +12,10 @@
package org.dromara.hutool.http.client.engine.jdk;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.core.reflect.FieldUtil;
import org.dromara.hutool.core.reflect.ModifierUtil;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.util.SystemUtil;
import org.dromara.hutool.http.HttpException;
@ -26,8 +26,6 @@ import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* 针对{@link HttpURLConnection}相关工具
@ -44,23 +42,34 @@ public class HttpUrlConnectionUtil {
/**
* 增加支持的METHOD方法<br>
* 此方法通过注入方式修改{@link HttpURLConnection}中的methods静态属性增加PATCH方法<br>
* see: <a href="https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch">https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch</a>
* see: https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch
*/
public static void allowPatch() {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
doAllowPatch();
return null;
});
public static void allowPatchQuietly() {
try{
allowPatch();
} catch (final Exception ignore){
// ignore
}
}
/**
* 增加支持的METHOD方法<br>
* 此方法通过注入方式修改{@link HttpURLConnection}中的methods静态属性增加PATCH方法<br>
* see: <a href="https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch">https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch</a>
* see: https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch
*/
public static void allowPatch() {
doAllowPatch();
}
/**
* 增加支持的METHOD方法<br>
* 此方法通过注入方式修改{@link HttpURLConnection}中的methods静态属性增加PATCH方法<br>
* see: https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch
*
* @since 5.7.4
*/
synchronized private static void doAllowPatch() {
// 注意此方法在jdk9+中抛出异常须添加`--add-opens=java.base/java.lang=ALL-UNNAMED`启动参数
final Field methodsField = FieldUtil.getField(HttpURLConnection.class, "methods");
if (null == methodsField) {
throw new HttpException("None static field [methods] with Java version: [{}]", SystemUtil.get("java.version"));

View File

@ -6,6 +6,6 @@ import org.junit.jupiter.api.Test;
public class HttpUrlConnectionUtilTest {
@Test
public void allowPatchTest() {
HttpUrlConnectionUtil.allowPatch();
HttpUrlConnectionUtil.allowPatchQuietly();
}
}

View File

@ -197,9 +197,9 @@ public class ImgUtil {
*/
public static void scale(final File srcImageFile, final File destImageFile, final int width, final int height, final Color fixedColor) throws IORuntimeException {
Img.from(srcImageFile)//
.setTargetImageType(FileNameUtil.extName(destImageFile))//
.scale(width, height, fixedColor)//
.write(destImageFile);
.setTargetImageType(FileNameUtil.extName(destImageFile))//
.scale(width, height, fixedColor)//
.write(destImageFile);
}
/**
@ -1201,8 +1201,8 @@ public class ImgUtil {
*/
public static BufferedImage toBufferedImage(final Image image, final String imageType, final Color backgroundColor) {
final int type = IMAGE_TYPE_PNG.equalsIgnoreCase(imageType)
? BufferedImage.TYPE_INT_ARGB
: BufferedImage.TYPE_INT_RGB;
? BufferedImage.TYPE_INT_ARGB
: BufferedImage.TYPE_INT_RGB;
return toBufferedImage(image, type, backgroundColor);
}
@ -1295,13 +1295,15 @@ public class ImgUtil {
// issue#1821@Github
img = new ImageIcon(img).getImage();
final BufferedImage bimage = new BufferedImage(
img.getWidth(null), img.getHeight(null), imageType);
final Graphics2D bGr = GraphicsUtil.createGraphics(bimage, backgroundColor);
final BufferedImage bImage = new BufferedImage(
img.getWidth(null),
img.getHeight(null),
imageType);
final Graphics2D bGr = GraphicsUtil.createGraphics(bImage, backgroundColor);
bGr.drawImage(img, 0, 0, null);
bGr.dispose();
return bimage;
return bImage;
}
/**
@ -1348,8 +1350,8 @@ public class ImgUtil {
*/
public static String toBase64DataUri(final Image image, final String imageType) {
return URLUtil.getDataUri(
"image/" + imageType, "base64",
toBase64(image, imageType));
"image/" + imageType, "base64",
toBase64(image, imageType));
}
/**
@ -1464,9 +1466,9 @@ public class ImgUtil {
*/
public static Rectangle2D getRectangle(final String str, final Font font) {
return font.getStringBounds(str,
new FontRenderContext(AffineTransform.getScaleInstance(1, 1),
false,
false));
new FontRenderContext(AffineTransform.getScaleInstance(1, 1),
false,
false));
}
// region ----- write
@ -1571,50 +1573,36 @@ public class ImgUtil {
write(image, imageType, destImageStream, 1);
}
/**
* 写出图像为指定格式
*
* @param image {@link Image}
* @param imageType 图片类型图片扩展名
* @param targetImageStream 写出到的目标流
* @param quality 质量数字为0~1不包括0和1表示质量压缩比除此数字外设置表示不压缩
* @throws IORuntimeException IO异常
* @since 4.3.2
*/
public static void write(final Image image, final String imageType, final ImageOutputStream targetImageStream,
final float quality) throws IORuntimeException {
write(image, imageType, targetImageStream, quality, null);
}
/**
* 写出图像为指定格式
*
* @param image {@link Image}
* @param imageType 图片类型图片扩展名{@code null}表示使用RGB模式JPG
* @param destImageStream 写出到的目标流
* @param out 写出到的目标流
* @param quality 质量数字为0~1不包括0和1表示质量压缩比除此数字外设置表示不压缩
* @param backgroundColor 背景色{@link Color}
* @throws IORuntimeException IO异常
* @since 4.3.2
*/
public static void write(final Image image, final String imageType, final ImageOutputStream destImageStream,
public static void write(final Image image, final String imageType, final ImageOutputStream out,
final float quality, final Color backgroundColor) throws IORuntimeException {
final BufferedImage bufferedImage = toBufferedImage(image, imageType, backgroundColor);
write(bufferedImage, destImageStream, quality);
write(bufferedImage, imageType, out, quality);
}
/**
* 通过{@link ImageWriter}写出图片到输出流
*
* @param image 图片
* @param imageType 图片类型
* @param output 输出的Image流{@link ImageOutputStream}
* @param quality 质量数字为0~1不包括0和1表示质量压缩比除此数字外设置表示不压缩
* @since 4.3.2
*/
public static void write(final Image image, final ImageOutputStream output, final float quality) {
ImgWriter.of(image, null)
.setQuality(quality)
.write(output);
public static void write(final Image image, final String imageType, final ImageOutputStream output, final float quality) {
ImgWriter.of(image, imageType)
.setQuality(quality)
.write(output);
}
/**
@ -1882,8 +1870,8 @@ public class ImgUtil {
*/
public static Point getPointBaseCentre(final Rectangle rectangle, final int backgroundWidth, final int backgroundHeight) {
return new Point(
rectangle.x + (Math.abs(backgroundWidth - rectangle.width) / 2), //
rectangle.y + (Math.abs(backgroundHeight - rectangle.height) / 2)//
rectangle.x + (Math.abs(backgroundWidth - rectangle.width) / 2), //
rectangle.y + (Math.abs(backgroundHeight - rectangle.height) / 2)//
);
}
// endregion
@ -2032,7 +2020,7 @@ public class ImgUtil {
*/
public static Image filter(final ImageFilter filter, final Image image) {
return Toolkit.getDefaultToolkit().createImage(
new FilteredImageSource(image.getSource(), filter));
new FilteredImageSource(image.getSource(), filter));
}
// endregion
}