Caused by: java.lang.NoClassDefFoundError: software/constructs/Construct - java

I’m beginner to Terraform CDK. I’ve created simple code in terraform CDK to create an EC2 instance. but here instead of run cdktf deploy in terminal I’m calling is via java processbuilder inside my main method.
Every thing good till now. My Code is compile successful and Jar build. But we I run the jar by command java -jar target/ getting the below error.
└─[$] java -jar target/irm-1.0-SNAPSHOT.jar [0:24:43]
Error: Unable to initialize main class com.example.test.Main
Caused by: java.lang.NoClassDefFoundError: software/constructs/Construct
Here is the my file structure
Here is the Main.java
package com.example.test;
import com.hashicorp.cdktf.App;
import com.hashicorp.cdktf.TerraformStack;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException {
final App app = new App();
TerraformStack stack = new MainStack(app, "aws_instance");
// new RemoteBackend(stack, RemoteBackendProps.builder()
// .hostname("app.terraform.io")
// .organization("<YOUR_ORG>")
// .workspaces(new NamedRemoteWorkspace("learn-cdktf"))
// .build());
app.synth();
//calling cdktf deploy
List<String> list = new ArrayList<String>();
list.add("/usr/local/bin/cdktf");
list.add("deploy");
// create the process
ProcessBuilder build = new ProcessBuilder(list);
// starting the process
Process process = build.start();
// for reading the output from stream
BufferedReader stdInput
= new BufferedReader(new InputStreamReader(
process.getInputStream()));
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
}
}
Here is the MainStack.java
package com.example.test;
import software.constructs.Construct;
import com.hashicorp.cdktf.TerraformStack;
import com.hashicorp.cdktf.TerraformOutput;
import com.hashicorp.cdktf.providers.aws.AwsProvider;
import com.hashicorp.cdktf.providers.aws.ec2.Instance;
public class MainStack extends TerraformStack
{
public MainStack(final Construct scope, final String id) {
super(scope, id);
AwsProvider.Builder.create(this, "AWS")
.region("ap-south-1")
.build();
Instance instance = Instance.Builder.create(this, "compute")
.ami("ami-0e18b1d379af4e263")
.instanceType("t3a.micro")
.build();
TerraformOutput.Builder.create(this, "public_ip")
.value(instance.getPublicIp())
.build();
}
}

There are two problems I can spot here:
The error you are getting hints towards the construct package not being installed in this project. I'd recommend using the "normal" workflow of running your cdktf program by running cdktf synth or cdktf deploy in the CLI. You can also compile your program (it it's a standard program like we initialize it) by running mvn -e -q compile
It seems like you are trying to execute deploy from within your cdktf program. This won't work, it will create an infinite loop since this program is being run by the synth operation that is being run before the deploy executes. If you want to start cdktf programmatically it has to be from another program that is independent from you CDKTF application

Related

AWS EC2 java run error: Could not find or load main class

I'm new to the AWS EC2, and I want to run a java class MyServer in an EC2 instance by executing a run.sh script that looks like this:
#!/bin/sh
cd /home/ec2-user/
java MyServer
MyServer.java
package server;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Random;
public class MyServer {
public static void main(String[] args) throws IOException {
String jokes[] = {"j1", "j2", "j3"};
ServerSocket socket = new ServerSocket(9000);
while(true){
Socket s = socket.accept();
PrintWriter print = new PrintWriter(s.getOutputStream(), true);
String ip = (InetAddress.getLocalHost().getHostAddress());
print.println(ip+jokes[(int)(Math.random()*(jokes.length-1))]);
s.close();
print.close();
}
}
}
I compiled the code by installing the compiler yum install java-devel and then javac MyServer.java
The instance's current work directory is /home/ec2-user, and I have MyServer.class and run.sh in this folder.
When I execute sh run.sh in the instance, I received Error: Could not find or load main class MyServer Caused by: java.lang.NoClassDefFoundError: server/MyServer (wrong name: MyServer)
I tried to solve it by using different class names in the .sh script, ie server.MyServer, MyServer.class but none of them works.
Change your shell script to something like this:
#!/bin/sh
(cd /home/ec2-user/ && java MyServer)
Otherwise, by the time the shell interpreter reaches java MyServer the current directory has changed back to the original current directory.
The problem is that you have a package called server and you are ignoring it in your bash script. Check whether /home/ec2-user/ have got the folder server or not. If compilation is successful then it will have it.
Next, modify your script with java server.MyClass without entering into server folder(package), and you shall be able to execute it successfully.
I have been able to execute this code on my local system:
package server;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Random;
public class MyServer {
public static void main(String[] args) throws IOException {
String jokes[] = {"j1", "j2", "j3"};
System.out.println("Server Started!");
ServerSocket socket = new ServerSocket(9000);
while(true){
Socket s = socket.accept();
PrintWriter print = new PrintWriter(s.getOutputStream(), true);
String ip = (InetAddress.getLocalHost().getHostAddress());
print.println(ip+jokes[(int)(Math.random()*(jokes.length-1))]);
s.close();
print.close();
}
}
}
This is the shell code for compiling and running:
saad#saadsap:~/java_barebone$ javac server/* -d out/
saad#saadsap:~/java_barebone$ cd out/
saad#saadsap:~/java_barebone/out$ java server.MyServer
Server Started!
Note: Flag -d is for destination folder which can be omitted.
After removing package server; from the code, it works. It seems that the package was added by java automatically.

How to Run Java Code from Gradle at Build Time

I'm using jsonschema-generator to generate a JSON schema file based on my POJOs. Currently I'm doing it via a test that is run during the gradle build step. This works fine but it doesn't feel right as really what I'm doing is not testing anything.
I've also found this answer which details how to run it on gradle run but this is not ideal either as it will pointlessly execute this every time the application comes up but not when I build.
Therefore, is there a way to tell gradle (in build.gradle) to run a piece of Java code at build time?
For completeness, here the code I'm looking to run:
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.victools.jsonschema.generator.Option;
import com.github.victools.jsonschema.generator.OptionPreset;
import com.github.victools.jsonschema.generator.SchemaGenerator;
import com.github.victools.jsonschema.generator.SchemaGeneratorConfig;
import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;
import com.mypackage.MyClass;
import org.junit.jupiter.api.Test;
import java.io.PrintWriter;
import java.util.Map;
#SuppressWarnings({"FieldCanBeLocal", "rawtypes"})
public class JsonSchemaGenerator {
private final String SCHEMA_FOLDER = "schemas/";
private final Map<Class, String> schemaToGenerate = Map.of(
MyClass.class, "my-class.schema"
);
#Test
public void generateJsonSchema() throws Exception {
SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(new ObjectMapper(), OptionPreset.PLAIN_JSON);
SchemaGeneratorConfig config = configBuilder.with(Option.DEFINITIONS_FOR_ALL_OBJECTS).build();
SchemaGenerator generator = new SchemaGenerator(config);
for (var entry : schemaToGenerate.entrySet()) {
JsonNode jsonSchema = generator.generateSchema(entry.getKey());
PrintWriter out = new PrintWriter(SCHEMA_FOLDER + entry.getValue());
out.println(jsonSchema.toPrettyString());
out.close();
}
}
}
The JavaExec Plugin seems to meet your requirements.
This allows you to run a main() method and thereby any Java Code you want – including whatever JSON Schema generation you like.
This other answer also describes pretty much what you want to do.
Adapted from the linked documentation:
apply plugin: 'java'
task generateJsonSchema(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'package.Main'
// arguments to pass to the application
args 'appArg1'
}
As per Jorn's comment below:
You can depend the build task on your custom task: build.dependsOn generateJsonSchema if your custom task is defined as task generateJsonSchema(type: JavaExec) { ... }

Could not find or load main class FaceDetect in java with angus.ai

I get the following error when I try to run
java -cp 'angus-sdk-java-0.0.2-jar-with-dependencies.jar:.' FaceDetect
I am following a tutorial for face detection in http://angus-doc.readthedocs.io/en/latest/getting-started/java.html . Below is my java code,
import java.io.IOException;
import org.json.simple.JSONObject;
import ai.angus.sdk.Configuration;
import ai.angus.sdk.Job;
import ai.angus.sdk.ProcessException;
import ai.angus.sdk.Root;
import ai.angus.sdk.Service;
import ai.angus.sdk.impl.ConfigurationImpl;
import ai.angus.sdk.impl.File;
public class FaceDetect {
public static void main(String[] args) throws IOException, ProcessException {
Configuration conf = new ConfigurationImpl();
Root root = conf.connect();
Service service = root.getServices().getService("age_and_gender_estimation", 1);
JSONObject params = new JSONObject();
params.put("image", new File("Downloads/IMG_1060.jpg"));
Job job = service.process(params);
System.out.println(job.getResult().toJSONString());
}
}
I don't understand the problem with it. I have tried all the answers in the stack overflow but nothing is working for me.
remove the single qoutes around the classpath:
java -cp angus-sdk-java-0.0.2-jar-with-dependencies.jar:. FaceDetect

How to run Spring Shell scripts in a JUnit test

I have a Spring Shell-based application and a couple of scripts. Is there an easy way to run the scripts in a JUnit test such that a test fails, if some exception/error occurs during the execution of the script?
The purpose of the tests is to make sure that all correct scripts run without errors.
Update 1:
Here's a little helper class for running scripts in JUnit:
import org.apache.commons.io.FileUtils;
import org.springframework.shell.Bootstrap;
import org.springframework.shell.core.CommandResult;
import org.springframework.shell.core.JLineShellComponent;
import java.io.File;
import java.io.IOException;
import java.util.List;
import static org.fest.assertions.api.Assertions.*;
public class ScriptRunner {
public void runScript(final File file) throws IOException
{
final Bootstrap bootstrap = new Bootstrap();
final JLineShellComponent shell = bootstrap.getJLineShellComponent();
final List<String> lines = FileUtils.readLines(file);
for (final String line : lines) {
execVerify(line, shell);
}
}
private void execVerify(final String command, final JLineShellComponent shell) {
final CommandResult result = shell.executeCommand(command);
assertThat(result.isSuccess()).isTrue();
}
}
You can create an instance of Bootstrap, get the shell out of it and then executeCommand() (including the shell command) on it.
You may be interested in what is done in Spring XD for this: https://github.com/spring-projects/spring-xd/blob/master/spring-xd-shell/src/test/java/org/springframework/xd/shell/AbstractShellIntegrationTest.java (although there are a lot of XD specific details)

External library not available when deploy with fat-jar

I'm using in my program the bluecove library.
While running the program via eclipse, all works smooth. I'm now trying to deploy my program, and following this post i'm using fat-jar.
When i run the jar file (created by fat-jar), the library can't be located, and i'm getting the exception BlueCove libraries not available as result of this line local = LocalDevice.getLocalDevice();.
In the fat-jar window i tried also to add bluecove-2.1.0.jar to the Class-Path place, and also with the path \src\JoJoServer\bluecove-2.1.0.jar.
I tried also to place the bluecove's jar file in different folders, such as the src, or an external folder.
Although i know it's not recommended, i tried the option of One-Jar, nevertheless it didn't help.
To run the jar (the one created by fat jar) i simply double click the file.
What i'm missing?
This is the entire code:
import java.io.IOException;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
#Override
public void run() {
// retrieve the local Bluetooth device object
LocalDevice local = null;
StreamConnectionNotifier notifier;
StreamConnection connection = null;
// setup the server to listen for connection
try {
local = LocalDevice.getLocalDevice();
local.setDiscoverable(DiscoveryAgent.GIAC);
UUID uuid = new UUID("0000110100001000800000805F9B34FB", false);
System.out.println(uuid.toString());
String url = "btspp://localhost:" + uuid.toString() + ";name=RemoteBluetooth";
notifier = (StreamConnectionNotifier)Connector.open(url);
} catch (BluetoothStateException e) {
System.out.println("Bluetooth is not turned on.");
e.printStackTrace();
return;
}
// ...
}
I have no clue what could be your problem, but I've tried the process and everything works, so just a summary of what I've did. Maybe you will figure it out by following it...
I don't understand how the posted code could be the entire, I see no class definition. :)
So I've modified it to the main method and it works both from the Eclipse and also by running the JAR generated by the FatJar.
The modified code of the BTTest class:
package test;
import java.io.IOException;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
public class BTTest {
public static void main(String[] args) throws Exception{
// retrieve the local Bluetooth device object
LocalDevice local = null;
StreamConnectionNotifier notifier;
StreamConnection connection = null;
// setup the server to listen for connection
try {
local = LocalDevice.getLocalDevice();
local.setDiscoverable(DiscoveryAgent.GIAC);
UUID uuid = new UUID("0000110100001000800000805F9B34FB", false);
System.out.println(uuid.toString());
String url = "btspp://localhost:" + uuid.toString()
+ ";name=RemoteBluetooth";
notifier = (StreamConnectionNotifier) Connector.open(url);
} catch (BluetoothStateException e) {
System.out.println("Bluetooth is not turned on.");
e.printStackTrace();
return;
}
// ...
}
}
To run or produce it, I have just put the bluecove library in the build path and created the fat jar with a simple way:
http://oi60.tinypic.com/vg1jpt.jpg
Starting the generated jar from command line:
D:\testProjects\bttest>java -jar bttest_fat.jar
BlueCove version 2.1.0 on winsock
0000110100001000800000805f9b34fb
BlueCove stack shutdown completed
Can you post a difference to your process?

Categories

Resources