Pass a class as argument to another class Java - java

I am using a data class written in POJO in package myApp. I have another Package UtilLibrary which I have imported as a jar file to the package myApp.
I have developed a method in UtilLibrary by hardcoding the dataclass now I need to remove the same, for which I am looking for solutons to pass the data class as argument. Below is a sample code, any help is really appreciated.
import com.package.dataclasses.TestTable;
public class Sample {
public String putBatchRecords(DynamoDbEnhancedClient enhancedClient, Object tableObj) {
try {
DynamoDbTable<TestTable> objTableMappedClass = enhancedClient.table("Test_Table", TableSchema.fromBean(TestTable.class));
BatchWriteItemEnhancedRequest batchWriteItemEnhancedRequest = BatchWriteItemEnhancedRequest.builder()
.writeBatches(
WriteBatch.builder(TestTable.class)
.mappedTableResource(objTableMappedClass)
.addPutItem(builder -> builder.item((TestTable) tableObj))
.build()
)
.build();
enhancedClient.batchWriteItem(batchWriteItemEnhancedRequest);
}
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "Batch write successful";
}
}
In the above code, i need to remove the import statement - hence pass the TestTable as object to putBatchRecords. Removing the statement shows below errors.

You can change your code like this:
Replace the class name with the fully qualified class name. Then you do not need to import that class.
public class Sample {
public String putBatchRecords(DynamoDbEnhancedClient enhancedClient, Object tableObj) {
try {
DynamoDbTable<com.package.dataclasses.TestTable> objTableMappedClass = enhancedClient.table("Test_Table", TableSchema.fromBean(com.package.dataclasses.TestTable.class));
BatchWriteItemEnhancedRequest batchWriteItemEnhancedRequest = BatchWriteItemEnhancedRequest.builder()
.writeBatches(
WriteBatch.builder(com.package.dataclasses.TestTable.class)
.mappedTableResource(objTableMappedClass)
.addPutItem(builder -> builder.item((com.package.dataclasses.TestTable) tableObj))
.build()
)
.build();
enhancedClient.batchWriteItem(batchWriteItemEnhancedRequest);
}
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "Batch write successful";
}
}
But it is not clear why you need to remove that import. It does not make your code behave differently at runtime, and it does not make it easier to read.
So removing one such import would only be meaningful if you want to remove a name collision with another TestTable class.
I strongly believe you do not want to hardcode against that one class name. Use a common base class, or an interface instead.

Related

JUnit Testing: How to test a custom, empty java class that extends Exception?

I am currently attempting to extend test coverage for a school-based-assignment web application after I came across a completely empty class that extends Exception and contains no coverage according to the coverage report.
Normally, I would assume that something like this could be disregarded. However, our overall test coverage factor directly into our individual grading for this course. Because of this and it being near the end of the semester, I am trying to go through the code flagged within the coverage report line-by-line and tidy up anything I can.
After going through course content and searches online, I am unsure of how to proceed with writing a test for a class such as this. This server-side class was included in our initial code base that was given to us at the start of the semester by the instructor (we build onto the code base as the semester progresses).
The entire code for the Java class:
package <package_name>;
/*
* This is a custom exception that fits our personal
* needs and won't collide with existing issues.
*/
public class BadRequestException extends Exception {}
One example of how the class is used (still code that was provided by instructor):
private String processHttpRequest(spark.Request httpRequest, spark.Response httpResponse, Type requestType) {
setupResponse(httpResponse);
String jsonString = httpRequest.body();
try {
JSONValidator.validate(jsonString, requestType);
Request requestObj = new Gson().fromJson(jsonString, requestType);
return buildJSONResponse(requestObj);
} catch (IOException | BadRequestException e) { // <---- Here
log.info("Bad Request - {}", e.getMessage()); // <----
httpResponse.status(HTTP_BAD_REQUEST);
} catch (Exception e) {
log.info("Server Error - ", e);
httpResponse.status(HTTP_SERVER_ERROR);
}
return jsonString;
}
What I have so far (practically nothing):
package <package_name>;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
public class TestBadRequestException {
#Test
#DisplayName("Test Empty BadRequestException Class")
public void testBadRequestException() {
}
}
Prior to the start of the semester, I had no experience with JUnit. So, any feedback/references/recommendations are greatly appreciated.
EDIT (Solution):
The first comment on this post provided the solution I was looking for. I had not occurred to me that it would be this simple.
The solution is in the answer below with proper credit.
I think write a unit test for that class is unnecessary.
You can try exclude that on your code coverage rules
Solution credit to #f1sh
f1sh's comment (original solution) recommended to add new BadRequestException() within the JUnit test.
This gave an me idea on how I could hopefully improve upon that recommendation.
My final result:
package <package_name>;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
import static org.junit.jupiter.api.Assertions.assertNotNull;
public class TestBadRequestException {
#Test
#DisplayName("Test Empty BadRequestException Class")
public void testBadRequestException() {
assertNotNull(new BadRequestException()); // <---- Here
}
}

How can I set a private class instance variable to the File object used by an unmarshaller without a setter or exposing the variable?

The problem
I'm coding a Java Swing application dealing with XML files, so I'm using JAXB in order to marshal classes into documents and unmarshal the other way around.
I want to include in the class that gets marshalled a private field, that stores the backing file the class is based on (if any), in the form of a File object. In this way, I can determine if a backing file is in use, so that when saving via a Save command, if the backing file is available, I can just marshal the class directly to that file, instead of obtaining it via a "Save file" dialog.
However, it seems that with the tools available in JAXB, I cannot get the File object from the Unmarshaller, while opening it. How can I tackle the situation so that I can set that variable correctly?
As this variable is internal, I don't want to include a setter or expose it so that other classes can't change it.
Background
Being aware of class event callbacks and external listeners, I know I can use a class event callback to set a class instance private field either before or after unmarshalling, but it seems I can't retrieve the file object being in use by the Unmarshaller from inside that callback.
On the other hand, with an external listener I could get ahold of the File object being unmarshalled, as it would be at the same level with the unmarshal method call, but now the private field would either need to be public or has to include a setter in order for it to be set.
Sample code
The following is a minimal, reproducible example, split in two files: JAXBTest.java and MarshalMe.java, both placed at the same level.
MarshalMe.java
import java.io.File;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class MarshalMe {
private File backingFile;
public File getBackingFile() {
return backingFile;
}
// Dummy function that sets the backing file beforehand.
public void processSth() {
backingFile = new File("dummy.hai");
}
}
JAXBDemo.java
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class JAXBTest {
public static void writeXML(MarshalMe me, File xml) {
try {
JAXBContext contextObj = JAXBContext.newInstance(MarshalMe.class);
Marshaller marshallerObj = contextObj.createMarshaller();
marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshallerObj.marshal(me, new FileOutputStream(xml));
} catch (JAXBException jaxbe) {
jaxbe.printStackTrace();
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
}
public static MarshalMe readXML(File xml) {
MarshalMe me = null;
try {
JAXBContext contextObj = JAXBContext.newInstance(MarshalMe.class);
Unmarshaller unmarshallerObj = contextObj.createUnmarshaller();
me = (MarshalMe) unmarshallerObj.unmarshal(xml);
} catch (JAXBException jaxbe) {
jaxbe.printStackTrace();
}
return me;
}
public static void main(String[] args) {
MarshalMe src = new MarshalMe();
src.processSth();
System.out.println(src.getBackingFile());
File meFile = new File("me.xml");
writeXML(new MarshalMe(), meFile);
MarshalMe retrieved = readXML(meFile);
System.out.println(retrieved.getBackingFile());
}
}
Expected output
Running with Java 1.8 (or later, provided a JAXB library and runtime implementation is accesible), the minimal, reproducible example outputs:
dummy.hai
null
when I expect the output to be
dummy.hai
me.xml
as the class is initially written in a XML file named me.xml before being read back.
I've found a way to set the private field without exposing it or giving it a setter: Reflection.
Using external event listeners, I can get ahold of the File object. Then, inside the beforeUnmarshal method, and after checking that I got the correct object, I use reflection to get the private field, and with the setAccessible method, I can now control when I get access to the field using reflection only.
After lifting the access checks, it's only a matter of editing the value via setting it, and reinstating the checks after that.
Relevant changes
The following snippet includes the relevant changes:
unmarshallerObj.setListener(new Unmarshaller.Listener() {
#Override
public void beforeUnmarshal(Object target, Object parent) {
if (!(target instanceof MarshalMe))
return;
MarshalMe me = (MarshalMe) target;
try {
Field meBackingFile = MarshalMe.class.getDeclaredField("backingFile");
meBackingFile.setAccessible(true);
meBackingFile.set(me, xml);
meBackingFile.setAccessible(false);
} catch (NoSuchFieldException nsfe) {
} catch (IllegalAccessException iae) {}
}
});
Including the edit in the sample program
Edit the file JAXBDemo.java by adding the following code:
// Add to the import section
import java.lang.reflect.Field;
// Under this function
public static MarshalMe readXML(File xml) {
MarshalMe me = null;
try {
JAXBContext contextObj = JAXBContext.newInstance(MarshalMe.class);
Unmarshaller unmarshallerObj = contextObj.createUnmarshaller();
/* Add this code vvv */
unmarshallerObj.setListener(new Unmarshaller.Listener() {
#Override
public void beforeUnmarshal(Object target, Object parent) {
if (!(target instanceof MarshalMe))
return;
MarshalMe me = (MarshalMe) target;
try {
Field meBackingFile = MarshalMe.class.getDeclaredField("backingFile");
meBackingFile.setAccessible(true);
meBackingFile.set(me, xml);
meBackingFile.setAccessible(false);
} catch (NoSuchFieldException nsfe) {
} catch (IllegalAccessException iae) {}
}
});
/* Add this code ^^^ */
me = (MarshalMe) unmarshallerObj.unmarshal(xml);
} catch (JAXBException jaxbe) {
jaxbe.printStackTrace();
}
return me;
}
After adding the import and the code between the /* Add this code */ lines, running the program again now outputs:
dummy.hai
me.xml
as expected.

MyObjectBox is red/not found but Java app still works

I'm trying to use ObjectBox in a simple java server side app.
Everything is working fine, I'm putting things in boxes etc, but the MyObjectBox class is always red when I use it.
I can see the generated .class and .java files, along with the meta _ classes, in build/classes/main/db (db is the package name I have in my actual code), but for some reason I can't import MyObjectBox.
Because of this, I also can't import the _ classes for use in Queries, which now kind of prevents me from getting any further.
My code to use objectBox is inside a class called DB which I have copied below, in case there's anything I'm doing wrong with that.
But as it actually works, I'm very confused!!
Thanks
UPDATE: if I run gradle clean build, my app runs fine, if I run Build->Build Project in intelliJ then I get the error
Error:(27, 21) java: cannot find symbol
symbol: variable MyObjectBox
location: class DB
.
package db;
import java.io.File;
import java.io.IOException;
import io.objectbox.Box;
import io.objectbox.BoxStore;
public class DB {
private File boxStoreDir;
private static BoxStore store;
public DB() {
try {
createMyObjectBox();
} catch (IOException e) {
e.printStackTrace();
}
}
private void createMyObjectBox() throws IOException {
File objectstorefile = new File("../objectBox/objectstorefile");
if(!objectstorefile.isDirectory()) {
objectstorefile.mkdirs();
}
boxStoreDir = objectstorefile;
if(store == null) {
store = MyObjectBox.builder().directory(boxStoreDir).build();
}
}
public<T> Box<T> getBox(Class<T> object) {
if(store == null) {
try {
createMyObjectBox();
} catch (IOException e) {
e.printStackTrace();
}
}
return store.boxFor(object);
}
}
Forget the apply plugin: 'net.ltgt.apt-idea' in build.gradle

"Attributes and objects cannot be resolved" - error

The following code is for reading or writing files with java, but:
Eclipse prints these errors:
buffer_1 cannot be resolved to a variable
file_reader cannot be resolved
also other attributes...
what is wrong in this code here:
//Class File_RW
package R_2;
import java.io.File;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.lang.NullPointerException;
public class File_RW {
public File_RW() throws FileNotFoundException, NullPointerException {
File file_to_read = new File("C:/myfiletoread.txt");
FileReader file_reader = new FileReader(file_to_read);
int nr_letters = (int)file_to_read.length()/Character.BYTES;
char buffer_1[] = new char[nr_letters];
}
public void read() {
file_reader.read(buffer_1, 0, nr_letters);
}
public void print() {
System.out.println(buffer_1);
}
public void close() {
file_reader.close();
}
public File get_file_to_read() {
return file_to_read;
}
public int get_nr_letters() {
return nr_letters;
}
public char[] get_buffer_1() {
return buffer_1;
}
//...
}
//main method # class Start:
package R_2;
import java.io.File;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.lang.NullPointerException;
public class Start {
public static void main(String[] args) {
File_RW file = null;
try {
file = new File_RW();
} catch (NullPointerException e_1) {
System.out.println("File not found.");
}
//...
}
}
I can't find any mistake. I have also tried to include a try catch statement into the constructor of the class "File_RW", but the error messages were the same.
Yes, there are errors in your code - which are of really basic nature: you are declaring variables instead of fields.
Meaning: you have them in the constructor, but they need to go one layer up! When you declare an entity within a constructor or method, then it is a variable that only exists within that constructor/method.
If you want that multiple methods can make use of that entity, it needs to be a field, declared in the scope of the enclosing class, like:
class FileRW {
private File fileToRead = new File...
...
and then you can use your fields within all your methods! Please note: you can do the actual setup within your constructor:
class FileRW {
private File fileToRead;
public FileRW() {
fileToRead = ..
but you don't have to.
Finally: please read about java language conventions. You avoid using "_" within names (just for SOME_CONSTANT)!
javacode already running...thx
same program edited with c++ in visual Studio express...
visit the stackoverflow entry link:
c++ file read write-error: Microsoft Visual C++ Runtime libr..debug Assertion failed, expr. stream.valid()

How to implement a SocketImplFactory using systems default sockets

I have a small problem with implementing a own SocketImplFactory in Java.
My goal is to write a factory which offers me a way to close all open sockets with one simple method call. So I only want to have a kind of "proxy factory" which stores all the created sockets in a list. On this list I could perform all the actions I need.
I tried to implement it like this:
package java.net;
import java.io.IOException;
import java.net.SocketImpl;
import java.net.SocketImplFactory;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.io.IOUtils;
import com.crosscloud.applicationlayer.logger.CCLogger;
public class CCSocketImplFactory implements SocketImplFactory
{
private List<SocketImpl> _openSockets;
public CCSocketImplFactory()
{
_openSockets = new LinkedList<>();
}
#Override
public SocketImpl createSocketImpl()
{
SocketImpl impl = new SocksSocketImpl();
_openSockets.add(impl);
return impl;
}
public void closeAll()
{
_openSockets.forEach((socket)->
{
try
{
socket.close();
}
catch (Exception e)
{
logException(this, e);
}
});
}
public static CCSocketImplFactory register()
{
CCSocketImplFactory fact = new CCSocketImplFactory();
try
{
Socket.setSocketImplFactory(fact);
}
catch (IOException e)
{
logException(CCSocketImplFactory.class, e);
}
return fact;
}
The problem I have now is that I have to create the class in the package java.net because the class SocksSocketImpl(In my opinion this should be the standard type) is only visible in this package.
When I now want to run the code I get a SecurityException because the package name is probhibited.
Is there a workaround for my problem?
Thank you!
It appears that you are trying to use only one class from java.net There is no need to move you class tot hat package just to create an instance of it. I suggest using reflection instead.
Constructor cons = Class.forName("java.net.SocksSocketImpl").getDeclaredConstructor();
cons.setAccessible(true);
SocketImpl si = (SocketImpl) cons.newInstance();
However using SOCKS by default is likely to be a bad idea as it will change the default not just for your sockets, but all sockets even ones for internal use such as JMX or VisualVM.
What would be an alternative instead of always using SocksSocketImpl?
I also found this example which shows some extended possibilities of this method.
Finding out what network sockets are open in the current Java VM

Categories

Resources