getting null from getResourceAsStream when using Travis-CI and Gradle - java

In my gradle project, it has a resources directory. Using the static getResourceAsStream, I access a file from that directory. This works in Eclipse or when running gradle from the command line locally. But when running in Travis-CI, it is not able to find the file.
I have tried using the "Thread.currentThread().getContextClassLoader().getResourceAsStream" and "LenPEGUtil.class.getClassLoader().getResourceAsStream", but each of those either made it stop working locally, or still failed in Travis-CI.
the build.gradle with the source sets
sourceSets{
main{
java {
srcDir 'src'
}
resources {
srcDir 'resources'
}
}
test{
java{
srcDir 'test'
}
resources{
srcDir 'testResources'
}
}
}
The java code reading the file:
private static BufferedImage lenna;
static {
try {
InputStream lennaInputStream = LenPEGUtil.class.getResourceAsStream("/lenna.png");
setLenna(ImageIO.read(lennaInputStream));
} catch (Exception e) {
e.printStackTrace();
}
}
Locally this works. But in Travis-CI I get an exception:
jjcard.jlenpeg.lenPEGWriterTest STANDARD_ERROR
java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(ImageIO.java:1348)
at jjcard.jlenpeg.LenPEGUtil.<clinit>(LenPEGUtil.java:96)
at jjcard.jlenpeg.lenPEGWriterTest.setup(lenPEGWriterTest.java:23)

Related

Jar file and resource file returning null

I have a simple program that reads a text file (test.txt) line by line and prints each line to the console. In intellij it works just fine.
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.io.File;
public class testing {
public static void main(String[] args) {
testing main= new testing();
main.handleData("test.txt");
// handleData();
//System.out.println("hello world");
}
public void handleData(String fileName) {
System.out.println("Testing");
File file= new File(getClass().getResource(fileName).getPath());
try {
Scanner scanner = new Scanner(file);
while(scanner.hasNextLine()){
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
I am trying to build it with gradle and when i run the jar command java -jar out/artifacts/helloTestingWorld_jar/helloTestingWorld.jar I get an error saying the path is null
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.net.URL.getPath()" because the return value of "java.lang.Class.getResource(String)" is null
at testing.handleData(testing.java:22)
at testing.main(testing.java:12)
My build.gradle file looks like this
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}
jar {
manifest {
attributes "Main-Class": "src.main.java.testing"
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
test {
useJUnitPlatform()
}
My resource folder is marked as the resource root and my java folder that contains my main class is marked as the source root. I am thinking that I might have to add the text file as a dependency in the jar file?
I have had a look at all of the other suggestions on here and the all lead to the same result. I have tried rebuilding the project from scratch and still the same result.
I have also tried using InputStream instead of File
InputStream in = getClass().getResourceAsStream(fileName);
When I use InputStream I get this error
Exception in thread "main" java.lang.NullPointerException
at java.base/java.io.Reader.<init>(Reader.java:168)
at java.base/java.io.InputStreamReader.<init>(InputStreamReader.java:76)
at java.base/java.util.Scanner.<init>(Scanner.java:566)
at testing.handleData(test.java:23)
at testing.main(test.java:10)

Duplicate handling strategy error with gradle while using protobuf for java

I am using the below configuration build.gradle
plugins {
id "com.google.protobuf" version "0.8.17"
id "java"
}
group "de.prerna.aws.tests"
version "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
ext {
protobufVersion = "3.18.1"
}
dependencies {
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
sourceSets {
main {
proto {
srcDir 'src/main/proto'
}
java {
// include self written and generated code
srcDirs 'src/main/java'
}
}
}
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:4.0.0-rc-2'
}
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:1.39.0"
}
}
generateProtoTasks.generatedFilesBaseDir = 'generated-sources'
generateProtoTasks {
all().each { task ->
task.plugins { grpc{} }
}
ofSourceSet('main')
}
}
Error
* What went wrong:
Execution failed for task ':processResources'.
> Entry Person.proto is a duplicate but no duplicate handling strategy has been set. Please refer to https://docs.gradle.org/7.2/dsl/org.gradle.api.tasks.Copy.html#org.gradle.api.tasks.Copy:duplicatesStrategy for details.
A variant of BParolini for build.gradle (Groovy DSL)
tasks.withType(Copy) {
filesMatching("**/*.proto") {
duplicatesStrategy = DuplicatesStrategy.INCLUDE
}
}
I could fix this problem by adding the following code to my build.gradle.kts:
tasks {
withType<Copy> {
filesMatching("**/*.proto") {
duplicatesStrategy = DuplicatesStrategy.INCLUDE
}
}
}
Extra info: I'm using Gradle 7.3-rc-3 and Java 17.
Unfortunately nobody explains reasons for this problem, so here is some of my explorations and guesses. Please correct me if you know more.
If found that following build script code causes this error:
proto { srcDir 'src/main/proto' }
If look inside "build/extracted-include-protos" directory, there are original .proto files copied into "build/extracted-include-protos/test" (but not into main).
My guess is that those auto-copied .proto files are originally uses as the only sources, but when adding "src/main/proto" source set we give some compiler tool second set of same files.
Removing this srcDir is not a good idea, because it required for IDEA to correctly open included .proto on Ctrl+click (otherwise it is opened extracted copies which is useless).

"path must exist" for Cucumber + Spring Boot

I made a Spring Boot 2 application with one endpoint to execute Cucumber test for 5.7.0 version
#PostMapping("/integration")
public Object runCucumber(#RequestBody List<String> request) {
try {
String pathDirectory = "src/main/resources/" + request.get(0);
String response = String.valueOf(Main.run(new String[]{"--glue", //Cucumber type (--glue)
"pmc/aop/integration", // the package which contains the glue classes
pathDirectory} //Step package
, Thread.currentThread().getContextClassLoader()));
return ResponseEntity.ok(request);
} catch (HttpClientErrorException ex) {
log.error(ex.getLocalizedMessage());
return ResponseEntity.status(ex.getStatusCode()).body(ex.getStatusText());
} catch (IllegalArgumentException ex) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ex.getLocalizedMessage());
}
}
The request used
[
"features/local/notify.feature"
]
As you can see I'd like to execute the notify.feature inside of local folder, inside of features folder, inside of resources folder
this is the configuration
#SpringBootTest
#AutoConfigureMockMvc
#CucumberContextConfiguration
#CucumberOptions(features="src/main/resources")
public class CucumberConfiguration {
}
Everything is going good, locally but on my server I got
path must exist: /app/src/main/resources/features/local/heal.feature
What's wrong?
When your application is deployed the src/main/resources/ directory does not exist. You can verify this by inspecting the contents of the jar or war file you've created.
Instead, try locating the feature on the class path. E.g. classpath:com/example/app/my.feature.

Adding a External Folder to the ClassPath in a runnable jar

I have a maven project where I create a jar with dependencies using maven assembly plugin. I also have an external config file ( conf.properties ) that is required by the jar to work properly.
My project structure is like this:
|- abc.jar
|- config
|-conf.properties
How can I add this config folder to the classpath of the jar file? I tried to do this using -cp command and manipulating class-path property in MANIFEST.MF file but no luck so far.
Does anyone know a way to do this?
This is how I tested (sorry, no maven)!
Main class:
package cfh.sf.Chamika;
import java.util.ResourceBundle;
public class ABC {
public static void main(String[] args) {
var bundle = ResourceBundle.getBundle("conf");
System.out.println(bundle.getString("test"));
}
}
Manifest file, note empty line at end (entries must end with a newline (CR, LF or CRLF)):
Manifest-Version: 1.0
Main-Class: cfh.sf.Chamika.ABC
Class-Path: config/
Directory structure
dist/
abc.jar
config/
conf.properties
Content of conf.properties:
test = OK, it is working!
Executed with
java -jar abc.jar
Alternative, not using ResourceBundle:
package cfh.sf.Chamika;
import java.io.IOException;
public class ABC {
public static void main(String[] args) {
try (var input = ClassLoader.getSystemResourceAsStream("conf.properties")) {
int ch;
while ((ch = input.read()) != -1) {
System.out.print((char) ch);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

Deploy java spring-boot app *.jar to heroku with other files in root folder

I have a spring boot app as qsysprereg2-1.0.jar. I pushed into heroku git already compiled jar file + Procfile + folder "config" with files for my app as "config/config.properties". Just some properties.
In Gradle I have only:
apply plugin: 'java'
task stage() {
println("Go stage...")
}
All compiled and deployed successfully.
In result I have error:
java.io.FileNotFoundException: config/config.properties (No such file or directory)
Of course, because:
Running bash on ⬢ qprereg... up, run.9546 (Free)
~ $ ls
Procfile qsysprereg2-1.0.jar system.properties
Where is no folder "config" from git. But "config/config.properties" had been pushed into git.
How to add the folder with files to deploy artifacts?
Sorry, but I did not find a nice solution. I made some tricks. I put all my config files in jar as resources. During starting the app I am checking the files outside jar on dick then coping from resources to dist. New files are keeping on disk without problems. Code for that:
public static void main(String[] args) {
try {
prepareConfig();
} catch (IOException ex) {
log.error("Config prepare fail.", ex);
log.throwing(ex);
throw new RuntimeException(ex);
}
SpringApplication.run(Application.class, args);
}
private static void prepareConfig() throws IOException {
File dir = new File("config");
if (!dir.exists() || !dir.isDirectory()) {
log.info("Create config directory");
Files.createDirectory(dir.toPath());
}
makeReady("config/config1.properties");
makeReady("config/config2.properties");
makeReady("config/config3.properties");
makeReady("config/configN.properties");
}
private static void makeReady(String fileName) throws IOException {
File file = new File(fileName);
if (!file.exists()) {
log.info("Create config file '{}'", file.getName());
try (final InputStream stream = Application.class.getResourceAsStream("/" + fileName)) {
Files.copy(stream, file.toPath());
}
}
}

Categories

Resources