I'm following an example to understand how SOAP works. I have generated code from wsdl using Apache cxf and I can log SOAP web service request e response. Apparently all works fine. I have just a problem to set a relative path. I've followed this solution How to avoid the need to specify the WSDL location in a CXF or JAX-WS generated webservice client?, but there isn't way to solve the log error on console.
The error message on console:
jun 03, 2021 2:17:38 PM io.codejournal.maven.wsdl2java.NumberConversion <clinit>
INFO: Can not initialize the default wsdl from classpath:wsdl/dataaccess-numberconversion.wsdl
this is my pom.xml:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-simple</artifactId>
<version>3.1.18</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>3.4.2</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>wsdl2java</goal>
</goals>
<configuration>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/resources/dataaccess-numberconversion.wsdl</wsdl>
<wsdlLocation>classpath:wsdl/dataaccess-numberconversion.wsdl</wsdlLocation>
<packagenames>
<packagename>io.codejournal.maven.wsdl2java</packagename>
</packagenames>
</wsdlOption>
</wsdlOptions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
My service class:
#WebServiceClient(name = "NumberConversion",
wsdlLocation = "classpath:wsdl/dataaccess-numberconversion.wsdl",
targetNamespace = "http://www.dataaccess.com/webservicesserver/")
public class NumberConversion extends Service {
public final static URL WSDL_LOCATION;
public final static QName SERVICE = new QName("http://www.dataaccess.com/webservicesserver/", "NumberConversion");
public final static QName NumberConversionSoap = new QName("http://www.dataaccess.com/webservicesserver/", "NumberConversionSoap");
public final static QName NumberConversionSoap12 = new QName("http://www.dataaccess.com/webservicesserver/", "NumberConversionSoap12");
static {
URL url = NumberConversion.class.getClassLoader().getResource("wsdl/dataaccess-numberconversion.wsdl");
if (url == null) {
java.util.logging.Logger.getLogger(NumberConversion.class.getName())
.log(java.util.logging.Level.INFO,
"Can not initialize the default wsdl from {0}", "classpath:wsdl/dataaccess-numberconversion.wsdl");
}
WSDL_LOCATION = url;
}
public NumberConversion(URL wsdlLocation) {
super(wsdlLocation, SERVICE);
}
public NumberConversion(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public NumberConversion() {
super(WSDL_LOCATION, SERVICE);
}
public NumberConversion(WebServiceFeature ... features) {
super(WSDL_LOCATION, SERVICE, features);
}
public NumberConversion(URL wsdlLocation, WebServiceFeature ... features) {
super(wsdlLocation, SERVICE, features);
}
public NumberConversion(URL wsdlLocation, QName serviceName, WebServiceFeature ... features) {
super(wsdlLocation, serviceName, features);
}
/**
*
* #return
* returns NumberConversionSoapType
*/
#WebEndpoint(name = "NumberConversionSoap")
public NumberConversionSoapType getNumberConversionSoap() {
return super.getPort(NumberConversionSoap, NumberConversionSoapType.class);
}
/**
*
* #param features
* A list of {#link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the <code>features</code> parameter will have their default values.
* #return
* returns NumberConversionSoapType
*/
#WebEndpoint(name = "NumberConversionSoap")
public NumberConversionSoapType getNumberConversionSoap(WebServiceFeature... features) {
return super.getPort(NumberConversionSoap, NumberConversionSoapType.class, features);
}
/**
*
* #return
* returns NumberConversionSoapType
*/
#WebEndpoint(name = "NumberConversionSoap12")
public NumberConversionSoapType getNumberConversionSoap12() {
return super.getPort(NumberConversionSoap12, NumberConversionSoapType.class);
}
/**
*
* #param features
* A list of {#link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the <code>features</code> parameter will have their default values.
* #return
* returns NumberConversionSoapType
*/
#WebEndpoint(name = "NumberConversionSoap12")
public NumberConversionSoapType getNumberConversionSoap12(WebServiceFeature... features) {
return super.getPort(NumberConversionSoap12, NumberConversionSoapType.class, features);
}
}
When I run this code URL url = NumberConversion.class.getClassLoader().getResource("wsdl/dataaccess-numberconversion.wsdl"); ,
I'll get a null value back. It is the wrong path that NumberConversion.class.getClassLoader() calls, because this class is in another package.
Any idea how to set in the right way?
There is a mismatch in your <wsdlOption>, between the <wsdl> and <wsdlLocation> values.
<wsdl>${basedir}/src/main/resources/dataaccess-numberconversion.wsdl</wsdl>
<wsdlLocation>classpath:wsdl/dataaccess-numberconversion.wsdl</wsdlLocation>
The first line says the file is in the root of the classpath but in your second line you say it's on a subpath called wsdl. Both cannot be true.
So change your code to either:
<wsdl>${basedir}/src/main/resources/wsdl/dataaccess-numberconversion.wsdl</wsdl>
<wsdlLocation>classpath:wsdl/dataaccess-numberconversion.wsdl</wsdlLocation>
or to:
<wsdl>${basedir}/src/main/resources/dataaccess-numberconversion.wsdl</wsdl>
<wsdlLocation>classpath:dataaccess-numberconversion.wsdl</wsdlLocation>
What's after /src/main/resources/ and classpath: must match.
Whatever variant you choose make sure that:
the WSDL file is in its proper place inside the /src/main/resources/ folder of your project (directly there or in wsdl subfolder).
that all your code also reflects the correct classpath path (on the root of the classpath or inside a subpackage called wsdl);
that after packaging your JAR file, you decompress it and look inside it to see the WSDL file is at the correct location inside the JAR (either directly on the root or in a a wsdl subfolder).
Related
I can not make XStream working and I do not know why. I am in a Maven projet, JRE-11, MVC model, XStream 1.4.18. I am french btw. Thanks in advance.
I just put an exemple with the UE class, but I want to do this with "Classe" and "Creneau".
I tried "xstream.alias", but did not work.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Archi</groupId>
<artifactId>Archi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.18</version>
</dependency>
</dependencies>
</project>
Archi.java
package controlleur;
import com.thoughtworks.xstream.XStream;
import modele.*;
import vue.*;
public class Archi {
public static void main(String[] args) {
Classe classe = new Classe("IATIC5", 2020, 2021);
UE ue = new UE("ARC", "EU-Archi");
Creneau creneau = new Creneau(9, 11, 2021, 20, 22);
Fenetre fenetre = new Fenetre();
XStream xstream = new XStream();
String xml = xstream.toXML(ue);
System.out.println(xml);
Controlleur controlleur = new Controlleur(classe, ue, creneau, fenetre);
}
}
Controller.java
package controlleur;
import modele.*;
import vue.*;
public class Controlleur {
public Controlleur(Classe classe, UE ue, Creneau creneau, Fenetre fenetre) {
fenetre.affiche(classe, ue, creneau);
}
}
UE.java
package modele;
import java.util.UUID;
public class UE {
private String id = UUID.randomUUID().toString(), sigle, nomination;
public UE(String sigle, String nomination) {
this.sigle = sigle;
this.nomination = nomination;
}
//All getter, setter and toString
}
error text
Exception in thread "main" com.thoughtworks.xstream.converters.ConversionException: No converter available
---- Debugging information ----
message : No converter available
type : modele.UE
converter : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
message[1] : Unable to make field private java.lang.String modele.UE.id accessible: module archi does not "opens modele" to module xstream
-------------------------------
at xstream#1.4.18/com.thoughtworks.xstream.core.DefaultConverterLookup.lookupConverterForType(DefaultConverterLookup.java:88)
at xstream#1.4.18/com.thoughtworks.xstream.XStream$1.lookupConverterForType(XStream.java:472)
at xstream#1.4.18/com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:48)
at xstream#1.4.18/com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
at xstream#1.4.18/com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:82)
at xstream#1.4.18/com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
at xstream#1.4.18/com.thoughtworks.xstream.XStream.marshal(XStream.java:1243)
at xstream#1.4.18/com.thoughtworks.xstream.XStream.marshal(XStream.java:1232)
at xstream#1.4.18/com.thoughtworks.xstream.XStream.toXML(XStream.java:1205)
at xstream#1.4.18/com.thoughtworks.xstream.XStream.toXML(XStream.java:1192)
at archi/controlleur.Archi.main(Archi.java:17)
I had the same issue and I found out what was wrong in my project.
I was developing a JavaFX with data persistence in XML with XStream. When attempting to read the file, I had the same issue.
In order to fix it, I did the following:
Save the models/javabeans on a directory.
MODULE/javabeans/
PeopleXML.java
PersonXML.java
Modify the module to allow XStream to use these classes (module-info.java)
module MODULE {
...
requires xstream;
...
opens MODULE.javabeans to xstream;
exports MODULE.javabeans;
}
Implement the code normally.
XStream xstream = new XStream();
xstream.addPermission(NoTypePermission.NONE);
xstream.addPermission(NullPermission.NULL);
xstream.addPermission(PrimitiveTypePermission.PRIMITIVES);
xstream.allowTypes(new Class[]{PersonXML.class, PeopleXML.class});
xstream.allowTypesByWildcard(new String[] {
"MODULE.javabeans.**"
});
xstream.alias("people", PeopleXML.class);
xstream.alias("person", PersonXML.class);
xstream.addImplicitCollection(PeopleXML.class, "lstPeople"); // Collection name
try {
FileInputStream fis = new FileInputStream(xmlFilename);
return (PeopleXML) xstream.fromXML(fis);
}
catch (FileNotFoundException e) {
throw new InvalidDataException("File not found: " + xmlFilename);
}
Note: MODULE is the module you are working on.
I am struggling to understand why code-generated soap request on the left is not working, but if I tweak it to what's on the right, then it works?
Now that I know what needs to be done to make it work, how do I fix it ?
I added jaxws-maven-plugin to my java project:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.5</version>
<configuration>
<sourceDestDir>src/main/java</sourceDestDir>
<wsdlDirectory>src/main/resources/wsdl</wsdlDirectory>
<wsdlFiles>
<wsdlFile>Flattened_Integrator7.0.wsdl</wsdlFile>
</wsdlFiles>
<keep>true</keep>
</configuration>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Notice in the picture above without prefix wsse, it doesn't work.
It has to be that word. And it exists in wsdl file.
Does anyone know how:
I can force namespace prefix for "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" to be wsse
Force code to generate namespaces in soap envelope and not in Security section
So, I had to manually add prefix/namespace to envelope and rename all children's prefixes to wsse.
Here is how I did it:
#Component
public class RequestClient {
private static final String WSSE_PREFIX = "wsse";
private static final String WSSE_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
private static final String NS2_PREFIX = "ns2";
private static final String NS2_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
private buildSoaprequest(){
...
SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope();
soapEnvelope.addNamespaceDeclaration(WSSE_PREFIX, WSSE_NAMESPACE);
soapEnvelope.addNamespaceDeclaration(NS2_PREFIX, NS2_NAMESPACE);
SOAPHeader soapHeader = soapMessage.getSOAPHeader();
removeUndesiredBodyNamespaceEntries(soapHeader.getChildElements());
soapHeader.setPrefix(WSSE_PREFIX);
addDesiredBodyNamespaceEntries(soapHeader.getChildElements());
soapMessage.saveChanges();
...
}
private void addDesiredBodyNamespaceEntries(Iterator childElements) {
while (childElements.hasNext()) {
final Object childElementNode = childElements.next();
if (childElementNode instanceof SOAPElement) {
SOAPElement soapElement = (SOAPElement) childElementNode;
soapElement.setPrefix(WSSE_PREFIX);
addDesiredBodyNamespaceEntries(soapElement.getChildElements());
}
}
}
private void removeUndesiredBodyNamespaceEntries(Iterator childElements) {
while (childElements.hasNext()) {
final Object childElementNode = childElements.next();
if (childElementNode instanceof SOAPElement) {
SOAPElement soapElement = (SOAPElement) childElementNode;
//remove any prefix/namespace entries added by JAX-WS in the body element
//it cannot be null, so it will leave wsse
for (String prefix : getNamespacePrefixList(soapElement.getNamespacePrefixes())) {
if (prefix != null) {
soapElement.removeNamespaceDeclaration(prefix);
}
}
// recursively remove prefix/namespace entries in child elements
removeUndesiredBodyNamespaceEntries(soapElement.getChildElements());
}
}
}
private Set<String> getNamespacePrefixList(Iterator namespacePrefixIter) {
Set<String> namespacePrefixesSet = new HashSet<>();
while (namespacePrefixIter.hasNext()) {
namespacePrefixesSet.add((String) namespacePrefixIter.next());
}
return namespacePrefixesSet;
}
I am working on a java project that runs in Azure Functions. The problem is that I can't make the Java CDI 2.0 work in the application.
Please refer to the application codes below.
Function.java
public class Function {
#Inject
private Util util;
/**
* This function listens at endpoint "/api/HttpTrigger-Java". Two ways to invoke it using "curl" command in bash:
* 1. curl -d "HTTP Body" {your host}/api/HttpTrigger-Java&code={your function key}
* 2. curl "{your host}/api/HttpTrigger-Java?name=HTTP%20Query&code={your function key}"
* Function Key is not needed when running locally, to invoke HttpTrigger deployed to Azure, see here(https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook#authorization-keys) on how to get function key for your app.
*/
#FunctionName("HttpTrigger-Java")
public HttpResponseMessage run(
#HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION) HttpRequestMessage<Optional<String>> request,
final ExecutionContext context) {
context.getLogger().info("Java HTTP trigger processed a request.");
// Parse query parameter
String query = request.getQueryParameters().get("name");
String name = request.getBody().orElse(query);
util.display();
if (name == null) {
return request.createResponseBuilder(HttpStatus.BAD_REQUEST).body("Please pass a name on the query string or in the request body").build();
} else {
return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
}
}
}
Util.java
#RequestScoped
public class Util {
public void display(){
System.out.println("testing..");
}
}
I have this in my pom.xml
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
when I deploy this and hit the endpoint, I am getting an nullpointerexception when accessing the method from the injected bean..
Can someone enlighten me regarding this matter?
The idea behind what i'm doing is exposing hyperledger fabric blockchain using Spring REST APIs.
When i build my code (withourt REST) and call it using the java command, it works fine and returns the data from Hyperledger fabric.
However, when i try to implement it in the REST controller, i find myself blocked.
Below is my code for the Rest Controller :
#RestController
public class RestWebController {
private static final Logger log = Logger.getLogger(RestWebController.class);
#RequestMapping(value = "/getall", method = RequestMethod.GET)
public void getAll(){
try {
HFCAClient caClient = getHfCaClient("http://localhost:7054", null);
// enroll or load admin
AppUser admin = getAdmin(caClient);
log.info(admin);
// register and enroll new user
AppUser appUser = getUser(caClient, admin, "hfuser");
log.info(appUser);
// get HFC client instance
HFClient client = getHfClient();
// set user context
client.setUserContext(admin);
// get HFC channel using the client
Channel channel = getChannel(client);
log.info("Channel: " + channel.getName());
// call query blockchain example
queryBlockChain(client);
}
catch (Exception e) {
e.printStackTrace();
}
}
/**
* Invoke blockchain query
*
* #param client The HF Client
* #throws ProposalException
* #throws InvalidArgumentException
*/
static void queryBlockChain(HFClient client) throws ProposalException, InvalidArgumentException {
// get channel instance from client
Channel channel = client.getChannel("mychannel");
// create chaincode request
QueryByChaincodeRequest qpr = client.newQueryProposalRequest();
// build cc id providing the chaincode name. Version is omitted here.
ChaincodeID fabcarCCId = ChaincodeID.newBuilder().setName("poc-app").build();
qpr.setChaincodeID(fabcarCCId);
// CC function to be called
qpr.setFcn("queryAllTransactions");
Collection<ProposalResponse> res = channel.queryByChaincode(qpr);
// display response
for (ProposalResponse pres : res) {
String stringResponse = new String(pres.getChaincodeActionResponsePayload());
log.info(stringResponse);
}
}
/**
* Initialize and get HF channel
*
* #param client The HFC client
* #return Initialized channel
* #throws InvalidArgumentException
* #throws TransactionException
*/
static Channel getChannel(HFClient client) throws InvalidArgumentException, TransactionException {
// initialize channel
// peer name and endpoint in fabcar network
Peer peer = client.newPeer("peer0.org1.example.com", "grpc://localhost:7051");
// eventhub name and endpoint in fabcar network
EventHub eventHub = client.newEventHub("eventhub01", "grpc://localhost:7053");
// orderer name and endpoint in fabcar network
Orderer orderer = client.newOrderer("orderer.example.com", "grpc://localhost:7050");
// channel name in fabcar network
Channel channel = client.newChannel("mychannel");
channel.addPeer(peer);
channel.addEventHub(eventHub);
channel.addOrderer(orderer);
channel.initialize();
return channel;
}
/**
* Create new HLF client
*
* #return new HLF client instance. Never null.
* #throws CryptoException
* #throws InvalidArgumentException
*/
static HFClient getHfClient() throws Exception {
// initialize default cryptosuite
CryptoSuite cryptoSuite = CryptoSuite.Factory.getCryptoSuite();
// setup the client
HFClient client = HFClient.createNewInstance();
client.setCryptoSuite(cryptoSuite);
return client;
}
/**
* Register and enroll user with userId.
* If AppUser object with the name already exist on fs it will be loaded and
* registration and enrollment will be skipped.
*
* #param caClient The fabric-ca client.
* #param registrar The registrar to be used.
* #param userId The user id.
* #return AppUser instance with userId, affiliation,mspId and enrollment set.
* #throws Exception
*/
static AppUser getUser(HFCAClient caClient, AppUser registrar, String userId) throws Exception {
AppUser appUser = tryDeserialize(userId);
if (appUser == null) {
RegistrationRequest rr = new RegistrationRequest(userId, "org1");
String enrollmentSecret = caClient.register(rr, registrar);
Enrollment enrollment = caClient.enroll(userId, enrollmentSecret);
appUser = new AppUser(userId, "org1", "Org1MSP", enrollment);
serialize(appUser);
}
return appUser;
}
/**
* Enroll admin into fabric-ca using {#code admin/adminpw} credentials.
* If AppUser object already exist serialized on fs it will be loaded and
* new enrollment will not be executed.
*
* #param caClient The fabric-ca client
* #return AppUser instance with userid, affiliation, mspId and enrollment set
* #throws Exception
*/
static AppUser getAdmin(HFCAClient caClient) throws Exception {
AppUser admin = tryDeserialize("admin");
if (admin == null) {
Enrollment adminEnrollment = caClient.enroll("admin", "adminpw");
admin = new AppUser("admin", "org1", "Org1MSP", adminEnrollment);
serialize(admin);
}
return admin;
}
/**
* Get new fabic-ca client
*
* #param caUrl The fabric-ca-server endpoint url
* #param caClientProperties The fabri-ca client properties. Can be null.
* #return new client instance. never null.
* #throws Exception
*/
static HFCAClient getHfCaClient(String caUrl, Properties caClientProperties) throws Exception {
CryptoSuite cryptoSuite = CryptoSuite.Factory.getCryptoSuite();
HFCAClient caClient = HFCAClient.createNewInstance(caUrl, caClientProperties);
caClient.setCryptoSuite(cryptoSuite);
return caClient;
}
// user serialization and deserialization utility functions
// files are stored in the base directory
/**
* Serialize AppUser object to file
*
* #param appUser The object to be serialized
* #throws IOException
*/
static void serialize(AppUser appUser) throws IOException {
try (ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(
Paths.get(appUser.getName() + ".jso")))) {
oos.writeObject(appUser);
}
}
/**
* Deserialize AppUser object from file
*
* #param name The name of the user. Used to build file name ${name}.jso
* #return
* #throws Exception
*/
static AppUser tryDeserialize(String name) throws Exception {
if (Files.exists(Paths.get(name + ".jso"))) {
return deserialize(name);
}
return null;
}
static AppUser deserialize(String name) throws Exception {
try (ObjectInputStream decoder = new ObjectInputStream(
Files.newInputStream(Paths.get(name + ".jso")))) {
return (AppUser) decoder.readObject();
}
}
I run spring boot using mvn spring-boot:run, the server starts normally. this is my pom.xml :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hyperledger.fabric-sdk-java</groupId>
<artifactId>fabric-sdk-java</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
After calling the server on localhost:8080/getall , i get this error :
2018-07-13 14:56:33.439 WARN 24669 --- [ault-executor-0] io.grpc.internal.ChannelExecutor : Runnable threw exception in ChannelExecutor
java.lang.NoClassDefFoundError: io/netty/handler/codec/http2/internal/hpack/Decoder
at io.grpc.netty.GrpcHttp2HeadersDecoder.<init>(GrpcHttp2HeadersDecoder.java:85) ~[grpc-netty-1.3.0.jar:1.3.0]
at io.grpc.netty.GrpcHttp2HeadersDecoder$GrpcHttp2ClientHeadersDecoder.<init>(GrpcHttp2HeadersDecoder.java:147) ~[grpc-netty-1.3.0.jar:1.3.0]
at io.grpc.netty.NettyClientHandler.newHandler(NettyClientHandler.java:119) ~[grpc-netty-1.3.0.jar:1.3.0]
at io.grpc.netty.NettyClientTransport.start(NettyClientTransport.java:190) ~[grpc-netty-1.3.0.jar:1.3.0]
at io.grpc.internal.ForwardingConnectionClientTransport.start(ForwardingConnectionClientTransport.java:44) ~[grpc-core-1.3.0.jar:1.3.0]
at io.grpc.internal.InternalSubchannel.startNewTransport(InternalSubchannel.java:216) ~[grpc-core-1.3.0.jar:1.3.0]
at io.grpc.internal.InternalSubchannel.obtainActiveTransport(InternalSubchannel.java:186) ~[grpc-core-1.3.0.jar:1.3.0]
at io.grpc.internal.ManagedChannelImpl$SubchannelImplImpl.obtainActiveTransport(ManagedChannelImpl.java:812) ~[grpc-core-1.3.0.jar:1.3.0]
at io.grpc.internal.GrpcUtil.getTransportFromPickResult(GrpcUtil.java:592) ~[grpc-core-1.3.0.jar:1.3.0]
at io.grpc.internal.DelayedClientTransport.reprocess(DelayedClientTransport.java:295) ~[grpc-core-1.3.0.jar:1.3.0]
at io.grpc.internal.ManagedChannelImpl$LbHelperImpl$5.run(ManagedChannelImpl.java:718) ~[grpc-core-1.3.0.jar:1.3.0]
at io.grpc.internal.ChannelExecutor.drain(ChannelExecutor.java:87) ~[grpc-core-1.3.0.jar:1.3.0]
at io.grpc.internal.ManagedChannelImpl$LbHelperImpl.runSerialized(ManagedChannelImpl.java:709) [grpc-core-1.3.0.jar:1.3.0]
at io.grpc.internal.ManagedChannelImpl$NameResolverListenerImpl.onAddresses(ManagedChannelImpl.java:758) [grpc-core-1.3.0.jar:1.3.0]
at io.grpc.internal.DnsNameResolver$1.run(DnsNameResolver.java:175) [grpc-core-1.3.0.jar:1.3.0]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_171]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_171]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_171]
Caused by: java.lang.ClassNotFoundException: io.netty.handler.codec.http2.internal.hpack.Decoder
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_171]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_171]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_171]
... 18 common frames omitted
2018-07-13 14:56:35.321 ERROR 24669 --- [nio-8080-exec-2] o.hyperledger.fabric.sdk.OrdererClient : sendDeliver time exceeded for orderer
org.hyperledger.fabric.sdk.exception.TransactionException: sendDeliver time exceeded for orderer
at org.hyperledger.fabric.sdk.OrdererClient.sendDeliver(OrdererClient.java:274) ~[fabric-sdk-java-1.0.0.jar:na]
at org.hyperledger.fabric.sdk.Orderer.sendDeliver(Orderer.java:165) [fabric-sdk-java-1.0.0.jar:na]
at org.hyperledger.fabric.sdk.Channel.getLatestBlock(Channel.java:1074) [fabric-sdk-java-1.0.0.jar:na]
at org.hyperledger.fabric.sdk.Channel.getConfigurationBlock(Channel.java:898) [fabric-sdk-java-1.0.0.jar:na]
at org.hyperledger.fabric.sdk.Channel.parseConfigBlock(Channel.java:826) [fabric-sdk-java-1.0.0.jar:na]
at org.hyperledger.fabric.sdk.Channel.initialize(Channel.java:526) [fabric-sdk-java-1.0.0.jar:na]
at com.example.demo.controller.RestWebController.getChannel(RestWebController.java:144) [classes/:na]
at com.example.demo.controller.RestWebController.getAll(RestWebController.java:84) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_171]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_171]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) [spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) [spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) [tomcat-embed-core-8.5.31.jar:8.5.31]
NOTE: The network is working fine, by calling the .jar independently, and even running the hyperledger fabric nodeJS sdk.
NoClassDefFoundError means the is a version conflict. gRPC was compiled to use a method that isn't existing at runtime.
Using mvn dependency:tree I see that Netty version 4.1.25.Final is being used. But looking at fabric-sdk-java 1.0.0, it is using grpc-netty 1.3.0 and Netty 4.1.8.Final. spring-boot-starter-parent is pulling in spring-boot-dependencies which is selecting Netty 4.1.25.Final.
I suggest upgrading to fabric-sdk-java 1.1.0 which uses grpc-netty 1.11.0 and Netty 4.1.23.Final. Then override spring-boot-dependencies to use Netty 4.1.23.Final by setting the netty.version property:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<netty.version>4.1.23.Final</netty.version> <!-- add this line -->
</properties>
I also encountered this problem, thanks to the answer Eric Anderson, I solved the problem.
It's completely correct that NoClassDefFoundError means a version conflict.
My version: fabric-sdk-java 1.0.0 , Spring Boot 2.2.6.RELEASE.
The netty version of fabric-sdk-java 1.0.0 is 4.1.8.Final,but netty version of Spring Boot 2.2.6.RELEASE parent is 4.1.48.Final,if you do nothing,fabric-sdk-java can use 4.1.48.Final,so it produces an error.
This is my solution:
<properties>
<java.version>1.8</java.version>
<netty.version>4.1.8.Final</netty.version>
</properties>
Null Pointer Exception in YouTube Analytics API Using Java IntelliJ IDEA ?
Could Please Give an any Suggestion ?
Throwable: null
java.lang.NullPointerException
at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkNotNull(Preconditions.java:191)
at com.google.api.client.util.Preconditions.checkNotNull(Preconditions.java:127)
at com.google.api.client.json.jackson2.JacksonFactory.createJsonParser(JacksonFactory.java:96)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:85)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:81)
at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:88)
at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287)
at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:307)
at com.google.api.client.auth.oauth2.Credential.executeRefreshToken(Credential.java:570)
at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489)
at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:217)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:859)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
at com.google.api.services.samples.youtube.cmdline.analytics.YouTubeAnalyticsReports.main(YouTubeAnalyticsReports.java:87)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
This is Pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.api.services.samples.youtube.cmdline</groupId>
<artifactId>samples</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>youtube-api-cmdline-samples</name>
<url>http://maven.apache.org</url>
<properties>
<project.youtube.version>v3-rev107-1.18.0-rc</project.youtube.version>
<project.youtube.analytics.version>v1-rev24-1.17.0-rc</project.youtube.analytics.version>
<project.http.version>1.18.0-rc</project.http.version>
<project.oauth.version>1.18.0-rc</project.oauth.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>google-api-services</id>
<url>http://google-api-client-libraries.appspot.com/mavenrepo</url>
</repository>
</repositories>
<dependencies>
<!-- YouTube Data V3 support -->
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-youtube</artifactId>
<version>${project.youtube.version}</version>
</dependency>
<!-- Required for any code that makes calls to the Google Analytics API -->
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-youtubeAnalytics</artifactId>
<version>${project.youtube.analytics.version}</version>
</dependency>
<!-- This dependency is only used for the Topics API sample, which requires the Jackson JSON parser -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-jackson2</artifactId>
<version>${project.http.version}</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-jetty</artifactId>
<version>${project.oauth.version}</version>
</dependency>
<dependency>
<groupId>com.google.collections</groupId>
<artifactId>google-collections</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Forces Maven to use Java 1.6 -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument></compilerArgument>
</configuration>
</plugin>
</plugins>
</build>
i need Report Generation for You Tube Videos using YouTube Analytics API in Java IntelliJ IDEA?
How to Fix the Exception could u please any one help u it Will helpful for me.
Report.java
package com.google.api.services.samples.youtube.cmdline.analytics;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.samples.youtube.cmdline.Auth;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.Channel;
import com.google.api.services.youtube.model.ChannelListResponse;
import com.google.api.services.youtubeAnalytics.YouTubeAnalytics;
import com.google.api.services.youtubeAnalytics.model.ResultTable;
import com.google.api.services.youtubeAnalytics.model.ResultTable.ColumnHeaders;
import com.google.common.collect.Lists;
import java.io.IOException;
import java.io.PrintStream;
import java.math.BigDecimal;
import java.util.List;
public class YouTubeAnalyticsReports {
/**
* Define a global instance of the HTTP transport.
*/
private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
/**
* Define a global instance of the JSON factory.
*/
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
/**
* Define a global instance of a Youtube object, which will be used
* to make YouTube Data API requests.
*/
private static YouTube youtube;
/**
* Define a global instance of a YoutubeAnalytics object, which will be
* used to make YouTube Analytics API requests.
*/
private static YouTubeAnalytics analytics;
/**
* This code authorizes the user, uses the YouTube Data API to retrieve
* information about the user's YouTube channel, and then fetches and
* prints statistics for the user's channel using the YouTube Analytics API.
*
* #param args command line args (not used).
*/
public static void main(String[] args) {
// These scopes are required to access information about the
// authenticated user's YouTube channel as well as Analytics
// data for that channel.
List<String> scopes = Lists.newArrayList(
"https://www.googleapis.com/auth/yt-analytics.readonly",
"https://www.googleapis.com/auth/youtube.readonly"
);
try {
// Authorize the request.
Credential credential = Auth.authorize(scopes, "analyticsreports");
// This object is used to make YouTube Data API requests.
youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName("youtube-analytics-api-report-example")
.build();
// This object is used to make YouTube Analytics API requests.
analytics = new YouTubeAnalytics.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName("youtube-analytics-api-report-example")
.build();
// Construct a request to retrieve the current user's channel ID.
YouTube.Channels.List channelRequest = youtube.channels().list("id,snippet");
channelRequest.setMine(true);
channelRequest.setFields("items(id,snippet/title)");
ChannelListResponse channels = channelRequest.execute();
// List channels associated with the user.
List<Channel> listOfChannels = channels.getItems();
// The user's default channel is the first item in the list.
Channel defaultChannel = listOfChannels.get(0);
String channelId = defaultChannel.getId();
PrintStream writer = System.out;
if (channelId == null) {
writer.println("No channel found.");
} else {
writer.println("Default Channel: " + defaultChannel.getSnippet().getTitle() +
" ( " + channelId + " )\n");
printData(writer, "Views Over Time.", executeViewsOverTimeQuery(analytics, channelId));
printData(writer, "Top Videos", executeTopVideosQuery(analytics, channelId));
printData(writer, "Demographics", executeDemographicsQuery(analytics, channelId));
}
} catch (IOException e) {
System.err.println("IOException: " + e.getMessage());
e.printStackTrace();
} catch (Throwable t) {
System.err.println("Throwable: " + t.getMessage());
t.printStackTrace();
}
}
/**
* Retrieve the views and unique viewers per day for the channel.
*
* #param analytics The service object used to access the Analytics API.
* #param id The channel ID from which to retrieve data.
* #return The API response.
* #throws IOException if an API error occurred.
*/
private static ResultTable executeViewsOverTimeQuery(YouTubeAnalytics analytics,
String id) throws IOException {
return analytics.reports()
.query("channel==" + id, // channel id
"2012-01-01", // Start date.
"2012-01-14", // End date.
"views,uniques") // Metrics.
.setDimensions("day")
.setSort("day")
.execute();
}
/**
* Retrieve the channel's 10 most viewed videos in descending order.
*
* #param analytics the analytics service object used to access the API.
* #param id the string id from which to retrieve data.
* #return the response from the API.
* #throws IOException if an API error occurred.
*/
private static ResultTable executeTopVideosQuery(YouTubeAnalytics analytics,
String id) throws IOException {
return analytics.reports()
.query("channel==" + id, // channel id
"2012-01-01", // Start date.
"2012-08-14", // End date.
"views,subscribersGained,subscribersLost") // Metrics.
.setDimensions("video")
.setSort("-views")
.setMaxResults(10)
.execute();
}
/**
* Retrieve the demographics report for the channel.
*
* #param analytics the analytics service object used to access the API.
* #param id the string id from which to retrieve data.
* #return the response from the API.
* #throws IOException if an API error occurred.
*/
private static ResultTable executeDemographicsQuery(YouTubeAnalytics analytics,
String id) throws IOException {
return analytics.reports()
.query("channel==" + id, // channel id
"2007-01-01", // Start date.
"2012-08-14", // End date.
"viewerPercentage") // Metrics.
.setDimensions("ageGroup,gender")
.setSort("-viewerPercentage")
.execute();
}
/**
* Prints the API response. The channel name is printed along with
* each column name and all the data in the rows.
*
* #param writer stream to output to
* #param title title of the report
* #param results data returned from the API.
*/
private static void printData(PrintStream writer, String title, ResultTable results) {
writer.println("Report: " + title);
if (results.getRows() == null || results.getRows().isEmpty()) {
writer.println("No results Found.");
} else {
// Print column headers.
for (ColumnHeaders header : results.getColumnHeaders()) {
writer.printf("%30s", header.getName());
}
writer.println();
// Print actual data.
for (List<Object> row : results.getRows()) {
for (int colNum = 0; colNum < results.getColumnHeaders().size(); colNum++) {
ColumnHeaders header = results.getColumnHeaders().get(colNum);
Object column = row.get(colNum);
if ("INTEGER".equals(header.getUnknownKeys().get("dataType"))) {
long l = ((BigDecimal) column).longValue();
writer.printf("%30d", l);
} else if ("FLOAT".equals(header.getUnknownKeys().get("dataType"))) {
writer.printf("%30f", column);
} else if ("STRING".equals(header.getUnknownKeys().get("dataType"))) {
writer.printf("%30s", column);
} else {
// default output.
writer.printf("%30s", column);
}
}
writer.println();
}
writer.println();
}
}
<repositories>
<repository>
<id>google-api-services</id>
<url>http://mavenrepo.google-api-java-client.googlecode.com/hg</url>
</repository>
<repository>
<id>google-api-services</id>
<url>http://google-api-client-libraries.appspot.com/mavenrepo</url>
</repository>
</repositories>
You have defined two repositories with the same ID, delete one of them or change its ID.