Working on a imgui port in kotlin, I have a metrics menu where I display the number of allocations
This is the init code I wrote:
try {
var ac: AttachingConnector? = null
for (x in Bootstrap.virtualMachineManager().attachingConnectors()) {
if (x.javaClass.name.toLowerCase().indexOf("socket") != -1) {
ac = x
break
}
}
if (ac == null) {
throw Error("No socket attaching connector found")
}
val connectArgs = HashMap<String, Argument>(ac.defaultArguments())
connectArgs["hostname"]!!.setValue("127.0.0.1")
connectArgs["port"]!!.setValue(Integer.toString(3001))
connectArgs["timeout"]!!.setValue("3000")
vm = ac.attach(connectArgs)
} catch (error: Exception) {
System.err.println("Couldn't retrieve the number of allocations, $error")
}
And these are the arguments I pass in as 'VM options'
-Xdebug -Xrunjdwp:transport=dt_socket,address=3001,server=y,suspend=n
Whenever I run it normally, it works. But if I run it in debug mode, it doesnt, returning the following error:
java.net.ConnectException: Connection refused: connect
I couldn't find yet a solution for that, at the moment I simply display a -1 to indicate an error
Does anyone have a solution/explanation about?
Specs:
Kotlin 1.2-m1
Idea 2017.2.1
I guess the problem is that you try to use the same port for the debugger as the one used by the program. Try to use a different port for the debugger.
Related
I have a method called createBufferedImageFromURI that takes a string that could be either a file system path or an URL, and creates a BufferedImage from the resource corresponding to that string.
The method code is the following:
private static BufferedImage createBufferedImageFromURI(String filePathOrUrl)
throws IOException
{
IHttpContext httpContext = com.genexus.ModelContext
.getModelContext().getHttpContext();
InputStream is = null;
try {
if (filePathOrUrl.toLowerCase().startsWith("http://") ||
filePathOrUrl.toLowerCase().startsWith("https://") ||
(httpContext.isHttpContextWeb() &&
filePathOrUrl.startsWith(httpContext.getContextPath())))
is = new URL(GXDbFile.pathToUrl(filePathOrUrl, httpContext))
.openStream();
else
is = getGXFile(filePathOrUrl).getStream();
return ImageIO.read(is);
} catch (IOException e) {
log.error("Failed to read image stream: " + filePathOrUrl);
throw e;
} finally {
is.close();
}
}
As you can see, the first part of the if - else block corresponds to the case where the string is an URL. It was working just fine until it suddenly didn't. The following started appearing in the webapp logs:
2023-02-14T09:25:30,286 [http-nio-8080-exec-13] ERROR com.genexus.GxImageUtil - getImageWidth https://static3.depositphotos.com/1000575/154/i/600/depositphotos_1549339-stock-photo-lithuania-landscape-panorama.jpg failed
java.lang.NullPointerException: Cannot invoke "java.awt.image.BufferedImage.getWidth()" because the return value of "com.genexus.GxImageUtil.createBufferedImageFromURI(String)" is null
at com.genexus.GxImageUtil.getImageWidth(GxImageUtil.java:79) ~[gxclassR-2.10-SNAPSHOT.jar:?]
at com.pruebasjavastable.webpanelimageapi_impl.e12042(webpanelimageapi_impl.java:771) ~[classes/:?]
at com.pruebasjavastable.webpanelimageapi_impl.strup040(webpanelimageapi_impl.java:736) ~[classes/:?]
at com.pruebasjavastable.webpanelimageapi_impl.start042(webpanelimageapi_impl.java:525) ~[classes/:?]
at com.pruebasjavastable.webpanelimageapi_impl.executeStartEvent(webpanelimageapi_impl.java:122) ~[classes/:?]
...
There is no other trace what could be the cause of this error. Neither on Tomcat's console or even in the browser console or network tab
I did some debugging to discard some obvious possible causes, but none of them where the case
GXDbFile.pathToUrl( filePathOrUrl, httpContext) builds the URL just fine. I even tried hard coding one and it still didn't work
Discarded some firewall or proxy issue by testing it on other PCs and networks. Even tried it on online playgrounds
Is there a problem with this implementation? As I said, it was working just fine until it suddenly didn't. Only change I can think of is that I changed my JDK from 17.0.4 to 17.0.6 but I read the release notes and nothing seems to affect my case.
I access Websites in a loop via selenium Java based. Some of the sites crash imediately so that i get the error
[1618982990.911][WARNING]: Timed out connecting to Chrome, retrying...
after a short time.
So this is not a selenium issue i assume, since even chrome crashes if i visit the site manually because of js errors, saying unresonsive Website
My problem is, that every time a site crashes, chromedriver and a chrome instance will stay alive so that i have high CPU usage after a short time.
Can i tell selenium to quit the instance if it is frozen? But i dont know how this should be possible if it does not get answer from chrome anymore?
Thankful for any solution or idea
Sometimes with some Windows version driver.quit() will not kill the chrome process which I have come across.
So at the end of the script you can kill the chrome processes if exists using java code, if the driver.quit doesn't work.
Please refer stackoverflow link which has the code to kill the process if exists in Java and pass the chrome process to it.
i found a workaround for anyone who would be interested. First setting up a pageLoadTimeout, after that force any chrome instance to be killed if an Exception is being thrown.
try{
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
//some excecution code....
}
catch (Exception e) {
System.out.println("Error. Closing");
driver.quit();
Runtime.getRuntime().exec("taskkill /F /IM chrome.exe");}
timerChromeKillListener = new Timer();
timerChromeKillListener.schedule(new TimerTask()
{
#Override
public void run()
{
if (driver != null)
{
try
{
final Logs logs = driver.manage().logs();
final LogEntries driverLog = logs.get("driver");
if (driverLog != null)
{
final List<LogEntry> logEntries = driverLog.getAll();
for (final LogEntry logEntry : logEntries)
{
final String message = logEntry.getMessage();
if (message.contains("Unable to evaluate script: disconnected: not connected to DevTools") || message.contains("Timed out connecting to Chrome, retrying..."))
{
disconnect();
}
}
}
}
catch (Exception ignored)
{
}
}
}
} , 1 , 100);
I am using Epson_JavaPOS_ADK_11414_for_Linux_x64 for installing the JavaPOS with pcs ( sh installJavaPOSFull-64.sh )
I ran this program one after the other in different shells and the second process crashes for some reason:
import jpos.JposException;
import jpos.POSPrinter;
import jpos.util.JposPropertiesConst;
import java.time.Duration;
import java.time.Instant;
public class POSPrinterClaimTest {
static POSPrinter posPrinter;
private static Boolean isOpen = false;
private static Boolean isClaimed = false;
private static Boolean isEnabled = false;
static {
System.setProperty(
JposPropertiesConst.JPOS_POPULATOR_FILE_PROP_NAME, "jpos.xml");
}
public static void main(String[] args) {
try {
posPrinter = new POSPrinter();
Instant start = Instant.now();
Instant finish = null;
Long timeElapsed = null;
openConnection("POSPrinter1");
finish = Instant.now();
timeElapsed = Duration.between(start, finish).toMillis();
System.out.println("Time taken to connect : " + timeElapsed.toString());
Thread.sleep(100000L);
terminate();
System.out.println("terminated from try block");
} catch (JposException | InterruptedException e) {
e.printStackTrace();
try {
terminate();
System.out.println("terminated from catch block");
Thread.sleep(5000);
} catch (JposException | InterruptedException jposException) {
jposException.printStackTrace();
}
} catch(Throwable t){
t.printStackTrace();
} finally {
posPrinter = null;
}
}
private static void openConnection(String printerName) throws JposException {
try {
String printerNamesss = printerName;
/**
* open the printer object according to the device logical name defined in jpos.xml
*/
posPrinter.open(printerName);
isOpen = true;
System.out.println("opened");
/**
* Get the exclusive control right for the opened device.
* Then the device is disable from other application.
* */
posPrinter.claim(3000);
isClaimed = true;
System.out.println("claimed");
/**
* enable the device for input and output
*/
posPrinter.setDeviceEnabled(true);
isEnabled = true;
System.out.println("enabled");
} catch (JposException jposException) {
System.out.println("jpos exception in open : " + jposException.getMessage());
throw jposException;
} catch(Throwable t) {
System.out.println("unknown throwable open: " + t.getMessage());
}
}
public static void terminate() throws JposException {
try {
if(isOpen && isClaimed) {
posPrinter.clearOutput();
System.out.println("cleared output");
}
if(isEnabled) {
posPrinter.setDeviceEnabled(false);
isEnabled = false;
System.out.println("setDeviceEnabled false");
}
if(isClaimed) {
posPrinter.release();
isClaimed = false;
System.out.println("released");
}
if(isOpen) {
posPrinter.close();
isOpen = false;
System.out.println("closed");
}
} catch (JposException jposException) {
jposException.printStackTrace();
throw jposException;
} catch(Throwable t) {
System.out.println("unknown throwable terminate: " + t.getMessage());
}
}
}
First process output
opened
claimed
enabled
Time taken to connect : 7928 --> now I start the second process.
cleared output
setDeviceEnabled false
released
closed
terminated from try block
Second process output
opened
jpos exception in open : The port is already open.
jpos.JposException: The port is already open.
at jp.co.epson.upos.core.v1_14_0001.pntr.CommonUPOSExceptionCreator.createJposException(CommonUPOSExceptionCreator.java:138)
at jp.co.epson.upos.core.v1_14_0001.pntr.CommonUPOSExceptionCreator.createJposException(CommonUPOSExceptionCreator.java:99)
at jp.co.epson.upos.core.v1_14_0001.pntr.CommonPrinterService.openPort(CommonPrinterService.java:3341)
at jp.co.epson.upos.core.v1_14_0001.pntr.CommonPrinterService.claim(CommonPrinterService.java:3103)
at jpos.BaseJposControl.claim(Unknown Source)
at POSPrinterClaimTestThreads.openConnection(POSPrinterClaimTestThreads.java:73)
at POSPrinterClaimTestThreads.test(POSPrinterClaimTestThreads.java:36)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
closed
terminated from catch block
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f43880ea9df, pid=12119, tid=0x00007f43690b0700
#
# JRE version: OpenJDK Runtime Environment (8.0_252-b09) (build 1.8.0_252-b09)
# Java VM: OpenJDK 64-Bit Server VM (25.252-b09 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [libethernetio31.so+0x1f9df] CCommonPort::PortEvent(unsigned int, unsigned int, unsigned int*, unsigned int, unsigned char*)+0xf
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /POSPrinterTest/JavaPOS/hs_err_pid12119.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
#
Aborted
If you see the second process throws a JposException which then initiates its catch and closes the connection. Then it suddenly crashes instead of sleeping for 5sec.
Any help?
After discussing this problem with EPSON team, they were able to provide a fix for the same with a new libepsonjpos.so and epsonjpos.jar
It solved two problems for me:
The original claim issue in the post - resolved after using the latest libepsonjpos.so
Multi-threaded printing in a single process in non-install mode (No-SetupPOS-insall)
the Epson team said to synchronize the POSPrinter.open() in all the threads and update the epsonjpos.jar with their fix
Some quotes on the issue from Epson Team.
Multi-thread issue - "Change History
The fix that has been applied is in the device sharing logic. Only affects lite-mode (No-SetupPOS version)
The different objects falsely assumed as equal. As result only the first connected printer has been used.
The fix corrects that comparison logic."
Claim Issue - "We are glad we could help you.
As for the background of the issues. The multi-process usage with non-install mode was a corner case for our JavaPOS ADK. With your help we could improve our testing cases."
Epson team said that they will release the patches in the next version.
It seems that the exclusive control processing of JavaPOS Service Object does not work well.
You should get a timeout error instead of an error that the port is already open.
However, your program is also bad.
The range of one try, catch is too wide.
JposException takes the form of an exception, but it's really just an error code notification.
Just because a JposException was signaled does not mean it crashes.
Most of the time, it will work if you eliminate the cause of the error and try again.
To be correct, try and catch each method call and property access.
The Epson_JavaPOS_ADK sample program should have been made that way.
Please code the same as the sample program.
In Addition:
Is what you see different?
It does try and catch in small units for each method and property, and does not propagate it to the top with throw.
Some of the sources I have are:
from "Epson_JavaPOS_ADK_11414_for_Linux_x64\Sample\Samples\Printer\PrinterSample_Step15\src\printersample_step15\Step15Frame.java"
// JavaPOS's code for Step7
// Set OutputCompleteEvent listener
ptr.addOutputCompleteListener(this);
// JavaPOS's code for Step7--END
// JavaPOS's code for Step10
try {
//Open the device.
//Use the name of the device that connected with your computer.
ptr.open("POSPrinter");
}
catch(JposException ex){
JOptionPane.showMessageDialog(this, "This device has not been registered, or cannot use.",
"",JOptionPane.WARNING_MESSAGE);
//Nothing can be used.
changeButtonStatus();
return;
}
try {
//Get the exclusive control right for the opened device.
//Then the device is disable from other application.
ptr.claim(1000);
bCoverSensor = ptr.getCapCoverSensor();
}
catch(JposException ex){
JOptionPane.showMessageDialog(this, "Fails to get the exclusive access for the device.",
"",JOptionPane.WARNING_MESSAGE);
//Nothing can be used.
changeButtonStatus();
return;
}
Extracting the situation from the comment and posting:
Well, the error reported by Claim may be wrong, so why not contact EPSON support with detailed information about such a situation?
From OP:
Done that already but we don't know if they will respond back. So trying to find answer here; somewhere. :D
From OP:
I ran the same program in a single process with multiple threads in two pulses. I do now get the timeout error as you said. Only in different processes scenario, I am getting a crash
If so, there may be a problem with the interprocess exclusive control of the JavaPOS service object. That's the problem with it, but the crash could be a cleanup issue at the end of the exception, as I commented earlier. When an exception occurs in the Claim method, instead of ending the process by propagating the exception, call the Close method and try other cleanup to end normally.
From OP:
I wrote the posPrinter.close() in claim catch block. It worked and crash frequency reduced significantly when doing with two processes single threads. Still the crash happened once or twice. But in two processes each with 10 threads trying to claim printer results in one process able to claim and the other process crashing. try{ posPrinter.claim(3000); } catch(JposException ex) { posPrinter.close();}
It seems that the problem of exclusive control of JavaPOS service object of EPSON may remain. Please make additional inquiries to EPSON based on such survey information.
We are now developing a payment card with NXP NQ220 (has embedded SE, called eSE) on Android N. The platform is MTK. Now, we can interact with eSE using OMA (using org.simalliance.openmobileapi.jar). It works as expected.
I was wondering if there is any ways to open channel in session without AID? Besides, is there any ways to control the power of eSE(power-on and power-off) and reset eSE in some situations?
My investigation as follows:
About open channel without AID, I have found following sentences in page 16 of Open Mobile API specification V3.
(h)Method: Channel openLogicalChannel(byte[] aid, Byte P2)
Open a logical channel with the SE, selecting the applet represented by the >given AID. If the AID is null, which means no applet is to be selected on >this channel, the default applet is used. It's up to the SE to choose which >logical channel will be used.
However, if we set aid to null in openLogicalChannel(byte[] aid), following exception will be shows. What happens about it? Is the default applet or eSE have problems?
01-30 01:06:39.941 V/SmartcardService( 2587): OpenLogicalChannel Exception: Access Control Enforcer: no APDU access allowed!
01-30 01:06:39.947 E/SeControlClient( 3239): Error occured:
01-30 01:06:39.947 E/SeControlClient( 3239): java.lang.SecurityException: Access Control Enforcer: no APDU access allowed!
01-30 01:06:39.947 E/SeControlClient( 3239): at org.simalliance.openmobileapi.SEService.checkForException(SEService.java:255)
01-30 01:06:39.947 E/SeControlClient( 3239): at org.simalliance.openmobileapi.Session.openLogicalChannel(Session.java:295)
It seems there is no method in OMA to reset eSE. But I found reset() method in INxpNfcAdapterExtras. However, when I use INxpNfcAdapterExtras.reset(), it always return false. Following codes is how we get INxpNfcAdapterExtras.
private INxpNfcAdapterExtras getNxpNfcAdapterExtras() {
if (mNfcAdapter != null) {
try {
INxpNfcAdapter nxpNfcAdapter =
mNfcAdapter.getService().getNxpNfcAdapterInterface();
return nxpNfcAdapter.getNxpNfcAdapterExtrasInterface();
} catch (Exception e) {
Log.e(LOGTAG, "Exception occured:", e);
}
} else {
Log.e(LOGTAG, "Please initialize NfcAdapter first.");
}
return null;
}
About control the power of eSE, is it related to the platform? Can you give me some suggestions? Thank you very much.
Dont known
To access SE functions your application must be execute with owner of android device.
You could check this in : https://github.com/NXPNFCLinux/android_nxp-nci/blob/1d95fe24334fa12c9d9eccd1141f8739972c4288/aosp/packages/apps/Nfc/src/com/android/nfc/NfcService.java
The reset method check permission before:
public boolean reset(String pkg) throws RemoteException {
NfcService.this.enforceNfceeAdminPerm(pkg);
Bundle result;
boolean stat = false;
try {
stat = _nfcEeReset();
result = writeNoException();
} catch (IOException e) {
result = writeEeException(EE_ERROR_IO, e.getMessage());
}
Log.d(TAG,"reset" + stat);
return stat;
}
The check permission method:
public void enforceNfceeAdminPerm(String pkg) {
if (pkg == null) {
throw new SecurityException("caller must pass a package name");
}
NfcPermissions.enforceUserPermissions(mContext);
if (!mNfceeAccessControl.check(Binder.getCallingUid(), pkg)) {
throw new SecurityException(NfceeAccessControl.NFCEE_ACCESS_PATH +
" denies NFCEE access to " + pkg);
}
if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
throw new SecurityException("only the owner is allowed to call SE APIs");
}
}
To execute your app with device owner, you could follow my anwser here:
Device Admin API, how to be a device owner?
I'm not sure about what you mean "control the power of eSE". If it's on/off eSE, then eSE is integrated with NFC chip so if you disable NFC in Android eSE will be power off.
I have found another way to solve this issue. It used NXP's own class NxpNfcAdapterExtrasService.
1.I still don't know why the exception happens when we open channel use the default Applet(without AID). But, with the method in NxpNfcAdapterExtrasService, we can establish connection with eSE.
2.About the second question. The codes is right but the way of how to use INxpNfcAdapterExtras.reset() is wrong. This method will return true only when you do something with eSE. Like transmit and execute APDU commands. So you can use this method when you want to disconnect the connection with eSE.
3.About the third question, I don't know whether the openUicc()/closeUicc() method can control the eSE power. But, it seems this two method works as expected.
i've looked at doc, tested, debugged ... but remain stumped. time for stackOverflow! i'll set the stage, then describe my error.
Background
i have an RMI client/sever setup that works fine when client, server and rmiregistry
all live together on localhost. so then i fire up rmiregistry on serverHost, with rmi.server.logCalls trace turned on (called RegistryTrace below). the important parts of the server code:
String hostname = "//serverHost.local/project"
String codeBase = "file:/home/rik/Code/eclipse/project/bin/"
System.setProperty("java.rmi.server.hostname", hostname);
System.setProperty("java.rmi.server.codebase", codeBase);
Driver server = new Driver();
Naming.rebind(hostname, server);
when i start the server, i see the rebind() call succeeds (by looking at RegistryTrace). also, looking at the list generated by Naming.list() shows it contains "//serverHost.local:1099/project"
starting my client, it successfully completes Naming.lookup():
server = (ServerInterface)Naming.lookup(serverHost);
looking at RegistryTrace, i am able to confirm that this lookup() query gets to the server end.
Error on first RMI
but now: my next statement tries to call one of server's methods
boolean status = server.initConnection(username);
generates an IllegalArgumentException:
java.lang.IllegalArgumentException: protocol = socket host = null
at sun.net.spi.DefaultProxySelector.select(DefaultProxySelector.java:151)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:424)
at java.net.Socket.connect(Socket.java:529)
at java.net.Socket.connect(Socket.java:478)
at java.net.Socket.<init>(Socket.java:375)
at java.net.Socket.<init>(Socket.java:189)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:595)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:198)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:110)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132)
at $Proxy0.initConnection(Unknown Source)
at project.client.View2.main(View2.java:651)
i've traced this down into Java source to a call to java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod()
private Object invokeRemoteMethod(Object proxy,
Method method,
Object[] args)
throws Exception
{
try {
if (!(proxy instanceof Remote)) {
throw new IllegalArgumentException(
"proxy not Remote instance");
}
// EXCEPTION OCCURS WITHIN CALL TO ref.invoke() BELOW
//
return ref.invoke((Remote) proxy, method, args,
getMethodHash(method));
} catch (Exception e) {
if (!(e instanceof RuntimeException)) {
Class<?> cl = proxy.getClass();
try {
method = cl.getMethod(method.getName(),
method.getParameterTypes());
} catch (NoSuchMethodException nsme) {
throw (IllegalArgumentException)
new IllegalArgumentException().initCause(nsme);
}
Class<?> thrownType = e.getClass();
for (Class<?> declaredType : method.getExceptionTypes()) {
if (declaredType.isAssignableFrom(thrownType)) {
throw e;
}
}
e = new UnexpectedException("unexpected exception", e);
}
throw e;
}
}
then i lose it in the source trace. (anyone know the story about source availability for things like sun.rmi.server.UnicastRef ?) the rest of the trace makes it seem like RMI can't create a socket?
i'm sure many parts of this code could be cleaner; any suggestions appreciated. i also need to convert this into jar file distributions, so if specifying them now for java.rmi.server.codebase would be easier...?
thanks for any suggestions, rik
It is constructing a SocksSocketImpl so you must be specifying an invalid SOCKS proxy host or port via socks.proxyHost/socks.proxyPort at the client, or perhaps you have java.rmi.server.hostname set to a strange value at the server.