I need to use a native pointer (an int) for an LWJGL project, and the tutorial I'm following proposes to use the Object.finalize() method. But, since it's deprecated since Java 9, I looked for better solutions. I found the Cleaner/Cleanable duo on the Oracle documentation and tried to use it, but I don't know if I'm doing it right. Is this the way to go?
import java.lang.ref.Cleaner;
public class PointerUsingObject
{
// A native pointer
private int pointer;
private static final Cleaner cleaner = Cleaner.create();
private final Cleaner.Cleanable cleanable;
public PointerUsingObject()
{
cleanable = cleaner.register(this, new Runnable()
{
#Override
public void run()
{
// Free the pointer
}
});
}
// Is called to destroy the object when I'm sure not to use it anymore
public void destroy()
{
cleanable.clean();
}
}
OK, so as someone pointed out, I should instantiate a static nested class to manage the cleaning, as following:
import java.lang.ref.Cleaner;
public class PointerUsingObject implements AutoCloseable
{
// A native pointer
private int pointer;
private static final Cleaner cleaner = Cleaner.create();
private final Cleaner.Cleanable cleanable;
public PointerUsingObject()
{
cleanable = cleaner.register(this, new CleanMethod(pointer));
}
#Override
public void close() throws Exception
{
cleanable.clean();
}
private static class CleanMethod implements Runnable
{
private int pointer;
public CleanMethod(int pointer)
{
this.pointer = pointer;
}
#Override
public void run()
{
// Free the pointer
}
}
}
I also implemented the AutoCloseable interface and replaced the destroy() method with the close() method.
Related
I am trying to solve statediagram exercise, but still have not understood why my code does not work.
I chave already cheked all possible code examles of code, but have not understood why mine version does not pass any tests.May be I chve some sort of small mistake which not easy to see. Below I provide my code, test semples and digramms I have.
https://drive.google.com/open?id=1SQAiwUBo1OwI-QKksxciDS7dEdKGS6dn [1]
https://drive.google.com/open?id=1JhdScK7t1XmNc3eLT7hSGpwyYDLWl46T [2]
public class GarageDoor {
private Motor motor;
private DoorState currentState;
public GarageDoor() {
this.setState(new Closed(this));
//currentState=new Closed(this);
}
public void openDoor(){
currentState.openDoor();
}
public void stopper(){
currentState.stopper();
}
public void closeDoor(){
currentState.closeDoor();
}
public Motor getMotor(){
return this.motor;
}
private void setState(DoorState ds){
this.currentState=ds;
}
public abstract class DoorState{
public abstract void openDoor();
public abstract void closeDoor();
public abstract void stopper();
}
public class Closed extends DoorState{
private GarageDoor garageDoor;
public Closed(GarageDoor garageDoor){
this.garageDoor=garageDoor;
}
#Override
public void openDoor() {
garageDoor.setState(new Opening(garageDoor));
garageDoor.getMotor().upwards();
}
#Override
public void closeDoor() {
throw new IllegalStateException();
}
#Override
public void stopper() {
throw new IllegalStateException();
}
}
}
Actually I cann not execute main()
public static void main(String[] args){
//Motor motor=new Motor();
GarageDoor gd=new GarageDoor();
gd.openDoor();
}
I don't see that you're setting motor anywhere, so in Closed.openDoor, when you call garageDoor.getMotor().upwards() you'll get a NullPointerException.
Also, I see that you're passing GarageDoor in to the Closed state and then calling garageDoor.setState. Consider just returning the next state from each DoorState method.
1) Try having GarageDoor extend DoorState, seems to override the same methods.
2) Nowhere in your code do you actually create the Motor in the GarageDoor class.
You need to initiate the Motor, e.g:
public GarageDoor() {
this.motor = new Motor();
}
I ve been looking into CDI to simplify the code, and I ve been trying to use it with Java EE 8. I an trying to replicate an existing exemple without success. I was wondering if anyone might have experienced the same issue:
The PoolManager Class:
import javax.ejb.Startup;
import javax.ejb.Singleton;
import javax.annotation.PostConstruct;
#Singleton
#Startup
public class PoolManager {
private Queue<Object> pooledObjects;
#PostConstruct
private void init() {
System.out.println("Hi");
pooledObjects = new LinkedBlockingQueue<Object>(1_000);
for (int i = 0; i <= 1000; i++) {
pooledObjects.offer(i);
}
}
public void returnObject(Object o) {
pooledObjects.offer(o);
}
public Object borrowObject() {
return pooledObjects.poll();
}
}
the UsePoolManager Class:
public class UsePoolManager {
#Inject
private PoolManager poolManager;
public void usePooledObject() {
Object object = this.poolManager.borrowObject();
System.out.println(object);
}
}
and the Main:
public static void main(String[] args) {
UsePoolManager user = new UsePoolManager();
user.usePooledObject();
}
}
The injection doesn t seem to be working at all at runtime. I have no beans xml (i understand it is not necessary, and adding it didnt change anything.).
Any help would be greatly appreciated.
Thanks!
Checking whether I am using SE or EE for clarification...
You need to run that in JavaEE container like JBoss or Tomcat, not like standalone JavaSE application (with publis static void main)
For the sake of argumentation, using the CDI 2 container for Java SE:
in Gradle:
// https://mvnrepository.com/artifact/org.jboss.weld.se/weld-se-core
compile group: 'org.jboss.weld.se', name: 'weld-se-core', version: '3.0.4.Final'
public class CDI2Fire {
public static void main(String[] args) {
SeContainerInitializer initializer =
SeContainerInitializer.newInstance();
try (SeContainer container = initializer.disableDiscovery().addPackages(CDI2Fire.class).initialize()) {
container.select(UsePoolManager.class);
}
}
}
#ApplicationScoped
public class UsePoolManager {
#Inject
private PoolManager poolManager;
public void init(#Observes #Priority(Interceptor.Priority.APPLICATION - 100)
#Initialized(ApplicationScoped.class) Object init) throws Exception{
usePooledObject();
}
public void usePooledObject() {
Object object = this.poolManager.borrowObject();
System.out.println(object);
}
}
#Singleton
#Startup
public class PoolManager {
private Queue<Object> pooledObjects;
#PostConstruct
private void init() {
System.out.println("Hi");
pooledObjects = new LinkedBlockingQueue<Object>(1_000);
for (int i = 0; i <= 1000; i++) {
pooledObjects.offer(i);
}
}
public void returnObject(Object o) {
pooledObjects.offer(o);
}
public Object borrowObject() {
return pooledObjects.poll();
}
}
Regarding you own answer: you changed the complete application logic by moving the business method call usePooledObject() into the initialization listener instead of calling it manually as in the original example.
This is probably not the best idea, as objects which wildly run on arbitrary initialization events are very hard to control.
Thus: the point that you probably missed is, using get() after select():
try (SeContainer ...) {
// replaces the original "new":
UsePoolManager user = CDI.current().select(UsePoolManager.class).get();
user.usePooledObject();
}
Further note, that the use of CDI.current() eliminates the necessity to have a concrete container reference in scope. Thus, you can use it everywhere in your application as long as the container is active.
Does Java have anything similar to C#'s Action type? Is Java 8 or Pre-Java 8 the way to go? Why or why not? I'm trying to avoid going down any rabbit holes. Please help me understand my options...
Statement:
Driver.NoWait(() => links = rowFindElements(ByLinkText(title)));
Methods:
public static void NoWait(Action action)
{
TurnOffWait();
action();
TurnOnWait();
}
public static void TurnOnWait()
{
Instance.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5));
}
public static void TurnOffWait()
{
Instance.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(0));
}
UPDATE
Thanks to #Nick Y and a programmer at the office (who told me the history of Java pragmatics vs Java traditionalists). This is the outcome of my findings:
Feature Menu Class 1st Way Post Java 8
public class FeatureMenu
{
static WebElement sideTab;
public static void Expand()
{
try
{
Iframe.Default.SwitchTo();
Driver.NoWait(() -> sideTab = Driver.Instance.findElement(By.cssSelector("div.wijmo-wijsplitter-v-panel1-collapsed")));
sideTab.click();
Log.Info("Feature Menu Expanded.");
}
catch(Exception e)
{
Log.Error("[EXCEPTION CAUGHT] : FeatureMenu.Expand()");
throw(e);
}
}
}
Feature Menu 2nd Way Pre Java 8
public class FeatureMenu
{
static WebElement sideTab;
public static void Expand()
{
try
{
Iframe.Default.SwitchTo();
Driver.NoWait( new Driver.Action(){ public void apply(){
sideTab = Driver.Instance.findElement(By.cssSelector("div.wijmo-wijsplitter-v-panel1-collapsed"));
}
});
sideTab.click();
Log.Info("Feature Menu Expanded.");
}
catch(Exception e)
{
Log.Error("[EXCEPTION CAUGHT] : FeatureMenu.Expand()");
throw(e);
}
}
}
Driver Class that can be used with either approach
public class Driver
{
public static WebDriver Instance;
public static String BaseAddress(String baseAddress)
{
return baseAddress;
}
public static void Initialize(String driverType)
{
Instance = new FirefoxDriver();
Instance.manage().window().maximize();
TurnOnWait();
}
#FunctionalInterface
public interface Action {
void apply();
}
public static void NoWait(Action action)
{
TurnOffWait();
action.apply();
TurnOnWait();
}
public static void TurnOffWait()
{
Instance.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
}
public static void TurnOnWait()
{
Instance.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
}
}
If you want to get closer to the most recent C# version you would want to use Java 8 (not pre-Java 8)
Java 8 has lambdas and functional interfaces which can get you very close to how things are done in C#. Google "functional interface java". There is a lot good information out there.
In the context of your specific question think about functional interfaces in java as delegates in C#.
public delegate void Action()
can be mimicked in java 8 as
#FunctionalInterface
public interface Action() {
void apply();
}
With this in mind, here is the simple usage of Action interface and lambda
public class MainWithAction {
public static void main(String[] args) {
noWait(() -> doSomething());
}
public static void noWait(Action action) {
turnOffWait();
action.apply();
turnOnWait();
}
public static void doSomething() { /* do something */ }
public static void turnOnWait() { /* skipped */ }
public static void turnOffWait() { /* skipped */ }
}
It is not a requirement to use #FunctionalInterface annotation but it helps compiler to generate error messages in certain cases.
apply() method name can be changed to anything else it is more of a convention thing.
Java 8 has a few predefined functional interfaces in package java.util.function however it appears that there is nothing that returns void and takes no parameters so you would need to have your own. Read more here:
https://softwareengineering.stackexchange.com/questions/276859/what-is-the-name-of-a-function-that-takes-no-argument-and-returns-nothing
You may want to consider having NoWaitAction interface which can be a more appropriate name for your scenario instead of a generic Action interface. It's up to you.
Having said all that I am moving to more interesting point of going down the rabbit hole.
Your particular use case may not map 100% into the java code. Let's try to convert this line.
Driver.NoWait(() => links = rowFindElements(ByLinkText(title)));
What caught my eye here is the links variable. It does look like a local variable to me. If this is not the case then the bellow is irrelevant, but may still trigger some thoughts.
For the sake of this exercise I am going to assume that links is a local variable of List of Strings type and rowFindElements takes String parameter and returns a List of Strings
Here is one way of converting this into java (with NoWaitAction as an example of my above point):
#FunctionalInterface
public interface NoWaitAction {
void apply();
}
and the meat
public class MainNoWaitAction {
public static void main(String[] args) {
List<String> links = new ArrayList<>();
String title = "title";
noWait(() -> links.addAll(rowFindElements(title)));
}
public static void noWait(NoWaitAction action) {
turnOffWait();
action.apply();
turnOnWait();
}
public static void turnOnWait() { /* skipped */ }
public static void turnOffWait() { /* skipped */ }
public static List<String> rowFindElements(String title) {
return new ArrayList<>(); // populate the list
}
}
There are various other ways of doing it, but the main point here is that the following will not compile
noWait(() -> links = rowFindElements(title));
Why? Read this answer for example
https://stackoverflow.com/a/4732617/5947137
Update 1
Based on OP comments I would like to suggest another approach
public class MainNoWaitAction {
public static void main(String[] args) {
List<String> links;
Object otherVariable;
String title = "title";
links = noWait(() -> rowFindElements(title));
otherVariable = noWait(() -> createAnObject());
}
public static <T> T noWait(Supplier<T> supplier) {
turnOffWait();
try {
return supplier.get();
} finally {
turnOnWait();
}
}
private static void turnOnWait() { /* skipped */ }
private static void turnOffWait() { /* skipped */ }
private static List<String> rowFindElements(String title) {
return new ArrayList<>(); // populate the list
}
private static Object createAnObject() {
return new Object();
}
}
Yes, you can write code the same way in Java :
public interface Action {
void apply();
}
public static void DoSomething(Action action)
{
action.apply();
}
public static void main(String[] args) throws IOException {
DoSomething(() -> System.out.println("test action"));
}
I am dealing with the text extraction from pdf. To this end I wrote my own text extraction
strategy. I have one dynamic class and within this class i invoke text extraction strategy.
However, when i introduce some parameters to my dynamic class i cannot use them within strategy class. To be clear i am adding my code template below.
My question is briefly, is it possible to invoke parameter unq showing up in "get_intro" class, from renderText? Or other way around, can a variable or parameter created inside the "renderText" class be invoked in the "get_intro"?
public class trial {
public trial(){}
public Boolean get_intro(String pdf, String unq){
try { ....
for (int j = 1; j <= 3; j++) {
out.println(PdfTextExtractor.getTextFromPage(reader, j, semTextExtractionStrategy));
}
...} catch (Exception e) {
e.printStackTrace();
}
semTextExtractionStrategy part:
public class SemTextExtractionStrategy implements TextExtractionStrategy {
#Override
public void beginTextBlock() {
}
#Override
public void renderText(TextRenderInfo renderInfo) {
text = renderInfo.getText();...}
#Override
public void endTextBlock() {
}
#Override
public void renderImage(ImageRenderInfo renderInfo) {
}
#Override
public String getResultantText() {
//return text;
return main;
}
}
One could consider the following problematic solution:
public abstract class DefaultTextExtractionStrategy<D>
implements TextExtractionStrategy {
protected D documentInfo;
public final void setDocumentInfo(D documentInfo) {
this.documentInfo = documentInfo;
}
public class SemTextExtractionStrategy extends DefaultTextExtractionStrategy<SemDoc> {
#Override
public void beginTextBlock() {
documentInfo ...
}
public class SemDoc {
public String unq:
}
And in get_intro:
SemDoc semDoc = new SemDoc();
semDoc.unq = unq;
semTextExtractionStrategy.setDocumentInfo(semDoc);
out.println(PdfTextExtractor.getTextFromPage(reader, j, semTextExtractionStrategy));
The problem is that you want to pass some context class on calling the entry function (like ActionEvent or such). But by its name a strategy class probably is a stateless singleton. In the above solution you would need to instantiate from a Class<TextExctractionStrategy>, Class<D> a new strategy instance. Or like in the MouseAdapter class pass the same event class parameter to every method.
This smells of "over-designing" or a skewed pattern application.
As we are on the brink of Java 8 lambdas, you might even consider a "backport" of a design with lambdas.
But for the moment I would go with adding a generic D textExtractionContext to every called function, if the API is not for an external library.
When i run this demo it's call TestBean's writeObject method which is private
How is it possible ?
Here is the Code:
import java.io.FileOutputStream;
public class Test {
public static void main(String[] args) {
try {
TestBean testBean = test.new TestBean();
testBean.setSize(23);
testBean.setWidth(167);
FileOutputStream fos =
new FileOutputStream(new File("d:\\serial.txt"));
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(testBean);
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
class TestBean implements Serializable {
private static final long serialVersionUID = 1L;
private int size;
private int width;
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
private void writeObject(ObjectOutputStream out) throws IOException {
System.out.println("TestBean writeObject");
out.defaultWriteObject();
}
private void readObject(ObjectInputStream input) throws IOException,
ClassNotFoundException {
System.out.println("TestBean readObject ===================> ");
input.defaultReadObject();
}
}
}
If your serializable object has any writeObject method, it will be called otherwise the defaultWriteObject method will be called.
The private method calling is possible using the reflection. If you see the source code of ObjectOutputStream Class in that method writeSerialData, the code below answers your question.
if (slotDesc.hasWriteObjectMethod()) {
// through reflection it will call the Serializable objects writeObject method
} else {
// the below is the same method called by defaultWriteObject method also.
writeSerialData(obj, desc);
}
The virtual machine will automatically check to see if either method
is declared during the corresponding method call. The virtual machine
can call private methods of your class whenever it wants but no other
objects can. Thus, the integrity of the class is maintained and the
serialization protocol can continue to work as normal. The
serialization protocol is always used the same way, by calling either
ObjectOutputStream.writeObject() or ObjectInputStream.readObject().
So, even though those specialized private methods are provided, the
object serialization works the same way as far as any calling object
is concerned.
You will get more about from this article:
Discover the secrets of the Java Serialization API
It uses reflection. private and public are not security measures. That is only a contract for class users.