When do I need to recycle? - java

I have an applicationScope managed bean that loads a bunch of information about a series of applications into a Map. Then the following method is part of the bean:
public Database getAppDB() {
Database appDB = null;
try{
Session s = ExtLibUtil.getCurrentSession();
serverName = s.createName(s.getCurrentDatabase().getServer()).getCommon();
appDB = s.getDbDirectory(serverName).openDatabaseByReplicaID(this.getAppRepID());
return appDB;
}catch (NotesException e){
System.out.println(e.toString());
return appDB;
}
}
Now this method declares two Objects (Session and appDB). Not sure if they need to be recycled before returning and if so how would one do that because appDB is the returned value. The Session can easily be recycled.
Now clearly if I call this method from some SSJS:
var thisDB:NotesDatabase = appProps[ssApplication].appDB;
I need to recycle thisDB in the SSJS.
also if I do something like this in SSJS:
var cNames = appProps[ssApplication].appDB.getView("vwFTSearch").getColumnNames();
I'm assuming that there is nothing to recycle?

Detailed answers are in other two questions Knut pasted.
The short answer to your specific question is that you shouldn't recycle those objects in the getAppDB() method.
Session will be automatically recycled after the page has been served. The database object should be recycled by the caller of this method (SSJS, for your case).

The general rule is: you destroy (recycle) what you created. You leave what was given. Session and database are system provided objects (given), so you leave them alone even if you used a different function to obtain them.
For the rest i found a reasonable Practise: in the function that created the object it gets recycled, not anywhere else. You have to take the "created" a little pragmatic. E.g. when you have something like:
var custDB = getCustDB(curUser);
then you wouldn't consider getCustDB as the creator, but that line of code and have the recycle(); in the function where that code is.

Related

How to get the current substate and the parent state out of the Spring Statemachine?

I am running a hierachical Spring Statemachine and - after walking through the inital transitions into state UP with the default substate STOPPED - want to use statemachine.getState(). Trouble is, it gives me only the parent state UP, and I cannot find an obvious way to retrieve both the parent state and the sub state.
The machine has states constructed like so:
StateMachineBuilder.Builder<ToolStates, ToolEvents> builder = StateMachineBuilder.builder();
builder.configureStates()
.withStates()
.initial(ToolStates.UP)
.state(ToolStates.UP, new ToolUpEventAction(), null)
.state(ToolStates.DOWN
.and()
.withStates()
.parent(ToolStates.UP)
.initial(ToolStates.STOPPED)
.state(ToolStates.STOPPED,new ToolStoppedEventAction(), null )
.state(ToolStates.IDLE)
.state(ToolStates.PROCESSING,
new ToolBeginProcessingPartAction(),
new ToolDoneProcessingPartAction());
...
builder.build();
ToolStates and ToolEvents are just enums. In the client class, after running the builder code above, the statemachine is started with statemachine.start(); When I subsequently call statemachine.getState().getId(); it gives me UP. No events sent to statemachine before that call.
I have been up and down the Spring statemachine docs and examples. I know from debugging that the entry actions of both states UP and STOPPED have been invoked, so I am assuming they are both "active" and would want to have both states presented when querying the statemachine. Is there a clean way to achieve this ? I want to avoid storing the substate somewhere from inside the Action classes, since I believe I have delegated all state management issues to the freakin Statemachine in the first place and I would rather like to learn how to use its API for this purpose.
Hopefully this is something embarrasingly obvious...
Any advice most welcome!
The documentation describes getStates():
https://docs.spring.io/spring-statemachine/docs/current/api/org/springframework/statemachine/state/State.html
java.util.Collection<State<S,E>> getStates()
Gets all possible states this state knows about including itself and substates.
stateMachine.getState().getStates();
to wrap it up after SMA's most helpful advice: turns out the stateMachine.getState().getStates(); does in my case return a list of four elements:
a StateMachineState instance containing UP and STOPPED
three ObjectState instances containing IDLE, STOPPED and PROCESSING,
respectively.
this leads me to go forward for the time being with the following solution:
public List<ToolStates> getStates() {
List<ToolStates> result = new ArrayList<>();
Collection<State<ToolStates, ToolEvents>> states = this.stateMachine.getState().getStates();
Iterator<State<ToolStates, ToolEvents>> iter = states.iterator();
while (iter.hasNext()) {
State<ToolStates, ToolEvents> candidate = iter.next();
if (!candidate.isSimple()) {
Collection<ToolStates> ids = candidate.getIds();
Iterator<ToolStates> i = ids.iterator();
while (i.hasNext()) {
result.add(i.next());
}
}
}
return result;
}
This maybe would be more elegant with some streaming and filtering, but does the trick for now. I don't like it much, though. It's a lot of error-prone logic and I'll have to see if it holds in the future - I wonder why there isn't a function in the Spring Statemachine that gives me a list of the enum values of all the currently active states, rather than giving me everything possible and forcing me to poke around in it with external logic...

PeopleSoft Component Interfaces: Create Method Doesn't Persist The New Object

I'm working with the PSJOA library. I have a Java app, and I'm testing each of the standard operations using the CI_PERSONAL_DATA. Everything works fine with the Get, Find and Save. But not with the Create, even though when I invoke the method, I get an OK response, with no apparent errors. The input parameter I'm sending (taken from the CreateKeys) is the KEYPROP_EMPLID.
The odd thing here is that, if instead I call the Create method using Web Services (through SoapUI), the new instances is correctly created. However, in this scenario, passing just the primary key KEYPROP_EMPLID is not enough and I have to fill more fields (as it I was performing an update).
Can someone point to me what might be happening? Is there some missing data? Maybe I misunderstood the creation behavior?
Thanks.
What exactly goes awry when you call create? That will create a new entry in the personal data component in PeopleSoft for the person with the supplied emplid. It will be editable, so you can fill in other information, but it will not persist until/unless you call save() afterwards.
Does the emplid already exist in the personal data component? If so, you should be calling get() instead.
Does the emplid already exist in the peoplesoft instance? If not, you should make sure it is in the system prior to using it.
Regarding the lack of error behavior, I have found the peoplesoft component interface APIs for java are notoriously unreliable. You can test them in real time through Application Designer (Via the "Test Component Interface" option in the drop-down menu), which I often find helpful.
Finally, calling session.checkMessages() on your session after performing a method on a CI can often generate error messages that otherwise will not be displayed.
EDIT: Here is a snippet of how we typically call/use it in our PeopleSoft HR instance:
ICiPersonalData wh = (ICiPersonalData)ses.getComponent("CI_PERSONAL_DATA");
if (wh == null) throw new UpdateException("Failed to get component");
wh.setInteractiveMode(true);
wh.setGetHistoryItems(true);
wh.setEditHistoryItems(true);
wh.setKeypropEmplid(emplid);
if (!existsInHR(emplid)) { // Direct database check
LOG.debug("Creating a new HR person.");
if ( ! wh.create() )
LOG.warn("wh.create returned false for emplid ="+emplid);
ses.checkMessages(); // will throw exception if errors exist
wh.setPropDerivedEmp("Y");
rs.put("NEW","Y");
setKeyPersonalData(wh, emplid, rs); // Sets name, etc.
} else {
if (!wh.get())
LOG.warn("wh.get returned false for emplid ="+emplid);
ses.checkMessages();
}

Java Code to fetch Session Store attribute values

I am writing an Assertion Generator Plugin in Java to fetch a user details from Session Store and modify the values in Assertion(SAML 2.0) accordingly.
I am able to identify the method(Link) using which I can pull the user values from Session Store (agentAPIObject.getSessionVariables()) based on SessionID, but, I am having trouble writing a code to fetch specific parameters from the session store. (speficially around setting values for Attribute method and making it as an array)
Can someone post a sample code if you have ever seen/written around it, so that I can fetch user attributes from Session Store.
I am having trouble understanding Java docs around it.
Thanks in advance,
The API mentions this:
responseAttributeList - On successful return from this method (YES is
returned), this output parameter contains the retrieved variable names
and their values. If the method returns UNRESOLVED, this parameter
includes variables that could not be retrieved.
You'll need to create two AttributeList Objects. If the response of getSessionVariables(...) is YES, then the variable responseAttributeList will contain the session variables. Since Java uses references, that same variable responseAttributeList will be updated. You can then use getAttributeAt(...) to access the Attribute Objects.
String sessionID = "sampleID";
ResourceContextDef rcd = //whatever it needs to be equal to
AttributeList requestAttributeList = new AttributeList();
AttributeList responseAttributeList = new AttributeList();
if(getSessionVariables(sessionId, rcd, requestAttributeList, responseAttributeList) == YES){
Attribute att = responseAttributeList.getAttributeAt(0);//or whatever index.
}
Remember to carefully read the API.
NOTE: This is just pseudo code. I have not tested this. However, this should be plenty enough to get you going where you need to.

HttpSession, session.getAttribute(), problem

I have a problem related to Java servlet sessions. I don't understand why the getAttribute() function of the session object is used before setAttribute(); Here is the code:
Vector buylist=(Vector)session.getAttribute("Register");
if (action.equals("del")) {
String del = request.getParameter("deli");
int d = (new Integer(del)).intValue();
buylist.removeElementAt(d);
}
session.setAttribute("Register", buylist);
Thanks.
This code intends to save back the modified vector represented by Register session attribute.
However you dont need to set the attribute back even after some elements are removed or added because its the reference anyways thats stored in session and any changes to it are essentially being applied to the same object.
Because Register attribute may be set from some other place (like. from jsp(in bad case),Servlet or Filter . . )
The only explanation I can think of is: first of all you you retrieve the vector, then make the change and after store it back into session object.
The code is either broken or the setAttribute() is futile.
If you get a mutable container (like a list or a vector) from the session, then it's not necessary to put it again into the session. It's the equivalent of this code:
session.setAttribute("Register", buylist);
session.setAttribute("Register", buylist);
session.setAttribute("Register", buylist);
None but the first line have an effect.
The other possibility is that the code has a bug and what really was meant was this:
Vector buylist = session.getAttribute("Register");
if( buylist == null ) {
buylist = new Vector();
session.setAttribute("Register", buylist);
}
i.e. create a new vector if it doesn't exist already.

OQL query to find all instances and sub-instances of a given class referred to from a session

I'm trying to use jhat/OQL to trace a memory leak in our Tomcat container. The question I want to ask is:
"Show me all the instances (and sub-instances) of foo.bar.Cacheable class that are reachable from javax.servlet.http.HttpSession"
I managed to come up with the following, but this doesn't show subclasses of foo.bar.Cacheable (which is important since this is infact an interface).
select filter(reachables(s), "/foo.bar.Cacheable/(classof(it).name)") from javax.servlet.http.HttpSession s
I tried various permutations of the concept below, but just keep getting errors ("foo" is not defined).
select filter(reachables(s), classof(it) instanceof foo.bar.Cacheable) from javax.servlet.http.HttpSession s
Can anyone help me out with what I'm doing wrong to pose this question through OQL?
In jhat based OQL implementations (jHat, VisualVM) you can exploit the fact that you are not limited to the SQL like syntax but you have a complete javascript engine at your hands.
The following piece of code would do the trick
var containerSuperClass = "javax.servlet.http.HttpSession"
var elementSuperClass = "foo.bar.Cacheable"
// find the container class by name
var alClz = heap.findClass(elementSuperClass)
// retrieve all subclasses
var subClzs = alClz.subclasses()
// filter the list of objects reachables from instances of the container super class
// and all its subclasses so it contains only objects of classes from subClzs
map(heap.objects(containerSuperClass), 'filter(reachables(it), "it != null && contains(subClzs, containsClause(it))")')
// we need to externalize the contains clause because of clash in naming the closure parameter 'it'
function containsClause(rcbl) {
return function(it) {
if (rcbl == null || it == null) return false;
return it.name.equals(classof(rcbl).name)
}
}

Categories