Null pointer exception when jenkins version is set to 2.X - jenkins

I have a plugin with jenkins version set to 1.580.3.And when I upgrade the jenkins version to 1.642.3<=version , it is throwing a null pointer exception.Below is the stacktrace
java.lang.NullPointerException
at hudson.model.Label.hashCode(Label.java:528)
at java.util.HashMap.hash(HashMap.java:338)
at java.util.HashMap.put(HashMap.java:611)
at java.util.HashSet.add(HashSet.java:219)
at java.util.Collections.addAll(Collections.java:5401)
at com.google.common.collect.Sets.newHashSet(Sets.java:183)
at com.ericsson.oss.axis.ATest.setUp(ATest.java:45)
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 org.junit.internal.runners.MethodRoadie.runBefores(MethodRoadie.java:132)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:95)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
below is my code
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.Is.is;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.jvnet.jenkins.plugins.nodelabelparameter.LabelParameterValue;
import org.mockito.Answers;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.XXXXX.JenkinsUtils;(internal)
import com.google.common.collect.Sets;
import hudson.model.AbstractBuild;
import hudson.model.Label;
import hudson.model.ParameterValue;
import hudson.model.ParametersAction;
import jenkins.model.Jenkins;
#RunWith(PowerMockRunner.class)
#PrepareForTest( JenkinsUtils.class)
public class A{
#Mock
private Label label;
#Mock
private Jenkins jenkins;
#Mock(answer = Answers.RETURNS_DEEP_STUBS)
private AbstractBuild build;
#Before
public void setUp() {
PowerMockito.mockStatic(JenkinsUtils.class);
try {
doReturn(Sets.newHashSet(label)).when(jenkins).getLabels();
} catch (Exception e) {
e.printStackTrace();
}
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest(NodeLabelParameterUtils.class )
public class B{
private BaselineDefinedMessageDispatcher unit;
private BuildData buildData = new BuildData();
private MyBuildDetails myBuildDetails;
#Mock(answer = Answers.RETURNS_DEEP_STUBS)
private AbstractBuild build;
#Mock
private BuildLogger buildLogger;
#Mock
private Label label;
#Mock
private Computer computer;
#Mock
private PretendSlave node;
#Mock
private FreeStyleProject project;
#Mock
private Jenkins jenkins;
#Mock
private EnvironmentVariableResolver envVarsResolver;
#Before
public void setUp() throws IOException, InterruptedException, Descriptor.FormException {
unit = spy(new BaselineDefinedMessageDispatcher(null, null));
unit.setBuildLogger(mock(BuildLogger.class));
MyBuildDetails = mock(MyBuildDetails.class);
doReturn("expectedSlaveHost").when(unit).getHostNameFromSlave(any(Node.class));
doReturn(project).when(build).getProject();
doReturn(Sets.<Node>newHashSet(node)).when(label).getNodes();
doReturn(node).when(build).getBuiltOn();
doReturn(jenkins).when(unit).getJenkinsInstance();
doReturn(Sets.newHashSet(label)).when(jenkins).getLabels();
PowerMockito.mockStatic(A.class);
when(envVarsResolver.processString(anyString())).thenAnswer(new Answer<String>() {
#Override
public String answer(InvocationOnMock invocationOnMock) throws Throwable {
return (String) invocationOnMock.getArguments()[0];
}
});
}
The following dependencies are being used
powermock-api-mockito - 1.6.3
mockito-core - 1.9.5
junit - 4.11
java - 1.8
jenkins.version - 1.642.3
I get the error exactly at doReturn(Sets.newHashSet(label)).when(jenkins).getLabels(); in class A.
This is a maven project and when jenkins version is set to 1.580.3 mvn clean install is success but when it is version>=1.642.3 it is failing.
My aim is to upgrade jenkins verison to 2.X.I went through manyworkarounds in stackoverflow but nothing worked
Any help is appreciated

Edit:
Looks like my orignal answer was just incorrect.
The NPE comes from the fact that the abstract Label class has a constructor parameter called name. This parameter is used to calculate the hashcode of the label.
If you mock it this name is null and you get the NPE.
The question now is do you need to create a mock of this or can you actually use a real instance? In the exmaple below I just used one of the implementations of that class LabelAtom. If a mock is required because you need to define some behaviour on the object that you can not get otherwise, you probably have to use a spy.
(Tested with org.jenkins-ci.main:jenkins-core:2.85)
import static org.mockito.Mockito.doReturn;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.modules.junit4.PowerMockRunner;
import com.google.common.collect.Sets;
import hudson.model.Label;
import hudson.model.labels.LabelAtom;
import jenkins.model.Jenkins;
#RunWith(PowerMockRunner.class)
public class Test {
#Mock
private Jenkins jenkins;
private Label label;
#Before
public void setUp() {
Assert.assertNotNull(jenkins);
label = new LabelAtom("someName");
// or if a mock is required
//label = Mockito.spy(new LabelAtom("someName"));
doReturn(Sets.newHashSet(label)).when(jenkins).getLabels();
}
#Test
public void test() {
}
}
Regarding the WithOrWithoutExpectedArguments I was not able to reproduce that one.

Related

spring-data-elasticsearch latest version throws NullPointer exception with Elasticsearch 8.1 version

Planning to use elasticsearch 8.1 version and use 'org.springframework.boot:spring-boot-starter-data-elasticsearch' in
our project.
Repository.save() throws following exception.
java.lang.NullPointerException: null
at java.base/java.util.Objects.requireNonNull(Objects.java:221)
at org.elasticsearch.action.DocWriteResponse.(DocWriteResponse.java:116)
at org.elasticsearch.action.index.IndexResponse.(IndexResponse.java:43)
The same code with Elasticsearch 7.15.2 works fine.
I see the supported matrix here https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#preface.requirements
Where to see the road map of Spring boot elasticsearch data plugin? When Do we get the plugin support for the 8.1 version of
Elasticsearch?
Thanks in advance
Adding the following headers resolved the issue.
Accept: "application/vnd.elasticsearch+json;compatible-with=7"
Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
Its better to change your code which is used for creating client
package com.search.elasticsearchapp.config;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import org.springframework.http.HttpHeaders;
#Configuration
#EnableElasticsearchRepositories(basePackages = "*")
public class TestClient {
#Value("${elasticsearch.host}")
private String host;
#Value("${elasticsearch.port}")
private int port;
#Value("${elasticsearch.protocol}")
private String protocol;
#Value("${elasticsearch.username}")
private String userName;
#Value("${elasticsearch.password}")
private String password;
#Bean(destroyMethod = "close")
public RestHighLevelClient restClient() {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
RestClientBuilder builder = RestClient.builder(new HttpHost(host, port, protocol))
.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider))
.setDefaultHeaders(compatibilityHeaders());
return new RestHighLevelClient(builder);
}
private Header[] compatibilityHeaders() {
return new Header[]{new BasicHeader(HttpHeaders.ACCEPT, "application/vnd.elasticsearch+json;compatible-with=7"), new BasicHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.elasticsearch+json;compatible-with=7")};
}
}

How to test Nothing Happens Until You subscribe()

return Mono.just(key) //
.map(Service1::doSomething) //
.map(Service2:: doSomething) //
.map(Service3::getBytes);
My code is as above, I have many logs in the methods of services (Service1, Service2 and Service3), so I can confirm that those methods are not called, till I call subscribe method by manually verifying the log files. Are there any testing tools which can help me automate that testing?
Mokito can track invocations using mocks/spys. Here's an example using Spring:
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.junit4.SpringRunner;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
#RunWith(SpringRunner.class)
public class ExampleTests {
#SpyBean
private Service1 service1;
#SpyBean
private Service2 service2;
#SpyBean
private Service3 service3;
#Test
public void verifyNothingHappensWithoutSubscribe() {
Mono.just("key")
.map(service1::doSomething)
.map(service2::doSomething)
.map(service3::getBytes);
verify(service1, times(0)).doSomething("key");
verify(service2, times(0)).doSomething("key");
verify(service3, times(0)).getBytes("key");
}
#Test
public void verifyCallsWhenSubscribed() {
Mono<byte[]> testMono = Mono.just("key")
.map(service1::doSomething)
.map(service2::doSomething)
.map(service3::getBytes);
StepVerifier.create(testMono)
.expectNextCount(1)
.verifyComplete();
verify(service1, times(1)).doSomething("key");
verify(service2, times(1)).doSomething("key");
verify(service3, times(1)).getBytes("key");
}
}

Connecting to a remote RabbitMQ server using letsencrypt ssl

I have this configuration to be able to connect to compose.io rabbitmq service
package com.gandalf.configuration;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean;
#Configuration
public class SpringAmqpConfiguration {
#Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses("portal274-33.***,....");
connectionFactory.setUsername("amqpuser");
connectionFactory.setPassword("muggledone");
connectionFactory.setUseSsl(true);
return connectionFactory;
}
#Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
factory.setConcurrentConsumers(3);
//If you want a fixed number of consumers, omit the max.
factory.setMaxConcurrentConsumers(10);
return factory;
}
#Bean
public RabbitTemplate rabbitTemplate() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
return template;
}
}
However, upon running the program, i get an error in this line
connectionFactory.setUseSsl(true);
This is the error i get
Compilation failure
/SpringAmqpConfiguration.java:[24,26] cannot find symbol
[ERROR] symbol: method setUseSsl(boolean)
[ERROR] location: variable connectionFactory of type org.springframework.amqp.rabbit.connection.CachingConnectionFactory
Why is connectionFactory.setUseSsl(true); not being found?.
There is no property useSsl on the CachingConnectionFactory; there is a useSslProtocol property on the underlying com.rabbitmq.client.ConnectionFactory.
Use connectionFactory.getRabbitConnectionFactory().useSslProtocol().

Xtext: Calling the Generator from a Context Menu

Following
https://christiandietrich.wordpress.com/2011/10/15/xtext-calling-the-generator-from-a-context-menu/
and using EclipseResourceFileSystemAccess2 instead of EclipseResourceFileSystemAccess when the line
final EclipseResourceFileSystemAccess2 fsa = fileAccessProvider.get();
give an exception. The only information I have is
// Compiled from InvocationTargetException.java (version 1.8 : 52.0, super bit)
public class java.lang.reflect.InvocationTargetException extends java.lang.ReflectiveOperationException {
I don't know how to get the stack trace in Eclipse.
does the code in the blog still function in the most recent release of Xtext?
Update 1
Snippets from plugin.xml
Handler:
<extension
point="org.eclipse.ui.handlers">
<handler
class="tuks.mcrl2.dsl.ui.handlers.Mcrl22Lps"
commandId="tuks.mcrl2.dsl.ui.commands.mcrl2lps">
</handler>
</extension>
Commands:
<extension
point="org.eclipse.ui.commands">
<command
categoryId="tuks.mcrl2.dsl.ui.category.processalgebra"
defaultHandler="tuks.mcrl2.dsl.ui.handlers.Mcrl22Lps"
description="Conver a mclr2 file to lps"
id="tuks.mcrl2.dsl.ui.commands.mcrl2lps"
name="mcrl22lps">
</command>
<category
id="tuks.mcrl2.dsl.ui.category.processalgebra"
name="Process Algebra">
</category>
</extension>
it basically works, if you do the update from EclipseResourceFileSystemAccess and Stuff and (maybe) IGenerator.
I assume in your case you dont set the Accesses ProgressMonitor and other props.
package org.xtext.example.mydsl.ui.handler;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.xtext.builder.EclipseResourceFileSystemAccess2;
import org.eclipse.xtext.generator.GeneratorContext;
import org.eclipse.xtext.generator.IGenerator2;
import org.eclipse.xtext.resource.IResourceDescriptions;
import org.eclipse.xtext.ui.resource.IResourceSetProvider;
import com.google.inject.Inject;
import com.google.inject.Provider;
public class GenerationHandler extends AbstractHandler implements IHandler {
#Inject
private IGenerator2 generator;
#Inject
private Provider<EclipseResourceFileSystemAccess2> fileAccessProvider;
#Inject
IResourceDescriptions resourceDescriptions;
#Inject
IResourceSetProvider resourceSetProvider;
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
ISelection selection = HandlerUtil.getCurrentSelection(event);
if (selection instanceof IStructuredSelection) {
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
Object firstElement = structuredSelection.getFirstElement();
if (firstElement instanceof IFile) {
IFile file = (IFile) firstElement;
IProject project = file.getProject();
IFolder srcGenFolder = project.getFolder("src-gen");
if (!srcGenFolder.exists()) {
try {
srcGenFolder.create(true, true,
new NullProgressMonitor());
} catch (CoreException e) {
return null;
}
}
final EclipseResourceFileSystemAccess2 fsa = fileAccessProvider.get();
fsa.setProject(project);
fsa.setOutputPath("src-gen");
fsa.setMonitor(new NullProgressMonitor());
URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true);
ResourceSet rs = resourceSetProvider.get(project);
Resource r = rs.getResource(uri, true);
generator.doGenerate(r, fsa, new GeneratorContext());
}
}
return null;
}
#Override
public boolean isEnabled() {
return true;
}
}
and make sure you register the handler properly.
the
class="org.xtext.example.mydsl.ui.MyDslExecutableExtensionFactory:org.xtext.example.mydsl.ui.handler.GenerationHandler"
is crucial, especially that it consists of 2 parts, the ExtensionFactory followed by a : followed by the actual class name

Run JesterRecommenderEvaluationRunner, but get no results of evaluation

I downloaded the Jester example code in Mahout, and tries to run it on jester dataset to see the evaluation results. the running is done successfully, but the console only has the results:
log4j:WARN No appenders could be found for logger (org.apache.mahout.cf.taste.impl.model.file.FileDataModel).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
I expect to see the evaluation score range from 0 to 10. any one can help me found out how to get the score?
I am using mahout-core-0.6.jar and the following is the code:
JesterDataModel.java:
package Jester;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.regex.Pattern;
import com.google.common.collect.Lists;
import org.apache.mahout.cf.taste.example.grouplens.GroupLensDataModel;
import org.apache.mahout.cf.taste.impl.common.FastByIDMap;
import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
import org.apache.mahout.cf.taste.impl.model.GenericPreference;
import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.model.Preference;
import org.apache.mahout.common.iterator.FileLineIterator;
//import org.apache.mahout.cf.taste.impl.common.FileLineIterable;
public final class JesterDataModel extends FileDataModel {
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
private long userBeingRead;
public JesterDataModel() throws IOException {
this(GroupLensDataModel.readResourceToTempFile("\\jester-data-1.csv"));
}
public JesterDataModel(File ratingsFile) throws IOException {
super(ratingsFile);
}
#Override
public void reload() {
userBeingRead = 0;
super.reload();
}
#Override
protected DataModel buildModel() throws IOException {
FastByIDMap<Collection<Preference>> data = new FastByIDMap<Collection<Preference>> ();
FileLineIterator iterator = new FileLineIterator(getDataFile(), false);
FastByIDMap<FastByIDMap<Long>> timestamps = new FastByIDMap<FastByIDMap<Long>>();
processFile(iterator, data, timestamps, false);
return new GenericDataModel(GenericDataModel.toDataMap(data, true));
}
#Override
protected void processLine(String line,
FastByIDMap<?> rawData,
FastByIDMap<FastByIDMap<Long>> timestamps,
boolean fromPriorData) {
FastByIDMap<Collection<Preference>> data = (FastByIDMap<Collection<Preference>>) rawData;
String[] jokePrefs = COMMA_PATTERN.split(line);
int count = Integer.parseInt(jokePrefs[0]);
Collection<Preference> prefs = Lists.newArrayListWithCapacity(count);
for (int itemID = 1; itemID < jokePrefs.length; itemID++) { // yes skip first one, just a count
String jokePref = jokePrefs[itemID];
if (!"99".equals(jokePref)) {
float jokePrefValue = Float.parseFloat(jokePref);
prefs.add(new GenericPreference(userBeingRead, itemID, jokePrefValue));
}
}
data.put(userBeingRead, prefs);
userBeingRead++;
}
}
JesterRecommenderEvaluatorRunner.java
package Jester;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.eval.RecommenderEvaluator;
import org.apache.mahout.cf.taste.impl.eval.AverageAbsoluteDifferenceRecommenderEvaluator;
import org.apache.mahout.cf.taste.model.DataModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public final class JesterRecommenderEvaluatorRunner {
private static final Logger log = LoggerFactory.getLogger(JesterRecommenderEvaluatorRunner.class);
private JesterRecommenderEvaluatorRunner() {
// do nothing
}
public static void main(String... args) throws IOException, TasteException {
RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();
DataModel model = new JesterDataModel();
double evaluation = evaluator.evaluate(new JesterRecommenderBuilder(),
null,
model,
0.9,
1.0);
log.info(String.valueOf(evaluation));
}
}
Mahout 0.7 is old, and 0.6 is very old. Use at least 0.7, or better, later from SVN.
I think the problem is exactly what you identified: you don't have any slf4j bindings in your classpath. If you use the ".job" files in Mahout you will have all dependencies packages. Then you will actually see output.

Resources