I'm creating a new OSGi plugin and I need to use the current user's session. The code in the plugin is called from a xe:customRestService in 'doGet'.
Now I was not able to 'just' pass the session over, so I used ExtLibUtil.getCurrentSession(); Now all compiles correctly and I can debug the code, but whenever I 'use' this session to get, for example, the current servername, it throws:
java.lang.NoClassDefFoundError: lotus/domino/Session
What dependency is my project missing or is there another possibility?
When I use ExtLibUtil.getCurrentSession() the session becomes invalid somehow, I don't know why but after a lot of testing this combination works. The 'getUserSession()' call somehow fixed the problem....
Session session = com.ibm.domino.osgi.core.context.ContextInfo.getUserSession();
session = ExtLibUtil.getCurrentSession();
I still don't understand why this works andSession session = ExtLibUtil.getCurrentSession(); does not.
Related
I'm trying to upgrade to Hazelcast 4.0 in our Spring Boot 2.2.1 application.
We use the #EnableHazelcastHttpSession annotation, which pulls in HazelcastHttpSessionConfiguration, which pulls in HazelcastIndexedSessionRepository from the spring-session-hazelcast jar.
However, this class won't compile because it imports Hazelcast's IMap which has moved to a different package in Hz 4.0.
Is there any way to fix this so that Spring Session works with Hazelcast 4?
I just copied the HazelcastIndexedSessionRepository into my own source code, changed the import from com.hazelcast.core.IMap to com.hazelcast.map.IMap, and swapped the sessionListenerId from String to UUID. If I keep it in the same package, then it loads my class instead of the one in the jar, and everything compiles and works fine.
Edit: We no longer get the SessionExpiredEvent, so something's not quite right, but manual testing shows us that our sessions do time out and force the user to log in again, even across multiple servers.
I found the cause of the error, you must look that the session repository is created by HazelcastHttpSessionConfiguration, in the class it checks wich version of hazelcast is in the classpath, when hazelcast4 is true then it instantiates Hazelcast4IndexedSessionRepository that doesn't use 'com.hazelcast.core.IMap' and you don't get the class not found exception.
Code of class HazelcastHttpSessionConfiguration
#Bean
public FindByIndexNameSessionRepository<?> sessionRepository() {
return (FindByIndexNameSessionRepository)(hazelcast4 ? this.createHazelcast4IndexedSessionRepository() : this.createHazelcastIndexedSessionRepository());
}
Remove the usage of HazelcastIndexedSessionRepository replace it with Hazelcast4IndexedSessionRepository or remove the code and let spring autoconfiguration do the job by HazelcastHttpSessionConfiguration
We are getting following below error when we deploy any application in Liferay DXP 7.
When we clean the Liferay DXP and then redeploy the below issue gets fixed.
But the problem with this approach is that all the caches gets deleted after cleaning and when we redeploy and access the site , the caches gets recreated but it takes lot of time to access any page on the site.
[2018-05-17 10:58:33,113] [DEBUG] [10.111.2.74] [] [http-nio-5443-exec-8] [com.fsvps.clientPortal.service.common.ProgramFilterPopulator] - Retrieving logged in user
[2018-05-17 10:58:33,137] [DEBUG] [10.111.2.74] [] [http-nio-5443-exec-8] [com.fsvps.clientPortal.util.common.UserContextInitializationInterceptor] - Portlet mode view and debug mode = false
[2018-05-17 10:58:33,137] [DEBUG] [10.111.2.74] [] [http-nio-5443-exec-8] [com.fsvps.clientPortal.util.common.UserContextInitializationInterceptor] - Checking to see if invalid filter view should be shown
[2018-05-17 11:07:40,859] [DEBUG] [] [] [http-nio-5443-exec-2] [com.fsvps.clientPortal.util.common.UserContextInitializationInterceptor] - Entering
[2018-05-17 11:07:40,859] [WARN] [] [] [http-nio-5443-exec-2] [org.springframework.web.portlet.DispatcherPortlet] - Handler execution resulted in exception - forwarding to resolved error view
java.lang.ClassCastException: com.fsvps.clientPortal.domain.common.UserContext cannot be cast to com.fsvps.clientPortal.domain.common.UserContext
at com.fsvps.clientPortal.domain.common.UserContext$$FastClassBySpringCGLIB$$818d2483.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at com.fsvps.clientPortal.domain.common.UserContext$$EnhancerBySpringCGLIB$$830ac420.setIpAddress(<generated>)
at com.fsvps.clientPortal.util.common.UserContextInitializationInterceptor.preHandle(UserContextInitializationInterceptor.java:93)
at org.springframework.web.portlet.handler.HandlerInterceptorAdapter.preHandleRender(HandlerInterceptorAdapter.java:72)
at org.springframework.web.portlet.DispatcherPortlet.doRenderService(DispatcherPortlet.java:739)
at org.springframework.web.portlet.FrameworkPortlet.processRequest(FrameworkPortlet.java:537)
The exact cause is impossible to pinpoint with the information you give. However, the class of problem is easy to identify:
java.lang.ClassCastException:
com.fsvps.clientPortal.domain.common.UserContext cannot be cast to
com.fsvps.clientPortal.domain.common.UserContext
(separated to lines to illustrate the identical class name)
Whenever a class can't be typecasted to itself or a legitimate superclass/interface, you're dealing with duplicate code: There are two versions of the class with the same name available to the classloader, and the system is choosing both.
As the error message just contains the name of the class, not its classloader, a first glance at the error message doesn't make sense. Knowing that a class is uniquely described by its package, name, and its classloader leads you to the root cause.
Identify your modules and make sure that there's only one option for com.fsvps.clientPortal.domain.common.UserContext available.
Edit: Answering to your comments - without knowing your deployment details, there's no way to help you other than wild guesses. Please add more information to your question if the next wild guess doesn't help:
The name of the class, UserContext, suggests that you might store it somewhere, e.g. in a session. Doing so will prevent the original class from unloading when you're undeploying your plugin. Note that there is a huge difference between undeploying code and garbage collecting objects: GC can only happen, when there is no more reference.
If you deploy an updated version of your plugin, the old and existing objects still are referencing the previously loaded UserContext class, while the new code is trying to assign it to a new UserContext reference. Even though, both might be identical in implementation, they are different classes that just share the name.
You can't keep long living references to code that might undeploy, and expect them to stay usable. A quick fix (if you're deploying OSGi modules) might be to extract stable and long-used classes into its own bundle that you won't redeploy. Or replace session stored objects (assuming that this is it) with Java runtime classes, e.g. Map of built-in types, and build a UserContext object from those types whenever you need it.
Previously I have been able to run this script that read events from a url.ics
import net.fortuna.ical4j.util.Calendars
import net.fortuna.ical4j.model.component.VEvent
#Grapes(
#Grab(group='org.mnode.ical4j', module='ical4j', version='2.2.0')
)
def url = 'https://calendar.google.com/calendar/ical/xxxx/basic.ics'.toURL()
def cal = Calendars.load(url)
However, now I am getting this exception java.lang.NoClassDefFoundError: javax/cache/configuration/Configuration.
I assume there is some sort of dependency change that has occurred. I have noted this
javax.cache.cache-api [optional*] - Supports caching timzeone definitions. * NOTE: when not included you must set a value for the net.fortuna.ical4j.timezone.cache.impl configuration
however, now I am getting this java.lang.NoClassDefFoundError: Could not initialize class net.fortuna.ical4j.validate.AbstractCalendarValidatorFactory
any help appreciated.
ical4j looks for a properties file called ical4j.properties and loads configuration from it. Create this file in the same folder and add
net.fortuna.ical4j.timezone.cache.impl=net.fortuna.ical4j.util.MapTimeZoneCache
to specify in-memory cache provider that uses ConcurrentHashMap. When property net.fortuna.ical4j.timezone.cache.impl is not specified, ical4j falls back to JCacheTimeZoneCache which uses cache manager and requires valid caching library to be present in the classpath.
The alternative to using ical4j.properties file is to set this property programatically, e.g.
System.setProperty("net.fortuna.ical4j.timezone.cache.impl", "net.fortuna.ical4j.util.MapTimeZoneCache")
Just remember to set it before calling Calendars.load(url) and it should work.
How to clean SSJS (Server Side Javascript) in Domino server after someone used javascript prototype in a nsf?
Mark Roden discovered a huge weakness in XPages SSJS: (thanks to David Leedy for tell me about this and show me the article).
If you have the following SSJS code:
var dummyObj = {}
dummyObj.prototype.NAME = "Johann"
XPages SSJS doesn't care that you uses var (var means the variable must be local) and it makes dummyObj.NAME visible in the whole server with the value Johann. So if another nsf in the same server uses a var with the same name it inherits the whole prototype:
var dummyObj = {}
println(dummyObj.NAME) /*prints "Johann" */
This is a huge bug (one that makes unreliable XPages SSJS IMO). Even if you don't use prototype at all, if someone else in his application do something like this:
String.prototype.split = function(){ return "I broke this method" }
It will broke all applications in the same server that uses the innocent split().
So, the question is: if someone "by mistake" writes the following SSJS (XPages Server Side Javascript) in a NSF:
String.prototype.split = function(){ return "I broke this method" }
How can I fix String.prototype.split() to his original value?
As Mark Roden said, restarting HTTP task doesn't fix it.
///////////////////////////////////////////////////////////
Edit 1: Why I think this is a huge bug:
I'm a Javascript fan but IMHO #MarkyRoden has discovered a huge bug in SSJS. Shims and polyfills aren't really the main problem. Eval is known to be a bad practice but the prototype object is a fundamental element of basic Javascript. It's the standard and preferred way to add methods to Javascript classes, it's also needed for inheritance and all kind of OOP stuff. So you will need some kind of namespace at server level in order to avoid collisions. All this is really bad but the huge problem is that just a line of code in one application can broke all applications in a server. Yes, you can trust in your developers but one of them can write a bad line by mistake and also a Domino server can have hundreds of applications from different software vendors. Set the responsability in code reviews is not a reliable enought procedure. Maybe it's time to have a real javascript engine in SSJS, like V8, Spidermonkey, Chakra or Rhino. As a workaround, I'm thinking in something like Tommy Valand's idea with Rhino in SSJS.
Edit 2: It's even worse. You can do things like:
prototype.importPackage = null
or
prototype.Array = null
As you can see in #SvenHasselbach's article: http://hasselba.ch/blog/?p=1371
Edit 3: IBM: you told me I could use SSJS. COME ONE! PLEASE FIX THIS, it's AWFUL. Please let's officially report this issue to IBM.
You can reset the SSJS interpreter with the following Java code:
FacesContextExImpl fc = (FacesContextExImpl) FacesContextExImpl.getCurrentInstance();
UIViewRootEx2 uiRoot = (UIViewRootEx2) fc.getViewRoot();
JSContext jsContext = uiRoot.getJSInterpreter().getJSContext();
jsContext.getRegistry().init(jsContext);
This reinitializes the registry and all prototype functions.
EDIT: Changed the declaration of fc to the correct type.
EDIT 2:
Here is the SSJS version:
var uiRoot = facesContext.getViewRoot();
var jsContext = uiRoot.getJSInterpreter().getJSContext();
var reg = jsContext.getRegistry();
reg.init( jsContext );
Does I understand you correctly, that you want to clean up the SSJS interpreter to avoid a collision with your own prototype extension?
Just to clarify the answer above: This reinitializes the SSJS interpreter once. And only once.
You have to do this over and over again, because directly after reinitializing, another application on the server can overwrite the prototype functionality again. That's why this is not a real solution, it is an answer to your initial question.
It will have interessting consequences if another application will do the same while your code tries to use your extension...
try to do a Restart Task Http instead
tell http restart will not do a full restart of the http task
I'm sure I'm missing something, but I'm not seeing it at all.
I'm creating PDFs using iText, and I want to do this in a bean. I've created one, but it's been erroring out. It seems some of the ways I've usually worked in Java don't seem to work in this bean.
For example, this line:
com.itextpdf.text.Document document1 = new com.itextpdf.text.Document();
will throw the error java.lang.NoClassDefFoundError: com.itextpdf.text.Document, even though the jar is imported, in the build path and com.itextpdf.text.Document is imported in the bean.
if you change it to this:
com.itextpdf.text.Document document1;
or
com.itextpdf.text.Document document1 = null;
the error goes away. I don't understand why one way works and the other doesn't, but it's a fairly easy change to make.
Now I need to set the page size. This will work in Eclipse:
document1.setPageSize(PageSize.LETTER);
but this is the error I get:
java.lang.NoClassDefFoundError: com.itextpdf.text.PageSize
Which might be because I've set it to null to initialize it. But
document1 = new Document();
and
document1 = new com.itextpdf.text.Document();
both throw java.lang.NoClassDefFoundError: com.itextpdf.text.Document
Oddly, the import statement for (iText) Document warns me it is never used.
document1.open();
will give the error java.lang.NoClassDefFoundError: com.itextpdf.text.Document as well.
So, am I missing something in the syntax in beans? I've created Notes Java agents, XAgents, and straight up Java Eclipse projects that work, but I can't get the methods to work in a 8.5.3 Java Bean. I imported the iText jars into WebContent\WEB-INF\lib and then added those (via add jars, not add external jars) to the build path. I've gotten the latest jars and I'm using them, I've built and cleaned, the bean is in faces-config. But I'm doing something wrong, and I can't see it.
If someone could point me in the right direction, I would be very grateful.
Cheers,
Brian
EDIT:
The license isn't a problem, but I still can't get the class to load even using the classLoader:
Thread currentThread = Thread.currentThread();
ClassLoader clCurrent = currentThread.getContextClassLoader();
//ClassLoader clCurrent=com.ibm.domino.xsp.module.nsf.NotesContext.getCurrent().getModule().getModuleClassLoader();
try {
currentThread.setContextClassLoader(Activator.class.getClassLoader());
DebugToolbar.get().info("after setting up FileOutputStream");
com.itextpdf.text.Document document1 = new com.itextpdf.text.Document();
//com.itextpdf.text.Document document1;
//com.itextpdf.text.Document document1 = null;
//document1 = new com.itextpdf.text.Document();
//document1.open();
document1.setPageSize(PageSize.LETTER);
I still get java.lang.NoClassDefFoundError: com.itextpdf.text.Document
I've cut the beans out, cleaned, built, pasted back in, cleaned built, still the error.
I appreciate the assistance.
Brian
Most likely you have a classloader isssue. Unless your app is strictly for internal use, you might reconsider use of iText since it is GPL. Apache PDFBox is an Apache licensed alternative (I'm particularly fond of) or Apache FOP (I'll complete the ]2 missing articles](http://www.wissel.net/blog/htdocs/DominoXSLT), promise). Of course OpenNTF's POI4XPages might just be what you need.
I called Lotus/ICS support. It seems for 8.5.3, if you put the jars in ~Lotus\Notes\jvm\lib\ext they will load. I'm testing this on my local, but the same path should work on the server. I'll test that Monday. I had researched, and if that is mentioned I didn't find it. Jars will be a design element in 9, putting them in a directory like this should not be needed for that version, but it seems that adding them this way is more consistent now. The jars have loaded properly for some applications I've made, so this confused me a bit.
Stephan and Panu, thank you for responding.
Brian