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 -lor 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)