Glassfish - JEE6 - Use of Interceptor to measure performance - glassfish

For measuring execution time of methods, I've seen suggestions to use
public class PerformanceInterceptor {
#AroundInvoke
Object measureTime(InvocationContext ctx) throws Exception {
long beforeTime = System.currentTimeMillis();
Object obj = null;
try {
obj = ctx.proceed();
return obj;
}
finally {
time = System.currentTimeMillis() - beforeTime;
// Log time
}
}
Then put
#Interceptors(PerformanceInterceptor.class)
before whatever method you want measured.
Anyway I tried this and it seems to work fine.
I also added a
public static long countCalls = 0;
to the PerformanceInterceptor class and a
countCalls++;
to the measureTime() which also seems to work o.k.
With my newby hat on, I will ask if my use of the countCalls is o.k. i.e
that Glassfish/JEE6 is o.k. with me using static variables in a Java class that is
used as an Interceptor.... in particular with regard to thread safety. I know that
normally you are supposed to synchronize setting of class variables in Java, but I
don't know what the case is with JEE6/Glassfish. Any thoughts ?

There is not any additional thread safety provided by container in this case. Each bean instance does have its own instance of interceptor. As a consequence multiple thread can access static countCalls same time.
That's why you have to guard both reads and writes to it as usual. Other possibility is to use AtomicLong:
private static final AtomicLong callCount = new AtomicLong();
private long getCallCount() {
return callCount.get();
}
private void increaseCountCall() {
callCount.getAndIncrement();
}
As expected, these solutions will work only as long as all of the instances are in same JVM, for cluster shared storage is needed.

Related

Actionscript, can a class be accessed using a variable name?

I wish to access many classes and variables, I would like to do this by dynamically setting the class name and variable name. Currently I am using
MyClass["myVariable1"]
to dynamically access the variable name
MyClass.myVariable1
I want to also dynanmically acces the class name, something like
["MyClass"]["myVariable1"]
But this does not work.
The purpose is that I have shared object with many user settings, I want to iterate through the shared object and set all the user settings across all the classes. I think if I cant dynamically access the class I must have a statement for each and every class name/variable.
I advise against such a practice. Although technically possible, it is like welcoming a disaster into the app architecture:
You rely on something you have no apparent control of: on the way Flash names the classes.
You walk out of future possibility to protect your code with identifier renaming obfuscation because it will render your code invalid.
Compile time error checks is better than runtime, and you are leaving it to runtime. If it happens to fail in non-debug environment, you will never know.
The next developer to work with your code (might be you in a couple of years) will have hard time finding where the initial data coming from.
So, having all of above, I encourage you to switch to another model:
package
{
import flash.net.SharedObject;
public class SharedData
{
static private var SO:SharedObject;
static public function init():void
{
SO = SharedObject.getLocal("my_precious_shared_data", "/");
}
static public function read(key:String):*
{
// if (!SO) init();
return SO.data[key];
}
static public function write(key:String, value:*):void
{
// if (!SO) init();
SO.data[key] = value;
SO.flush();
}
// Returns stored data if any, or default value otherwise.
// A good practice of default application values that might
// change upon user activity, e.g. sound volume or level progress.
static public function readSafe(key:String, defaultValue:*):*
{
// if (!SO) init();
return SO.data.hasOwnProperty(key)? read(key): defaultValue;
}
}
}
In the main class you call
SharedData.init();
// So now your shared data are available.
// If you are not sure you can call it before other classes will read
// the shared data, just uncomment // if (!SO) init(); lines in SharedData methods.
Then each class that feeds on these data should have an initialization block:
// It's a good idea to keep keys as constants
// so you won't occasionally mistype them.
// Compile time > runtime again.
static private const SOMAXMANA:String = "maxmana";
static private const SOMAXHP:String = "maxhp";
private var firstTime:Boolean = true;
private var maxmana:int;
private var maxhp:int;
// ...
if (firstTime)
{
// Make sure it does not read them second time.
firstTime = false;
maxhp = SharedData.readSafe(SOMAXHP, 100);
maxmana = SharedData.readSafe(SOMAXMANA, 50);
}
Well, again. The code above:
does not employ weird practices and easy to understand
in each class anyone can clearly see where the data come from
will be checked for errors at compile time
can be obfuscated and protected
You can try getting the class into a variable and going from there:
var myClass:Class = getDefinitionByName("MyClass") as Class;
myClass["myVariable1"] = x;

Can collections / iterables / streams be passed into #ParamterizedTests?

In Junit5 5.0.0 M4 I could do this:
#ParameterizedTest
#MethodSource("generateCollections")
void testCollections(Collection<Object> collection) {
assertOnCollection(collection);
}
private static Iterator<Collection<Object>> generateCollections() {
Random generator = new Random();
// We'll run as many tests as possible in 500 milliseconds.
final Instant endTime = Instant.now().plusNanos(500000000);
return new Iterator<Collection<Object>>() {
#Override public boolean hasNext() {
return Instant.now().isBefore(endTime);
}
#Override public Collection<Object> next() {
// Dummy code
return Arrays.asList("this", "that", Instant.now());
}
};
}
Or any number of other things that ended up with collections of one type or another being passed into my #ParameterizedTest. This no longer works: I now get the error
org.junit.jupiter.api.extension.ParameterResolutionException:
Error resolving parameter at index 0
I've been looking through the recent commits to SNAPSHOT and I there's a few changes in the area, but I can't see anything that definitely changes this.
Is this a deliberate change? I'd ask this on a JUnit5 developer channel but I can't find one. And it's not a bug per se: passing a collection is not a documented feature.
If this is a deliberate change, then this is a definite use-case for #TestFactory...
See https://github.com/junit-team/junit5/issues/872
The next snapshot build should fix the regression.

Selenium get value of current implicit wait

I realize that Selenium has a default value for implicit waits, but how do I get this value if I change it? For example:
driver.implicitly_wait( 13 );
How do I later get the 13 value from the driver?
Unfortunately there's no getter for that.
http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/WebDriver.Timeouts.html
There isn't for explicit waits either.
http://selenium.googlecode.com/svn/trunk/docs/api/java/com/thoughtworks/selenium/Wait.html
I know I'm a couple years late, and #JaneGoodall is not wrong -- there is no built-in function for that. But it's not impossible!
It's not very difficult to create your own versions of the WebDriver interface and browser-specific driver class. And then, you can put whatever code you want into the driver!
Example:
MyDriver.java (specialized version of WebDriver, not quite mandatory but a very good idea):
public interface MyDriver extends WebDriver {
void setWait(int timeout);
int getWait();
}
MyChrome.java (specialized version of ChromeDriver -- works the same for any browser)
public class MyChrome extends ChromeDriver implements MyDriver {
int timeout = 0;
public void setWait(int timeout) {
this.timeout = timeout;
this.manage().timeouts().implicitlyWait(timeout, TimeUnit.SECONDS);
}
public int getWait() {
return timeout;
}
}
And now, to use it, MyProgram.java:
public class MyProgram {
MyDriver driver = new MyChrome();
driver.setWait(10);
assert(driver.getWait() == 10);
}
I hope this is helpful!
For those who came here from google. In 2018 it seems like there is a method to get those timeouts at least in javascript (I know question was about java):
const {implicit, pageLoad, script} = await driver.manage().getTimeouts();
Hope this will help.
TL;DR - This is not a solution to get implicit waits. You cannot get the implicit wait in Java even today, without using a workaround like this.
In 2020, selenium 3.141.59 still does not have a getter for any timeouts. The WebDriver interface has a nested interface Timeouts which does not define any getters. RemoteWebDriver, which is the parent of Chrome and Firefox drivers, implements the WebDriver interface and it does not add a getter for timeouts.
RemoteWebDriver implements WebDriver.Timeouts, but it does not store the value of implicit timeout anywhere, as you can see from the code below.
protected class RemoteTimeouts implements Timeouts {
public Timeouts implicitlyWait(long time, TimeUnit unit) {
execute(DriverCommand.SET_TIMEOUT, ImmutableMap.of(
"implicit", TimeUnit.MILLISECONDS.convert(time, unit)));
return this;
}
public Timeouts setScriptTimeout(long time, TimeUnit unit) {
execute(DriverCommand.SET_TIMEOUT, ImmutableMap.of(
"script", TimeUnit.MILLISECONDS.convert(time, unit)));
return this;
}
public Timeouts pageLoadTimeout(long time, TimeUnit unit) {
execute(DriverCommand.SET_TIMEOUT, ImmutableMap.of(
"pageLoad", TimeUnit.MILLISECONDS.convert(time, unit)));
return this;
}
} // timeouts class.
The execute() method in the RemoteWebDriver takes the wait inside a Map of parameters, but it does not make that map or the wait settings accessible to us via a getter.
protected Response execute(String driverCommand, Map<String, ?> parameters)
//Open the source code to see why you can't make your own getter for implicitWait.
This can print real timeout value (plus calculating time, usually within 100ms):
public void getCurrentWaitTimeout() {
long milliseconds = java.time.ZonedDateTime.now().toInstant().toEpochMilli();
driver.findElements(By.cssSelector(".nonExistingElement"));
milliseconds = java.time.ZonedDateTime.now().toInstant().toEpochMilli() - milliseconds;
log.info("Current waiting timeout is {} milliseconds", milliseconds);
}
So you can always call such a method to be sure you know actual timeout, not the value you tried to set.
For Java version of Selenium, org.seleniumhq.selenium:selenium-api:4.0.0-beta-4
allows you to get the current implicit wait duration:
WebDriver.manage().timeouts().getImplicitWaitTimeout()
With this method, it makes possible to temporarily change the timeout to let's say 1 second and restore it afterwards:
final Duration originalTimeout = driver.manage().timeouts().getImplicitWaitTimeout();
driver.manage().timeouts().implicitlyWait(Duration.of(1, ChronoUnit.SECONDS));
... // do something
// restore the original timeout
driver.manage().timeouts().implicitlyWait(originalTimeout);
Probably, this functionality is present even before selenium-api:4.0.0-beta-4.
I get the defined implicitTimeout with:
driver.manage().timeouts().getImplicitWaitTimeout().getSeconds()
Many years later, in Python, using selenium 4.4.3 you can access the timeouts very easily via simply:
print(driver.timeouts.implicit_wait)
print(driver.timeouts.page_load)
print(driver.timeouts.script)
Note that when I call driver.implicitly_wait(60), it changed the implicit_wait value only.
Also, there is no such function as driver.manage() in Python, as in the Java answers above.

AspectJ - Doubt

An aspect can be used to measure the performance of method invocations,
as illustrated in the example below:
public aspect MonitorRequests {
void around() : monitoredRequestO {
PerfStats stats = getPerfStats(thisDoinPointStaticPart);
long start = System-currentTimeMillisO;
proceedO;
stats.ecunter++;
stats.time += System.currentTimeMillisC)-start;
}
pointcut monitoredRequestO :
execution(void HttpServ1et.do*(..)) && if(enabled);
// can expose stats via JMX, dump method, getstats etc.
public static class PerfStats { _. }
private Map<StaticPart,PerfStats> perfStatMap • //...
private boolean enabled;
}
By default, an aspect instance is associated with the Java Virtual Machine, rather with
specific execution flows, similar to a static class.
Another aspect below uses percflow() to associate an aspect instance differently from
the default:
public aspect MonitorDatabaseRequests
percflow(monitoredRequest() && !cflowbelow(mon-5toredRequest()) {
void around() : monitoredRequestO {
PerfStats stats = getPerfStats(thisJoinPointStaticPart);
long time.= System.currentTimeMi 11 i s O ;
proceed();
stats.counter++;
stats.databaseTime += accumulatedoatabaseTime;
stats.time 4= System.currentTimeMi 11 isO-time;
}
}
What is the difference that adding the percflow() declaration makes in this example
I'm confused how percflow works and how this is different from not using it....
percflow is the aspect instantiation model. See here:
http://eclipse.org/aspectj/doc/released/progguide/quick-aspectAssociations.html
This means that one instance of this aspect is created for every cflow entered.
The first aspect is a singleton and so it must store a map for all of the performance stats it keeps track of. The second aspect is instantiated as needed, so performance stats are implicitly stored and associated with the proper dynamic call graph.

Problem attaching WatiN to IE

I am experimenting with WatiN for our UI testing, I can get tests to work, but I can't get IE to close afterwards.
I'm trying to close IE in my class clean up code, using WatiN's example IEStaticInstanceHelper technique.
The problem seems to be attaching to the IE thread, which times out:
_instance = IE.AttachTo<IE>(Find.By("hwnd", _ieHwnd));
(_ieHwnd is the handle to IE stored when IE is first launched.)
This gives the error:
Class Cleanup method
Class1.MyClassCleanup failed. Error
Message:
WatiN.Core.Exceptions.BrowserNotFoundException:
Could not find an IE window matching
constraint: Attribute 'hwnd' equals
'1576084'. Search expired after '30'
seconds.. Stack Trace: at
WatiN.Core.Native.InternetExplorer.AttachToIeHelper.Find(Constraint
findBy, Int32 timeout, Boolean
waitForComplete)
I'm sure I must be missing something obvious, has anyone got any ideas about this one?
Thanks
For completeness, the static helper looks like this:
public class StaticBrowser
{
private IE _instance;
private int _ieThread;
private string _ieHwnd;
public IE Instance
{
get
{
var currentThreadId = GetCurrentThreadId();
if (currentThreadId != _ieThread)
{
_instance = IE.AttachTo<IE>(Find.By("hwnd", _ieHwnd));
_ieThread = currentThreadId;
}
return _instance;
}
set
{
_instance = value;
_ieHwnd = _instance.hWnd.ToString();
_ieThread = GetCurrentThreadId();
}
}
private int GetCurrentThreadId()
{
return Thread.CurrentThread.GetHashCode();
}
}
And the clean up code looks like this:
private static StaticBrowser _staticBrowser;
[ClassCleanup]
public static void MyClassCleanup()
{
_staticBrowser.Instance.Close();
_staticBrowser = null;
}
The problem is that when MSTEST executes the method with the [ClassCleanup] attribute, it will be run on a thread that isn't part of the STA.
If you run the following code it should work:
[ClassCleanup]
public static void MyClassCleanup()
{
var thread = new Thread(() =>
{
_staticBrowser.Instance.Close();
_staticBrowser = null;
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
}
The WatiN website briefly mentions that WatiN won't work with threads not in the STA here but it isn't obvious that [TestMethod]'s run in the STA while methods like [ClassCleanup] and [AssemblyCleanupAttribute] do not.
By default when IE object are destroyed, they autoclose the browser.
Your CleanUp code may try to find a browser already close, which why you have an error.
Fixed this myself by dumping mstest and using mbunit instead. I also found that I didn't need to use any of the IEStaticInstanceHelper stuff either, it just worked.