How to resolve "java.lang.NullPointerException: Cannot invoke method startsWith()"? - java

I am new to groovy. I am writing a shared library for Jenkins pipeline. I am facing this java.lang.NullPointerException exception. Below is my code:
def call(Map config = [:], env) {
pipeline {
defaults = [
'pipelineStrategy' : 'deployOnly',
'buildSystem' : 'maven'
] + config
environment {
BRANCH_NAME = "${GIT_BRANCH.split("/")[1]}"
}
boolean autoDeploy = false;
if (env.BRANCH_NAME.equals('master') || env.BRANCH_NAME.startsWith('hotfix-')){
autoDeploy = true;
}
}
}
Below are my Jenkins build logs:
java.lang.NullPointerException: Cannot invoke method startsWith() on null object
at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:48)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:35)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:20)
at pipelineStrategy.call(pipelineStrategy.groovy:21)

The only startsWith() in the code you posted is in
env.BRANCH_NAME.startsWith('hotfix-')
and you are being told that there is a null object. It means that
env.BRANCH_NAME
is null. You will need to think why or how to handle that situation. One way might be to use
String.valueOf(env.BRANCH_NAME).startsWith('hotfix-')

Related

Can't use "Handler" approach to adding a URLStreamHandler in AWS Lambda

I'm currently trying to add a URLStreamHandler so I can handle URLs with custom protocols. This works fine when run locally. When deployed to AWS Lambda I get:
java.net.MalformedURLException: unknown protocol: baas
I'm following the "Handler" approach to registering the URLStreamHandler.
I even went as far as copying the code from URL.getURLStreamHandler(String) and added logging into my own code that is run by Lambda:
(Note: this is from the Java 8 source - I realise now that this might not be representative because AWS Lambda uses a Java 11 runtime).
URLStreamHandler handler = null;
String packagePrefixList = null;
packagePrefixList
= java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction(
"java.protocol.handler.pkgs",""));
if (packagePrefixList != "") {
packagePrefixList += "|";
}
// REMIND: decide whether to allow the "null" class prefix
// or not.
packagePrefixList += "sun.net.www.protocol";
LOG.debug("packagePrefixList: " + packagePrefixList);
StringTokenizer packagePrefixIter =
new StringTokenizer(packagePrefixList, "|");
while (handler == null &&
packagePrefixIter.hasMoreTokens()) {
String packagePrefix =
packagePrefixIter.nextToken().trim();
try {
String clsName = packagePrefix + "." + "baas" +
".Handler";
Class<?> cls = null;
LOG.debug("Try " + clsName);
try {
cls = Class.forName(clsName);
} catch (ClassNotFoundException e) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
if (cl != null) {
cls = cl.loadClass(clsName);
}
}
if (cls != null) {
LOG.debug("Instantiate " + clsName);
handler =
(URLStreamHandler)cls.newInstance();
}
} catch (Exception e) {
// any number of exceptions can get thrown here
LOG.debug(e);
}
}
This prints (in Cloudwatch logs):
packagePrefixList: com.elsten.bliss|sun.net.www.protocol (BaasDriver.java:94, thread main)
Try com.elsten.bliss.baas.Handler (BaasDriver.java:108, thread main)
Instantiate com.elsten.bliss.baas.Handler (BaasDriver.java:118, thread main)
com.elsten.bliss.baas.Handler constructor (Handler.java:55, thread main)
So, when run from my own code, in Lambda, it works.
However, the very next line of logging:
java.lang.IllegalArgumentException: URL is malformed: baas://folder: java.lang.RuntimeException
java.lang.RuntimeException: java.lang.IllegalArgumentException: URL is malformed: baas://folder
...
Caused by: java.net.MalformedURLException: unknown protocol: baas
at java.base/java.net.URL.<init>(Unknown Source)
at java.base/java.net.URL.<init>(Unknown Source)
at java.base/java.net.URL.<init>(Unknown Source)
So it seems odd the same code is failing when run in URL. The main difference I can think of is the parent classloader used to load URL and my code are different, and so there's some sort of class loading issue.
The SPI approach can't be used because Lambda doesn't extract META-INF folders!
Initially I thought the old URL.setURLStreamHandlerFactory(URLStreamHandlerFactory) approach was to be avoided, but it turns out this has been improved in recent Java versions, and so I have fallen back to that.
Specifically, a default fallback URLStreamHandlerFactory which is capable of handling streams to http, https, file et al is used as a fallback if the custom one provided cannot handle a stream.
This is a workaround though - it would be interesting to know why the class cannot be loaded.

suppress rjava error output in console

How can I suppress the rJava output to the console in the following example?
library(rJava)
TC <- J("edu.cens.spatial.RTileController")
dummy <- capture.output(suppressWarnings(suppressMessages(
res <- TC$getInstance(type="osm-bw")$getTileValues(4389,2691,13)
)))
Despite capture.output, I still get the following in the console:
java.lang.NullPointerException
at edu.cens.spatial.RTileController.getTileValues(RTileController.java:109)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at RJavaTools.invokeMethod(RJavaTools.java:386)
Edit: In pure R Console (without Rstudio), I get no messages (but I have to call library("OpenStreetMap") first). So this might be an Rstudio issue after all ... The question is now: how can I suppres Java output to the R console in Rstudio? Is it possible to do this when calling osmtile as outlined below?
PS1: It works for osm instead of osm-bw.
PS2: I came across this via
tile <- OpenStreetMap::osmtile(x=4389,y=2691,zoom=13,type="osm-bw")
In my case, something like this works - NullPointer message is suppressed:
> s <- .jcall(obj, returnSig="V", method="nullcall")
Error in .jcall(obj, returnSig = "V", method = "nullcall") :
java.lang.NullPointerException: Exception
> suppressMessages(s <- .jcall(obj, returnSig="V", method="nullcall"))
To reproduce this code do following:
Create file (from within R)
dir.create("utils")
dir.create("target")
cat('package utils;
public class RUsingStringArray {
public void nullcall() throws NullPointerException {
throw new NullPointerException("Exception");
}
public static void main(String [] arg) {
RUsingStringArray obj = new RUsingStringArray();
obj.nullcall();
}
}', file="utils/RUsingStringArray.java")
Compile java code (in cmd / terminal, last line won't work on windows)
javac -d target utils/*.java
java -cp target utils/RUsingStringArray
Exception in thread "main" java.lang.NullPointerException: Exception
at utils.RUsingStringArray.nullcall(RUsingStringArray.java:19)
at utils.RUsingStringArray.main(RUsingStringArray.java:24)
export CLASSPATH=`pwd`/target
Inside R
library(rJava)
.jinit("C:/path_to_folder/target") # leave empty if CLASSPATH was set
obj <- .jnew("utils.RUsingStringArray")
s <- .jcall(obj, returnSig="V", method="nullcall")
suppressMessages(s <- .jcall(obj, returnSig="V", method="nullcall"))
Error in .jcall(obj, returnSig = "V", method = "nullcall") :
java.lang.NullPointerException: Exception

Unable to call DOC_INFO_BY_NAME from a Custom WCC Java Service

I'm creating a Custom Java Component for oracle-ucm to do some processing based on passed in Excel Files. The files are keyed off of Content ID.
one of the first things the application does after reading the excel file is call DOC_INFO_BY_NAME.
In short: Why can't DOC_INFO_BY_NAME by name find dProcessingState and how do I fix it?
Full Details Below
However, when I do I get the following Error Message:
Error getting DOC_INFO for 'LOCALHOST16200000001'. Unable to retrieve information for 'LOCALHOST16200000001'. Unable to retrieve file format information. Cannot find the parameter 'dProcessingState'. [ Details ]
An error has occurred. The stack trace below shows more information.
!$Error getting DOC_INFO for 'LOCALHOST16200000001'.!csUnableToGetRevInfo2,LOCALHOST16200000001!csUnableToGetFileFormatInfo!syParameterNotFound,dProcessingState
intradoc.common.ServiceException: !csUnableToGetRevInfo2,LOCALHOST16200000001!csUnableToGetFileFormatInfo
at intradoc.server.ServiceRequestImplementor.buildServiceException(ServiceRequestImplementor.java:2176)
at intradoc.server.Service.buildServiceException(Service.java:2404)
at intradoc.server.Service.createServiceExceptionEx(Service.java:2398)
at intradoc.server.Service.createServiceException(Service.java:2393)
at intradoc.server.DocCommonHandler.getDocFormats(DocCommonHandler.java:271)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at intradoc.common.IdcMethodHolder.invokeMethod(IdcMethodHolder.java:86)
at intradoc.common.ClassHelperUtils.executeMethodReportStatus(ClassHelperUtils.java:324)
at intradoc.server.ServiceHandler.executeAction(ServiceHandler.java:79)
at intradoc.server.Service.doCodeEx(Service.java:622)
at intradoc.server.Service.doCode(Service.java:594)
at intradoc.server.ServiceRequestImplementor.doAction(ServiceRequestImplementor.java:1693)
at intradoc.server.Service.doAction(Service.java:566)
at intradoc.server.ServiceRequestImplementor.doActions(ServiceRequestImplementor.java:1483)
at intradoc.server.Service.doActions(Service.java:561)
at intradoc.server.ServiceRequestImplementor.executeActions(ServiceRequestImplementor.java:1415)
at intradoc.server.Service.executeActions(Service.java:547)
at intradoc.server.ServiceRequestImplementor.doRequestInternalEx(ServiceRequestImplementor.java:958)
at intradoc.server.ServiceRequestImplementor.executeServiceTopLevelSimple(ServiceRequestImplementor.java:1070)
at com.lowes.content.edam.massMetaDataUpdate.service.types.ServicesWrapper.executeService(ServicesWrapper.java:139)
at com.lowes.content.edam.massMetaDataUpdate.service.file.GetFileService.getDocInfo(GetFileService.java:478)
at com.lowes.content.edam.massMetaDataUpdate.service.ServiceFieldMapper.getMappings(ServiceFieldMapper.java:76)
at com.lowes.content.edam.massMetaDataUpdate.file.mapper.impl.FieldMapWorker.doInBackground(FieldMapWorker.java:107)
at com.lowes.content.edam.massMetaDataUpdate.file.mapper.impl.FieldMapWorker.doInBackground(FieldMapWorker.java:37)
at javax.swing.SwingWorker$1.call(SwingWorker.java:277)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at javax.swing.SwingWorker.run(SwingWorker.java:316)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
Caused by: intradoc.data.DataException: !syParameterNotFound,dProcessingState
at intradoc.data.DataBinder.getEx(DataBinder.java:1258)
at intradoc.data.DataBinder.get(DataBinder.java:1057)
at intradoc.server.DocCommonHandler.getProcessingState(DocCommonHandler.java:277)
at intradoc.server.DocCommonHandler.getDocFormats(DocCommonHandler.java:184)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at intradoc.common.IdcMethodHolder.invokeMethod(IdcMethodHolder.java:87)
at intradoc.common.ClassHelperUtils.executeMethodReportStatus(ClassHelperUtils.java:324)
at intradoc.server.ServiceHandler.executeAction(ServiceHandler.java:79)
at intradoc.server.Service.doCodeEx(Service.java:622)
at intradoc.server.Service.doCode(Service.java:595)
... 20 more
I've tried multiple ways of calling the additional service.
currently I'm using:
public DataBinder executeService(DataBinder binder, Workspace workspace)
throws DataException, ServiceException
{
final String serviceName = binder.getLocal(Services.IdcService);
//check for REMOTE_USER
String username = binder.getEnvironmentValue("REMOTE_USER");
if ( null == username || "".equals(username.trim()))
{
log.warn("username not found, searching the binder.");
try { username = binder.get("dUser"); }
catch (DataException de) { log.error("Unable to get Username.", de); }
if ( null != username && !"".equals(username.trim()))
{ binder.setEnvironmentValue("REMOTE_USER", username); }
else { throw new IllegalStateException("Username required!"); }
}
//clear idcToken
binder.getLocalData().remove("idcToken");
log.info("About to run '" + serviceName + "' as '" + username +"'");
try
{
log.info("Calling service " + serviceName + ": "
+ binder.getLocalData().toString());
// Execute service
service.createRequestImplementor();
service.getRequestImplementor()
.executeServiceTopLevelSimple(binder, serviceName,
service.getUserData());
log.info("Finished calling service");
return service.getBinder();
}
catch (DataException e)
{
String msg = "Unexpected Failure executing service '"+serviceName+"'";
log.info(msg, e);
throw e; //log and duck
}
}
So why can't WCC find dProcessingState, and how do I fix it?
Your way of calling the service is fairly standard and I don't think that is the reason. My first guess is that your other code is interfering with your call to DOC_INFO_BY_NAME. If you disable all your other custom code (perhaps easier said than done) and call the service in a clean component, then I think it'll work. Second candidate is to reconsider if your custom service really should be a FileService. Not sure if that affects the result, but perhaps worth a try.
It almost seems like a bug to me.
getProcessingState() is called from getDocFormats() which is called from the DOC_INFO* service.
The code for getProcessingState() first retrieves dProcessingState.
String curProcState = this.m_binder.get("dProcessingState");
Then, it checks if this is null:
if (curProcState != null)
However, it never gets to the null check. This is because DataBinder.get() is requiring a value for any key passed in (in this case dProcessingState.)
Trying setting dProcessingState to a value in the DataBinder before calling the service.
binder.setLocal("dProcessingState", "ignore");
The problem was totally my fault. I had tried to be fancy, and extend Databinder to make it easier for me to use. Turns out my extension was faulty.
Rolling back to the default and double checking my data in the binder fixed it.

how to set Hadoop DistributedCache?

when I run the hadoop code to add the third jar,just like the following code:
public static void addTmpJar(String jarPath, JobConf conf) throws IOException {
System.setProperty("path.separator", ":");
FileSystem fs = FileSystem.getLocal(conf);
String newJarPath = new Path(jarPath).makeQualified(fs).toString();
String tmpjars = conf.get("tmpjars");
if (tmpjars == null || tmpjars.length() == 0) {
conf.set("tmpjars", newJarPath);
} else {
conf.set("tmpjars", tmpjars + "," + newJarPath);
}
}
I get the following exception:
Error initializing attempt_201405281453_0053_m_000002_0:
org.apache.hadoop.util.DiskChecker$DiskErrorException: Could not find any valid local directory for taskTracker/hadoop/distcache/-7315515059647727905_-860888033_1107570546/nn.hadoop.dev/tmp/hadoop-hadoop/mapred/staging/hadoop/.staging/job_201405281453_0053/libjars/mahout-core-0.8-job.jar
at org.apache.hadoop.fs.LocalDirAllocator$AllocatorPerContext.getLocalPathForWrite(LocalDirAllocator.java:381)
at org.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:146)
at org.apache.hadoop.filecache.TrackerDistributedCacheManager.getLocalCache(TrackerDistributedCacheManager.java:173)
at org.apache.hadoop.filecache.TaskDistributedCacheManager.setupCache(TaskDistributedCacheManager.java:187)
at org.apache.hadoop.mapred.TaskTracker$4.run(TaskTracker.java:1320)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1190)
at org.apache.hadoop.mapred.TaskTracker.initializeJob(TaskTracker.java:1311)
at org.apache.hadoop.mapred.TaskTracker.localizeJob(TaskTracker.java:1226)
at org.apache.hadoop.mapred.TaskTracker$5.run(TaskTracker.java:2603)
at java.lang.Thread.run(Thread.java:744)
any one who can tell how to solve this problem,thanks!
From the commandline you can add a jar to the distributedcache using -libjars, the only prerequisite is that your MR program implements Tool which uses GenericOptionsParser, the latter takes care of adding the jar to the cache.
This page explains the above in more detail

Play 1.2.2 - are tags inside tags no longer allowed?

I am developing an application in play and in my selenium tests I use several tags for repetitive tasks. Two tags are:
app/views/tags/loginAs.html
*{ Tag for running selenium tests when being logged in }*
#{if !_keepData}
#{braindumpFixture delete:'all', load:'users.yml' /}
#{/if}
#{selenium}
... some selenium code to log into the application
#{/selenium}
app/views/tags/braindumpFixture.html
%{
if(_delete == 'all') {
play.test.Fixtures.deleteAll()
} else if(_delete) {
play.test.Fixtures.delete(_delete)
}
}%
%{
if(_load) {
play.test.Fixtures.load(_load)
}
// finally make sure the index is correctly updated.
new application.jobs.CompleteReindexJob().doJob();
}%
These work without a problem in Play 1.1. After switching to play 1.2.2, I get the following exception when running a selenium test that uses loginAs:
test/selenium/AddCard.test.html
*{ Tests adding a simple card }*
#{loginAs login:'foobar#foobar.com', password:'foobar' /}
#{selenium}
open('#{Application.index()}')
... more selenium stuff here
#{/selenium}
The exception being:
play.exceptions.TemplateExecutionException: Cannot get property 'data' on null object
at play.templates.BaseTemplate.throwException(BaseTemplate.java:84)
at play.templates.GroovyTemplate.internalRender(GroovyTemplate.java:252)
at play.templates.GroovyTemplate$ExecutableTemplate.invokeTag(GroovyTemplate.java:374)
at /test/selenium/AddCard.test.html.(line:3)
at play.templates.GroovyTemplate.internalRender(GroovyTemplate.java:229)
at play.templates.Template.render(Template.java:26)
at play.templates.GroovyTemplate.render(GroovyTemplate.java:184)
at controllers.TestRunner.run(TestRunner.java:107)
at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:543)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:499)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:475)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:470)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:158)
at Invocation.HTTP Request(Play!)
Caused by: java.lang.NullPointerException: Cannot get property 'data' on null object
at play.templates.GroovyTemplate.internalRender(GroovyTemplate.java:229)
... 12 more
When I remove the #{if !_keepData} around the call to braindumpFixture I get an EmptyStackException:
play.exceptions.TemplateExecutionException
at play.templates.BaseTemplate.throwException(BaseTemplate.java:84)
at play.templates.GroovyTemplate.internalRender(GroovyTemplate.java:252)
at play.templates.Template.render(Template.java:26)
at play.templates.GroovyTemplate.render(GroovyTemplate.java:184)
at controllers.TestRunner.run(TestRunner.java:107)
at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:543)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:499)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:475)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:470)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:158)
at Invocation.HTTP Request(Play!)
Caused by: java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:85)
at java.util.Stack.pop(Stack.java:67)
at play.templates.TagContext.exitTag(TagContext.java:31)
at play.templates.GroovyTemplate$ExecutableTemplate.invokeTag(GroovyTemplate.java:380)
at /test/selenium/AddCard.test.html.(line:3)
at play.templates.GroovyTemplate.internalRender(GroovyTemplate.java:229)
... 9 more
I wonder if something fundamentally changed with tags in Play 1.2 and I just overlooked it in the documentation or if this might be a bug. Any ideas on solving this riddle are welcome.
The issue is the #{fixture} tag. It will kill the internal stack when loading an yml file. See https://play.lighthouseapp.com/projects/57987-play-framework/tickets/1026-using-tags-inside-tags-is-broken-since-play-121#ticket-1026-3.
As a workaround you can create a modified version of the fixture tag:
%{
if(_delete == 'all') {
play.test.Fixtures.deleteAll()
} else if(_delete) {
play.test.Fixtures.delete(_delete)
}
}%
%{
if(_load) {
// Workaround (save the stack)
stack = play.templates.TagContext.currentStack.get();
play.test.Fixtures.load(_load)
// Workaround (restore the stack)
play.templates.TagContext.currentStack.set(stack);
}
}%
%{
if(_arg && _arg instanceof String) {
try {
play.Play.classloader.loadClass(_arg).newInstance()
} catch(Exception e) {
throw new play.exceptions.TagInternalException('Cannot apply ' + _arg + ' fixture because of ' + e.getClass().getName() + ', ' + e.getMessage())
}
}
%}
I am not aware that anything should have changed to stop this from working, so would expect this is a bug.

Categories