import java.nio.charset.Charset;
public boolean isAscii(String v) {
Charset.forName("US-ASCII").newEncoder().canEncode(v);
}
Search This Blog
Showing posts with label java. Show all posts
Showing posts with label java. Show all posts
Java: check if a String contains only ASCII
Java: remove unsafe html tags
public class HtmlTagRemover {
public static String removeUnsafeTags(String html) {
// Define the regular expression pattern to match unsafe tags
String unsafeTagsPattern = "<(script|iframe|object|embed)[^>]*>.*?</\\1>";
// Remove the unsafe tags from the HTML string
String safeHtml = html.replaceAll(unsafeTagsPattern, "");
return safeHtml;
}
public static void main(String[] args) {
String html = "<b>Safe HTML</b><script>alert('XSS')</script>";
String safeHtml = removeUnsafeTags(html);
System.out.println(safeHtml);
}
}
Set Groovy Development Environment
I. Install required SDK and IDE
- Install Java SDK 8+
- Install Gradle
- Install Groovy
- Install Intellij Idea
II. Create a new Groovy project using Gradle
- Create a new project directory:
mkdir my-groovy-app
- Get into the project directory
cd my-groovy-app
and run gradle:gradle init Select type of project to generate: 1: basic 2: application 3: library 4: Gradle plugin Enter selection (default: basic) [1..4] 1 Select build script DSL: 1: Groovy 2: Kotlin Enter selection (default: Groovy) [1..2] 1 Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no] Project name (default: my-groovy-app): > Task :init Get more help with your project: Learn more about Gradle by exploring our samples at https://docs.gradle.org/7.6/samples BUILD SUCCESSFUL in 22s 2 actionable tasks: 2 executed - Edit build.gradle file and add the content (like below):
plugins { id 'groovy' id 'application' } group 'myapps' version '1.0-SNAPSHOT' repositories { mavenCentral() maven { url 'https://my.org/mvn-repo' } } dependencies { implementation 'org.apache.groovy:groovy:4.0.7' implementation 'org.apache.ivy:ivy:2.5.0' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' } application { mainClass = 'my.App' } test { useJUnitPlatform() } - Create source folder structure:
mkdir src/main/groovy mkdir src/main/java mkdir src/main/resources mkdir src/test/groovy mkdir src/test/java mkdir src/test/resources - Optional: create gradle.properties file at the project root, and add the options below:
org.gradle.warning.mode=all org.gradle.logging.stacktrace=full
- Create Application class: my.App.groovy:
package my class App { static void main(String[] args) { println 'Hello, Wolrd' } } - Start Intellij Idea, open the project directory. Select src/main/groovy directory, Mark directory as -> Sources root
Java source code: implementation of ANT path pattern
Java source code of org.springframework.util.AntPathMatcher
see also
- Java ANT path patterns
- Java Doc: org.springframework.util.AntPathMatcher
- Stackoverflow discussion about ANT path pattern
- Java 7 has some basic PathMatcher support via java.nio.file.FileSystem.getPathMatcher()
Setup GraalVM and Native Image on Windows 10
- Download GraalVM and install it (Instructions)
- Install Native Image:
gu install native-image
- Install Build Tools for Visual Studio 20XX
- Start using native-image
- On Windows, the native-image builder will only work when it’s executed from the x64 Native Tools Command Prompt. You can find it in Start Menu or folder: "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools"
See also
Install Eclipse Color Theme plugin
The update site https://eclipse-color-theme.github.com/update/ from Marketplace does NOT work.
Use the site url below:
https://eclipse-color-theme.github.io/update/
Manually add a new site: https://eclipse-color-theme.github.io/update/ and install.
Use the site url below:
https://eclipse-color-theme.github.io/update/
Manually add a new site: https://eclipse-color-theme.github.io/update/ and install.
javax.net.ssl.SSLHandshakeException: Insufficient buffer remaining for AEAD cipher fragment (2). Needs to be more than tag size (16)
javax.net.ssl.SSLHandshakeException: Insufficient buffer remaining for AEAD cipher fragment (2). Needs to be more than tag size (16)
at sun.security.ssl.Alert.createSSLException(Alert.java:131)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:324)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:267)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:262)
at sun.security.ssl.SSLTransport.decode(SSLTransport.java:130)
at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1397)
at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1305)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
at sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:818)
at sun.security.ssl.SSLSocketImpl.access$200(SSLSocketImpl.java:73)
at sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:909)
at arc.dqV.a(SourceFile:80)
at arc.dqV.read(SourceFile:56)
at arc.ud.a(SourceFile:187)
at arc.ud.a(SourceFile:256)
at arc.mf.modules.dicom.DicomNetworkService.readNextMessage(SourceFile:250)
at arc.cQg.run(SourceFile:303)
at arc.cQh.doExecute(SourceFile:497)
at arc.utils.Task.a(SourceFile:990)
at arc.utils.Task.run(SourceFile:939)
at arc.dFf.a(SourceFile:530)
at arc.dFf.run(SourceFile:478)
at arc.dFe.run(SourceFile:321)
Caused by: javax.crypto.BadPaddingException: Insufficient buffer remaining for AEAD cipher fragment (2). Needs to be more than tag size (16)
at sun.security.ssl.SSLCipher$T13GcmReadCipherGenerator$GcmReadCipher.decrypt(SSLCipher.java:1845)
at sun.security.ssl.SSLSocketInputRecord.decodeInputRecord(SSLSocketInputRecord.java:262)
at sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:190)
at sun.security.ssl.SSLTransport.decode(SSLTransport.java:109)
... 18 more
Cause:
javax.crypto.BadPaddingException: Insufficient buffer remaining for AEAD cipher fragment (2). Needs to be more than tag size (16):
Stack:
javax.crypto.BadPaddingException: Insufficient buffer remaining for AEAD cipher fragment (2). Needs to be more than tag size (16)
at sun.security.ssl.SSLCipher$T13GcmReadCipherGenerator$GcmReadCipher.decrypt(SSLCipher.java:1845)
at sun.security.ssl.SSLSocketInputRecord.decodeInputRecord(SSLSocketInputRecord.java:262)
at sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:190)
at sun.security.ssl.SSLTransport.decode(SSLTransport.java:109)
at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1397)
at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1305)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
at sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:818)
at sun.security.ssl.SSLSocketImpl.access$200(SSLSocketImpl.java:73)
at sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:909)
at arc.dqV.a(SourceFile:80)
at arc.dqV.read(SourceFile:56)
at arc.ud.a(SourceFile:187)
at arc.ud.a(SourceFile:256)
at arc.mf.modules.dicom.DicomNetworkService.readNextMessage(SourceFile:250)
at arc.cQg.run(SourceFile:303)
at arc.cQh.doExecute(SourceFile:497)
at arc.utils.Task.a(SourceFile:990)
at arc.utils.Task.run(SourceFile:939)
at arc.dFf.a(SourceFile:530)
at arc.dFf.run(SourceFile:478)
at arc.dFe.run(SourceFile:321)
Cause
This is known Oracle issue. For details, visit the following links:- https://bugs.openjdk.java.net/browse/JDK-8221218
- https://support.oracle.com/knowledge/Middleware/2519569_1.html
Solution
There are two solutions for this issue:- Add -DUseSunHttpHandler=true in the startup arguments.
- Identify on which cipher the handshake was negoitiated by enabling the JSSE debug and disable that cipher in the jre/lib/security/java.security file.
see also
Secure Java SSL by updating jdk.tls.disabledAlgorithms in java.security file
Disable SSL/TLS Diffie-Hellman keys less that 2048 bits
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, \
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, \
TLS_DHE_RSA_WITH_AES_256_CBC_SHA, \
TLS_DHE_DSS_WITH_AES_256_CBC_SHA, \
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, \
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, \
TLS_DHE_RSA_WITH_AES_128_CBC_SHA, \
TLS_DHE_DSS_WITH_AES_128_CBC_SHA, \
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, \
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, \
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, \
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
Disable following algorithms to enforce Perfect Forward Secrecy
TLS_RSA_WITH_AES_128_CBC_SHA256, \
TLS_RSA_WITH_AES_128_CBC_SHA, \
TLS_RSA_WITH_AES_128_GCM_SHA256, \
TLS_RSA_WITH_AES_256_CBC_SHA256, \
TLS_RSA_WITH_AES_256_CBC_SHA, \
TLS_RSA_WITH_AES_256_GCM_SHA384, \
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, \
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, \
TLS_DHE_RSA_WITH_AES_128_CBC_SHA, \
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
jdk.tls.disabledAlgorithms in jre/lib/security/java.security
jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
DH keySize < 2048, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
include jdk.disabled.namedCurves \
TLS_DHE_DSS_WITH_AES_128_CBC_SHA, \
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, \
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, \
TLS_DHE_DSS_WITH_AES_256_CBC_SHA, \
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, \
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, \
TLS_DHE_RSA_WITH_AES_128_CBC_SHA, \
TLS_DHE_RSA_WITH_AES_128_CBC_SHA, \
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, \
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, \
TLS_DHE_RSA_WITH_AES_256_CBC_SHA, \
TLS_DHE_RSA_WITH_AES_256_CBC_SHA, \
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, \
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, \
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, \
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, \
TLS_RSA_WITH_AES_128_CBC_SHA, \
TLS_RSA_WITH_AES_128_CBC_SHA256, \
TLS_RSA_WITH_AES_128_GCM_SHA256, \
TLS_RSA_WITH_AES_256_CBC_SHA, \
TLS_RSA_WITH_AES_256_CBC_SHA256, \
TLS_RSA_WITH_AES_256_GCM_SHA384
see also
Java util logging: configure root logger
Logger rootLogger = Logger.getLogger("");
Handler[] handlers = rootLogger.getHandlers();
for (Handler h : handlers) {
h.setLevel(level);
}
rootLogger.setLevel(level);
Java: check if directory is empty
public boolean isEmpty(Path path) throws IOException {
if (Files.isDirectory(path)) {
try (Stream<Path> entries = Files.list(path)) {
return !entries.findFirst().isPresent();
}
}
return false;
}
Enable DNS cache for Java applications
To enable DNS cache, there are two options:
- Enable Java in-memory DNS cache by setting JVM security property: networkaddress.cache.ttl to a positive integer (of seconds).
- Enable operating system's DNS cache (and no change to Java security property. networkaddress.cache.ttl=-1 by default).
See also:
Java FileInputStream: Seek to offset using file channel
File f = File.createTempFile("aaa", null);
byte[] out = new byte[]{0, 1, 2};
FileOutputStream o = new FileOutputStream(f);
o.write(out);
o.close();
FileInputStream i = new FileInputStream(f);
i.getChannel().position(1);
assert i.read() == out[1];
i.close();
f.delete();
Count lines of Java source code
find . -type f -name "*.java" | xargs cat | grep [alnum{}] | wc -l
or shell script could be:
#!/bin/bash
[[ -z $1 ]] && dir=. || dir=$1
find $dir -type f -name "*.java" | xargs cat | grep [alnum{}] | wc -l
log4j2: conditional appender using routes
<?xml version="1.0"?>
<Configuration status="INFO">
<Appenders>
<Console name="SYS_OUT" target="SYSTEM_OUT" />
<Console name="SYS_ERR" target="SYSTEM_ERR" />
<Routing name="Router">
<Routes pattern="$${env:STREAM_TO:-OUT}">
<Route ref="SYS_OUT" key="OUT" />
<Route ref="SYS_ERR" key="ERR" />
</Routes>
</Routing>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Router" />
</Root>
</Loggers>
</Configuration>
see also
Maven: conditionally execute plugins using profiles
<project>
<properties>...</properties>
<repositories>...</repositories>
<dependencies>...</dependencies>
<build>
<plugins>...</plugins>
</build>
<profiles>
<profile>
<id>windows</id>
<activation>
<os>
<name>Windows XP</name>
<family>Windows</family>
<arch>x86</arch>
<version>5.1.2600</version>
</os>
</activation>
<properties>...</properties>
<repositories>...</repositories>
<dependencies>...</dependencies>
<build>
<plugins>...</plugins>
</build>
</profile>
</profiles>
</project>
To activate the profile manually:mvn package -p PROFILE_ID
see also
Java: try with AutoCloseable resources
1. Multiple AutoCloseable resources
try (InputStream in = getInputStream(); OutputStream out = getOutputStream()) {
... ...
}
The resources are closed in the reverse order of declaration.
2. Resource leaking caused by nested constructors
There is possible resource leaking issue for the code below:
try(InputStream in = new MyFilterInputStream(new BufferedInputStream(new FileInputStream("/tmp/test.file")))) {
... ...
}
Because any checked exception from the chain of the constructors can cause resource failing to close. The code below with multiple declared AutoCloseables should be used:
try(FileInputStream fis = new FileInputStream("/tmp/test.file");
BufferedInputStream bis = new BufferedInputStream(fis);
MyFilterInputStream mfis = new MyFilterInputStream(bis)) {
... ...
}
3. What will happen if the AutoCloseable is null
A resource is closed only if it initialized to a non-null value. So the code works without having to worry about NPE when in is null.
try(InputStream in = createNew==true? createInputStream(): null) {
if(in==null) {
... ...
}
}
see also
try (InputStream in = getInputStream(); OutputStream out = getOutputStream()) {
... ...
}
The resources are closed in the reverse order of declaration.
2. Resource leaking caused by nested constructors
There is possible resource leaking issue for the code below:
try(InputStream in = new MyFilterInputStream(new BufferedInputStream(new FileInputStream("/tmp/test.file")))) {
... ...
}
Because any checked exception from the chain of the constructors can cause resource failing to close. The code below with multiple declared AutoCloseables should be used:
try(FileInputStream fis = new FileInputStream("/tmp/test.file");
BufferedInputStream bis = new BufferedInputStream(fis);
MyFilterInputStream mfis = new MyFilterInputStream(bis)) {
... ...
}
3. What will happen if the AutoCloseable is null
A resource is closed only if it initialized to a non-null value. So the code works without having to worry about NPE when in is null.
try(InputStream in = createNew==true? createInputStream(): null) {
if(in==null) {
... ...
}
}
see also
Build Java runtime from OpenJDK using jlink
MODULES=$(java --list-modules | sed 's/\@.*//' | paste -sd "," -) jlink --no-header-files --no-man-pages --compress=2 --add-modules $MODULES --output java-runtime
Modularise legacy jar
- Run "jdeps --generate-module-info" on the legacy jar to generate module-info.java file.
jdeps --module-path $ROOT_DIR/modules \ --add-modules jackson.annotations,jackson.core \ --generate-module-info ~/work $JACKSON_DATABIND_JAR - Unjar the legacy jar, add module-info.java from above, re-compile and re-jar:
javac --module-path $ROOT_DIR/modules \ --add-modules jackson.annotations,jackson.core \ -d $ROOT_DIR/classes module-info.java
see also
Subscribe to:
Posts (Atom)
