I am having a bizarre problem with my JerseyTest class.
When executing my test code and putting a break point on line 203 of org.glassfish.jersey.message.internal.ReaderInterceptorExecutor, I see that my reader is not in reader.workers. However, as you can see below, I register this MessageBodyReader in the ResourceConfig.
All relevant code is provided below.
My custom MessageBodyReader/Writer
#Provider
#Produces({V1_JSON})
#Consumes({V1_JSON})
public class JsonMessageBodyHandlerV1
implements
MessageBodyWriter<Object>,
MessageBodyReader<Object> {
...
}
And yes, isReadable returns true.
When debugging, I see that the code hits writeTo but not readFrom.
Test code that fails
public class TestLocationResource extends JerseyTest {
public static class LocationResourceHK2Binder extends AbstractBinder {
#Override
protected void configure() {
// Singleton bindings.
bindAsContract(LocationDao.class).in(Singleton.class);
// Singleton instance bindings.
bind(new FakeLocationDao()).to(LocationDao.class);
}
}
#Test
public void basicTest() {
LocationListV1 actualResponse = /**/
/**/target(LocationResourceV1.PathFields.PATH_ROOT)
/* */.path(LocationResourceV1.PathFields.SUBPATH_LIST)
/* */.request(V1_JSON)
/* */.header(HEADER_API_KEY, "abcdefg")
/* */.get(LocationListV1.class);
assertEquals(10, actualResponse.getLocations().size());
}
#Override
protected Application configure() {
enable(TestProperties.LOG_TRAFFIC);
enable(TestProperties.DUMP_ENTITY);
ResourceConfig rc = new ResourceConfig();
rc.registerClasses(LocationResourceV1.class, JsonMessageBodyHandlerV1.class);
rc.register(new LocationResourceHK2Binder());
return rc;
}
}
(Pulling from this example.)
The resource it's testing...
public class LocationResourceV1 implements ILocationResourceV1 {
...
#Inject
private LocationDao daoLoc;
private final LocationTranslator translator = new LocationTranslator();
#Override
public LocationListV1 listV1(String apiKey) {
return translator.translate(daoLoc.query(LocationFilters.SELECT_ALL));
}
...
#VisibleForTesting
public void setLocationDao(LocationDao dao) {
this.daoLoc = dao;
}
}
(Note that the web service annotations such as #GET are in the interface.)
Generates this fail trace
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException:
MessageBodyReader not found for media
type=application/vnd.com.company-v1+json, type=class
com.company.rest.v1.resources.location.json.LocationListV1,
genericType=class
com.company.rest.v1.resources.location.json.LocationListV1.
at
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:207)
at
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:139)
at
org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1109)
at
org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:851)
at
org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:785)
at
org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:96)
at
org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:761)
at
org.glassfish.jersey.client.JerseyInvocation.access$500(JerseyInvocation.java:90)
at
org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:671)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315) at
org.glassfish.jersey.internal.Errors.process(Errors.java:297) at
org.glassfish.jersey.internal.Errors.process(Errors.java:228) at
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:422)
at
org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:667)
at
org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:396)
at
org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:296)
at
com.company.rest.resources.location.TestLocationResource.basicTest(TestLocationResource.java:47)
[...]
... with this console output
[...]
INFO: [HttpServer] Started.
Oct 29, 2013 4:26:16 PM org.glassfish.jersey.filter.LoggingFilter log
INFO: 1 * LoggingFilter - Request received on thread main
1 > GET http://localhost:9998/location/list
1 > Accept: application/vnd.com.company-v1+json
1 > X-ApiKey: abcdefg
Oct 29, 2013 3:30:21 PM org.glassfish.jersey.internal.Errors logErrors
WARNING: The following warnings have been detected: WARNING: HK2 service reification failed for [com.company.persistence.dao.intf.LocationDao] with an exception:
MultiException stack 1 of 2
java.lang.NoSuchMethodException: Could not find a suitable constructor in com.company.persistence.dao.intf.LocationDao class.
at org.glassfish.jersey.internal.inject.JerseyClassAnalyzer.getConstructor(JerseyClassAnalyzer.java:189)
at org.jvnet.hk2.internal.Utilities.getConstructor(Utilities.java:159)
at org.jvnet.hk2.internal.ClazzCreator.initialize(ClazzCreator.java:125)
at org.jvnet.hk2.internal.ClazzCreator.initialize(ClazzCreator.java:176)
at org.jvnet.hk2.internal.SystemDescriptor.internalReify(SystemDescriptor.java:649)
at org.jvnet.hk2.internal.SystemDescriptor.reify(SystemDescriptor.java:604)
at org.jvnet.hk2.internal.ServiceLocatorImpl.reifyDescriptor(ServiceLocatorImpl.java:396)
[...]
MultiException stack 2 of 2
java.lang.IllegalArgumentException: Errors were discovered while reifying SystemDescriptor(
implementation=com.company.persistence.dao.intf.LocationDao
contracts={com.company.persistence.dao.intf.LocationDao}
scope=org.glassfish.jersey.process.internal.RequestScoped
qualifiers={}
descriptorType=CLASS
descriptorVisibility=NORMAL
metadata=
rank=0
loader=org.glassfish.hk2.utilities.binding.AbstractBinder$2#568bf3ec
proxiable=null
proxyForSameScope=null
analysisName=null
id=143
locatorId=0
identityHashCode=2117810007
reified=false)
at org.jvnet.hk2.internal.SystemDescriptor.reify(SystemDescriptor.java:615)
at org.jvnet.hk2.internal.ServiceLocatorImpl.reifyDescriptor(ServiceLocatorImpl.java:396)
at org.jvnet.hk2.internal.ServiceLocatorImpl.narrow(ServiceLocatorImpl.java:1916)
at org.jvnet.hk2.internal.ServiceLocatorImpl.access$700(ServiceLocatorImpl.java:113)
at org.jvnet.hk2.internal.ServiceLocatorImpl$6.compute(ServiceLocatorImpl.java:993)
at org.jvnet.hk2.internal.ServiceLocatorImpl$6.compute(ServiceLocatorImpl.java:988)
[...]
[...]
(Above is repeated 4 times)
[...]
[...]
Followed by this, implying that there was a successful response
Oct 29, 2013 3:30:22 PM org.glassfish.jersey.filter.LoggingFilter log
INFO: 2 * LoggingFilter - Response received on thread main
2 < 200
2 < Date: Tue, 29 Oct 2013 22:30:21 GMT
2 < Content-Length: 16
2 < Content-Type: application/vnd.com.company-v1+json
{"locations":[]}
Oct 29, 2013 3:30:22 PM org.glassfish.jersey.test.grizzly.GrizzlyTestContainerFactory$GrizzlyTestContainer stop
INFO: Stopping GrizzlyTestContainer...
Oct 29, 2013 3:30:22 PM org.glassfish.grizzly.http.server.NetworkListener stop
INFO: Stopped listener bound to [localhost:9998]
Anybody have any idea what I am doing wrong?
The first stack-trace comes from your client because you didn't register your message-body provider there (and hence it cannot be found). JerseyTest#configure method is supposed to be used to configure only the server-side. There is another method called JerseyTest#configureClient intended to be used on the client-side. You need to override both methods if you want to use a custom provider.
The second stack-trace comes from your LocationResourceHK2Binder. By
bindAsContract(LocationDao.class).in(Singleton.class);
you're telling HK2 that LocationDao class should be instantiated as a singleton and HK2 would then inject it to LocationDao types. You may want to change your binder to use something like:
bind(new FakeLocationDao()).to(LocationDao.class);
For more information on this topic, refer to Custom Injection and Lifecycle Management.
Related
I'd like to use Log4j2 and am setting up my MainVerticle with system properties to do that,
public class MainVerticle extends AbstractVerticle
{
static {
System.setProperty( "vertx.logger-delegate-factory-class-name",
"io.vertx.core.logging.Log4j2LogDelegateFactory" );
System.setProperty( "log4j2.debug", "true" );
}
....
}
I then deploy my HttpVerticle from this verticle, and in the HTTP verticle, I'm trying to use parameterized statements, which aren't working. So I added a couple of logging statements to show the logger delegate in-use, as well as the system property:
public class HttpServerVerticle extends AbstractVerticle
{
private static final Logger LOGGER = LoggerFactory.getLogger( HttpServerVerticle.class );
#Override
public void start() throws Exception
{
LOGGER.info( System.getProperty( "vertx.logger-delegate-factory-class-name" ) );
LOGGER.info( LOGGER.getDelegate().getClass().getName() );
....
And below in a handler of the incoming message, I'm using this:
LOGGER.info( "Chat message received: {}" + message.body(), message.body() );
Note that I'm adding the message.body() using concatenation to prove that the message is not an empty string.
The output of these log statements are:
[INFO] Sep 24, 2018 2:46:09 AM ca.LinkEdTutoring.chat.http.HttpServerVerticle
[INFO] INFO: io.vertx.core.logging.Log4j2LogDelegateFactory
[INFO] Sep 24, 2018 2:46:09 AM ca.LinkEdTutoring.chat.http.HttpServerVerticle
[INFO] INFO: io.vertx.core.logging.JULLogDelegate
and for an incoming message of the letter "b":
[INFO] INFO: Chat message received: {}b
I've tried setting the system properties in the pom.xml file and on the command line with -D arguments.
This is with vert.x 3.5.3
Any thoughts on what I've forgotten to do?
================
EDIT: capturing the salient points from the comment thread.
cannot set system properties in a verticle, because the vert.x JUL logger gets initiated before the main verticle.
cannot set ... in the pom.xml when running the code with the vertx plugin. The mvn vertx plugin must get invoked after vertx is initialized.
only way it seems possible to override the JUL logger is the command line, using -D vargs.
do not forget that vargs are set before the -jar switch, i.e., $ java -Dx=y -jar jarname.jar
If you use the command line to start, you can configure it with -Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.Log4j2LogDelegateFactory. This is the easiest.
Of course, you can also set it directly in the code via System.setProperty, which is the same as the -D setting, but this must be done before the LoggerFactory is initialized. Obviously your code in the Verticle subclass must be executed after the Vertx initialization is successful. The LoggerFactory has already been initialized.
When i run my pipeline from local machine, i can update the table which resides in the cloud Sql instance. But, when i moved this to run using DataflowRunner, the same is failing with the below exception.
To connect from my eclipse, I created the data source config as
.create("com.mysql.jdbc.Driver", "jdbc:mysql://<ip of sql instance > :3306/mydb") .
The same i changed to
.create("com.mysql.jdbc.GoogleDriver", "jdbc:google:mysql://<project-id>:<instance-name>/my-db") while running through the Dataflow runner.
Should i prefix the zone information of the instance to ?
The exception i get when i run this is given below :
Jun 22, 2017 6:53:58 PM org.apache.beam.runners.dataflow.util.MonitoringUtil$LoggingHandler process
INFO: 2017-06-22T13:23:51.583Z: (840be37ab35d3d0d): Starting 2 workers in us-central1-f...
Jun 22, 2017 6:53:58 PM org.apache.beam.runners.dataflow.util.MonitoringUtil$LoggingHandler process
INFO: 2017-06-22T13:23:51.634Z: (dabfae1dc9365d10): Executing operation JdbcIO.Read/Create.Values/Read(CreateSource)+JdbcIO.Read/ParDo(Read)+JdbcIO.Read/ParDo(Anonymous)+JdbcIO.Read/GroupByKey/Reify+JdbcIO.Read/GroupByKey/Write
Jun 22, 2017 6:54:49 PM org.apache.beam.runners.dataflow.util.MonitoringUtil$LoggingHandler process
INFO: 2017-06-22T13:24:44.762Z: (21395b94f8bf7f61): Workers have started successfully.
SEVERE: 2017-06-22T13:25:30.214Z: (3b988386f963503e): java.lang.RuntimeException: org.apache.beam.sdk.util.UserCodeException: java.sql.SQLException: Cannot load JDBC driver class 'com.mysql.jdbc.GoogleDriver'
at com.google.cloud.dataflow.worker.runners.worker.MapTaskExecutorFactory$3.typedApply(MapTaskExecutorFactory.java:289)
at com.google.cloud.dataflow.worker.runners.worker.MapTaskExecutorFactory$3.typedApply(MapTaskExecutorFactory.java:261)
at com.google.cloud.dataflow.worker.graph.Networks$TypeSafeNodeFunction.apply(Networks.java:55)
at com.google.cloud.dataflow.worker.graph.Networks$TypeSafeNodeFunction.apply(Networks.java:43)
at com.google.cloud.dataflow.worker.graph.Networks.replaceDirectedNetworkNodes(Networks.java:78)
at com.google.cloud.dataflow.worker.runners.worker.MapTaskExecutorFactory.create(MapTaskExecutorFactory.java:152)
at com.google.cloud.dataflow.worker.runners.worker.DataflowWorker.doWork(DataflowWorker.java:272)
at com.google.cloud.dataflow.worker.runners.worker.DataflowWorker.getAndPerformWork(DataflowWorker.java:244)
at com.google.cloud.dataflow.worker.runners.worker.DataflowBatchWorkerHarness$WorkerThread.doWork(DataflowBatchWorkerHarness.java:125)
at com.google.cloud.dataflow.worker.runners.worker.DataflowBatchWorkerHarness$WorkerThread.call(DataflowBatchWorkerHarness.java:105)
at com.google.cloud.dataflow.worker.runners.worker.DataflowBatchWorkerHarness$WorkerThread.call(DataflowBatchWorkerHarness.java:92)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.beam.sdk.util.UserCodeException: java.sql.SQLException: Cannot load JDBC driver class 'com.mysql.jdbc.GoogleDriver'
at org.apache.beam.sdk.util.UserCodeException.wrap(UserCodeException.java:36)
at org.apache.beam.sdk.io.jdbc.JdbcIO$Read$ReadFn$auxiliary$M7MKjX9p.invokeSetup(Unknown Source)
at com.google.cloud.dataflow.worker.runners.worker.DoFnInstanceManagers$ConcurrentQueueInstanceManager.deserializeCopy(DoFnInstanceManagers.java:65)
at com.google.cloud.dataflow.worker.runners.worker.DoFnInstanceManagers$ConcurrentQueueInstanceManager.peek(DoFnInstanceManagers.java:47)
at com.google.cloud.dataflow.worker.runners.worker.UserParDoFnFactory.create(UserParDoFnFactory.java:100)
at com.google.cloud.dataflow.worker.runners.worker.DefaultParDoFnFactory.create(DefaultParDoFnFactory.java:70)
at com.google.cloud.dataflow.worker.runners.worker.MapTaskExecutorFactory.createParDoOperation(MapTaskExecutorFactory.java:365)
at com.google.cloud.dataflow.worker.runners.worker.MapTaskExecutorFactory$3.typedApply(MapTaskExecutorFactory.java:278)
... 14 more
Any help to fix this is really appreciated. This is my first attempt to run a beam pipeline as a dataflow job.
PipelineOptions options = PipelineOptionsFactory.as(DataflowPipelineOptions.class);
((DataflowPipelineOptions) options).setNumWorkers(2);
((DataflowPipelineOptions)options).setProject("xxxxx");
((DataflowPipelineOptions)options).setStagingLocation("gs://xxxx/staging");
((DataflowPipelineOptions)options).setRunner(DataflowRunner.class);
((DataflowPipelineOptions)options).setStreaming(false);
options.setTempLocation("gs://xxxx/tempbucket");
options.setJobName("sqlpipeline");
PCollection<Account> collection = dataflowPipeline.apply(JdbcIO.<Account>read()
.withDataSourceConfiguration(JdbcIO.DataSourceConfiguration
.create("com.mysql.jdbc.GoogleDriver", "jdbc:google:mysql://project-id:testdb/db")
.withUsername("root").withPassword("root"))
.withQuery(
"select account_id,account_parent,account_description,account_type,account_rollup,Custom_Members from account")
.withCoder(AvroCoder.of(Account.class)).withStatementPreparator(new JdbcIO.StatementPreparator() {
public void setParameters(PreparedStatement preparedStatement) throws Exception {
preparedStatement.setFetchSize(1);
preparedStatement.setFetchDirection(ResultSet.FETCH_FORWARD);
}
}).withRowMapper(new JdbcIO.RowMapper<Account>() {
public Account mapRow(ResultSet resultSet) throws Exception {
Account account = new Account();
account.setAccount_id(resultSet.getInt("account_id"));
account.setAccount_parent(resultSet.getInt("account_parent"));
account.setAccount_description(resultSet.getString("account_description"));
account.setAccount_type(resultSet.getString("account_type"));
account.setAccount_rollup("account_rollup");
account.setCustom_Members("Custom_Members");
return account;
}
}));
Have you properly pulled in the com.google.cloud.sql/mysql-socket-factory maven dependency? Looks like you are failing to load the class.
https://cloud.google.com/appengine/docs/standard/java/cloud-sql/#Java_Connect_to_your_database
Hi I think it's better to move on with "com.mysql.jdbc.Driver" because google driver is supporting for app engine deployments
So as it goes this is what my pipeline configurations look alike and it works perfectly fine for me
PCollection < KV < Double, Double >> exchangeRates = p.apply(JdbcIO. < KV < Double, Double >> read()
.withDataSourceConfiguration(JdbcIO.DataSourceConfiguration.create("com.mysql.jdbc.Driver", "jdbc:mysql://ip:3306/dbname?user=root&password=root&useUnicode=true&characterEncoding=UTF-8")
)
.withQuery(
"SELECT PERIOD_YEAR, PERIOD_YEAR FROM SALE")
.withCoder(KvCoder.of(DoubleCoder.of(), DoubleCoder.of()))
.withRowMapper(new JdbcIO.RowMapper < KV < Double, Double >> () {
#Override
public KV<Double, Double> mapRow(java.sql.ResultSet resultSet) throws Exception {
LOG.info(resultSet.getDouble(1)+ "Came");
return KV.of(resultSet.getDouble(1), resultSet.getDouble(2));
}
}));
Hope it will help
Intention is to create an asset using java code and the Sites REST API.
First of I couldn't find the REST API samples anywhere in the installation or even source directories of the 11.1.1.8.0 Sites or JSK.
Instead I found the the samples in the 11.1.1.6.0 server.
The code I'm running after changing the base URL in both the POSt and PUT methods:
/*
* $Logfile:$ $Revision:$ $Date:$ Copyright © 2010 FatWire Corporation, All
* Rights Reserved. Copyright 2010 FatWire Corporation. Title, ownership rights,
* and intellectual property rights in and to this software remain with FatWire
* Corporation. This software is protected by international copyright laws and
* treaties, and may be protected by other law. Violation of copyright laws may
* result in civil liability and criminal penalties.
*/
package com.fatwire.rest.samples.flex;
import javax.ws.rs.core.MediaType;
import com.fatwire.rest.beans.AssetBean;
import com.fatwire.rest.beans.Attribute;
import com.fatwire.rest.beans.Attribute.Data;
import com.fatwire.rest.beans.ErrorBean;
import com.fatwire.rest.beans.Parent;
import com.fatwire.wem.sso.SSO;
import com.fatwire.wem.sso.SSOException;
import com.fatwire.wem.sso.SSOSession;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.WebResource.Builder;
import com.fatwire.wem.sso.cas.conf.CASConfig;
/**
* <p>
* Sample JAVA class to demonstrate creation of new Flex assets using REST API
* exposed by Fatwire WEM module.
* </p>
* <p>
* For this class to function, the following are the pre-requisites:
* <ol>
* <li>The following jars are required in the classpath:
* <ul>
* <li>rest-api.jar</li>
* <li>wem-sso-api.jar</li>
* <li>jersey-client.jar</li>
* <li>jsr311-api.jar</li>
* <li>jersey-client.jar</li>
* <li>jersey-core.jar</li>
* </ul>
* </li>
* <li>The following configuration file is required in the classpath (in the
* example, the above file is referred to as <tt>ExampleCASConfig.xml</tt>.):
*
* <pre>
* <?xml version="1.0" encoding="UTF-8"?>
* <beans
* xmlns="http://www.springframework.org/schema/beans"
* xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
* xmlns:context="http://www.springframework.org/schema/context"
* xsi:schemaLocation="http://www.springframework.org/schema/beans
* http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
* http://www.springframework.org/schema/context
* http://www.springframework.org/schema/context/spring-context-2.5.xsd">
* <!-- DONOT CHANGE: Single Sign On provider -->
* <bean id="ssoprovider" class="com.fatwire.wem.sso.cas.CASProvider">
* <property name="config" ref="ssoconfig" />
* </bean>
* <!--
* Single Sign On configuration: change ONLY the following property:
* casUrl - URL of the CAS installation
* -->
* <bean id="ssoconfig" class="com.fatwire.wem.sso.cas.conf.CASConfig">
* <property name="casUrl" value="${cas-url}" />
* <property name="casRestPath" value="/v1" />
* </bean>
* </beans>
* </pre>
*
* </li>
* <li>The Content Server Installation must have the "FirstSiteII" sample site
* and the "Product_C" asset type. "Product_C" should be enabled in
* "FirstSiteII". There should not be an asset by the name of "Test Product_C"
* which is the name of the test asset.</li>
* </ol>
*
* #author Saikat Chaudhuri
*/
public final class CreateAsset
{
/**
* Main method. Run this method to create a basic asset using:
* <ul>
* <li>{#link #createUsingPut()}</li>
* <li>{#link #createUsingPost()}</li>
* </ul>
*
* #param args
*/
public static void main(String[] args)
{
createUsingPut();
// createUsingPost();
}
/**
* Run this method to create a basic asset using PUT.
*/
public static void createUsingPut()
{
// Step 1: Initiate Jersey client
Client client = Client.create();
// Step 2: Create a WebResource with the base URL
WebResource webResource =
client.resource("http://127.0.0.1:9080/cs/REST");
// Step 3: Authenticate over SSO-CAS to acquire a ticket specific to a
// service or a multi-ticket over multiple services.
SSOSession ssoSession = null;
String multiticket = null;
try
{
ssoSession = SSO.getSSOSession("ExampleCASConfig.xml");
multiticket = ssoSession.getMultiTicket("fwadmin", "xceladmin");
}
catch (SSOException e)
{
// Troubleshooting SSOException
// ============================
//
// Cause: CAS is not running.
// Remedy: Deploy CAS and start up the application server for CAS
// webapp.
//
// Cause: CAS is not configured.
// Remedy: Verify that the URL in the CAS config file,
// ExampleCASConfig.xml, is reachable.
//
// Cause: Username / password is invalid.
// Remedy: Use valid username / password to authenticate against
// CAS.
// Handle exception
e.printStackTrace();
}
// Step 4: Provide the ticket into the REST request
webResource = webResource.queryParam("multiticket", multiticket);
// Trying to create a Flex asset for the Flex asset type
// "Product_C" in the CS site "FirstSiteII"
String flexAssetSiteName = "FirstSiteII";
String flexAssetTypeName = "Product_C";
// Step 5: Specify the REST Resource URL into the WebResource
// For creating assets of type {typename} in the CS site {sitename},
// this is: {base_url}/sites/{sitename}/types/{typename}/assets/0
webResource =
webResource.path("sites").path(flexAssetSiteName).path("types")
.path(flexAssetTypeName).path("assets").path("0");
// Step 6: Create a Builder and set the desired response type
// Supported response types are:
// MediaType.APPLICATION_XML, or,
// MediaType.APPLICATION_JSON
Builder builder = webResource.accept(MediaType.APPLICATION_XML);
// Step 7: Instantiate and define the AssetBean for the asset
AssetBean sourceAsset = new AssetBean();
// Name - mandatory field
sourceAsset.setName("Test Product_C PUT");
// Description - optional field
sourceAsset.setDescription("Test Product_C PUT description");
// Add attributes / associations / parents as in the Asset type
// definition
Attribute sourceAssetAttribute = new Attribute();
Data sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIISKU");
sourceAssetAttributeData.setStringValue("Test SKU");
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
sourceAssetAttribute = new Attribute();
sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIILongDescription");
sourceAssetAttributeData.setStringValue("Test Long Description");
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
sourceAssetAttribute = new Attribute();
sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIIPrice");
sourceAssetAttributeData.setDoubleValue(10.00);
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
sourceAssetAttribute = new Attribute();
sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIIImage");
sourceAssetAttributeData.setStringValue("Media_C:1114083738411");
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
Parent parent = new Parent();
parent.setParentDefName("FSIIManufacturer");
parent.getAssets().add("Product_P:1114083739006");
sourceAsset.getParents().add(parent);
parent = new Parent();
parent.setParentDefName("FSIISubcategory");
parent.getAssets().add("Product_P:1114083739104");
sourceAsset.getParents().add(parent);
// Required: Must specify the site(s) for the asset
sourceAsset.getPublists().add(flexAssetSiteName);
// Required: Must specify the sub type for the Flex asset type
sourceAsset.setSubtype("FSII Product");
// Step 8: Invoke the REST request to create the asset
AssetBean resultAsset = builder.put(AssetBean.class, sourceAsset);
// If the REST call encounter a server side exception, the client
// receives a UniformInterfaceException at runtime.
// Troubleshooting UniformInterfaceException
// =========================================
//
// Cause: HTTP 403: User does not have permission to access the REST
// resource.
// Remedy: Use an authorized CAS user to use this REST resource.
//
// Cause: HTTP 404: Either site and/or asset type does not exist, or the
// asset type is not enabled in the site.
// Remedy: Verify existence of the site and/or asset type, if necessary
// create the site and/or type and make sure that the type is enabled in
// the site.
//
// Cause: HTTP 500: Generic server side exception.
// Remedy: Verify that the source AssetBean has been provided with all
// mandatory attributes, associations as per type definition, verify
// that at least one site has been provided in the publist attribute of
// the AssetBean.
//
// Cause: UnmarshalException.
// Remedy: Verify that the correct bean has been provided in the
// argument for put().
}
/**
* Run this method to create a basic asset using POST.
*/
public static void createUsingPost()
{
// Step 1: Initiate Jersey client
Client client = Client.create();
// Step 2: Create a WebResource with the base URL
WebResource webResource =
client.resource("http://127.0.0.1:9080/cs/REST");
// Step 3: Authenticate over SSO-CAS to acquire a ticket specific to a
// service or a multi-ticket over multiple services.
SSOSession ssoSession = null;
String multiticket = null;
try
{
ssoSession = SSO.getSSOSession("ExampleCASConfig.xml");
multiticket = ssoSession.getMultiTicket("fwadmin", "xceladmin");
}
catch (SSOException e)
{
// Troubleshooting SSOException
// ============================
//
// Cause: CAS is not running.
// Remedy: Deploy CAS and start up the application server for CAS
// webapp.
//
// Cause: CAS is not configured.
// Remedy: Verify that the URL in the CAS config file,
// ExampleCASConfig.xml, is reachable.
//
// Cause: Username / password is invalid.
// Remedy: Use valid username / password to authenticate against
// CAS.
// Handle exception
e.printStackTrace();
}
// Step 4: Provide the ticket into the REST request
webResource = webResource.queryParam("multiticket", multiticket);
// Trying to create a Flex asset for the Flex asset type
// "Product_C" in the CS site "FirstSiteII"
String flexAssetSiteName = "FirstSiteII";
String flexAssetTypeName = "Product_C";
// Step 5: Specify the REST Resource URL into the WebResource
// For creating assets of type {typename} in the CS site {sitename},
// this is: {base_url}/sites/{sitename}/types/{typename}/assets
webResource =
webResource.path("sites").path(flexAssetSiteName).path("types")
.path(flexAssetTypeName).path("assets");
// Step 6: Create a Builder and set the desired response type
// Supported response types are:
// MediaType.APPLICATION_XML, or,
// MediaType.APPLICATION_JSON
Builder builder = webResource.accept(MediaType.APPLICATION_XML);
// Step 7: Instantiate and define the AssetBean for the asset
AssetBean sourceAsset = new AssetBean();
// Name - mandatory field
sourceAsset.setName("Test Product_C POST");
// Description - optional field
sourceAsset.setDescription("Test Product_C POST description");
// Add attributes / associations / parents as in the Asset type
// definition
Attribute sourceAssetAttribute = new Attribute();
Data sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIISKU");
sourceAssetAttributeData.setStringValue("Test SKU");
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
sourceAssetAttribute = new Attribute();
sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIILongDescription");
sourceAssetAttributeData.setStringValue("Test Long Description");
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
sourceAssetAttribute = new Attribute();
sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIIPrice");
sourceAssetAttributeData.setDoubleValue(10.00);
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
sourceAssetAttribute = new Attribute();
sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIIImage");
sourceAssetAttributeData.setStringValue("Media_C:1114083738411");
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
Parent parent = new Parent();
parent.setParentDefName("FSIIManufacturer");
parent.getAssets().add("Product_P:1114083739006");
sourceAsset.getParents().add(parent);
parent = new Parent();
parent.setParentDefName("FSIISubcategory");
parent.getAssets().add("Product_P:1114083739104");
sourceAsset.getParents().add(parent);
// Required: Must specify the site(s) for the asset
sourceAsset.getPublists().add(flexAssetSiteName);
// Required: Must specify the sub type for the Flex asset type
sourceAsset.setSubtype("FSII Product");
// Step 8: Invoke the REST request to create the asset
ClientResponse resp = builder.post(ClientResponse.class, sourceAsset);
// The "Location" header provides the element URI
// which can be used to read back the asset which was created.
String elementURI = resp.getHeaders().get("Location").get(0);
// If the REST call encounter a server side exception, the client
// receives a UniformInterfaceException at runtime.
// Troubleshooting UniformInterfaceException
// =========================================
//
// Cause: HTTP 403: User does not have permission to access the REST
// resource.
// Remedy: Use an authorized CAS user to use this REST resource.
//
// Cause: HTTP 404: Either site and/or asset type does not exist, or the
// asset type is not enabled in the site.
// Remedy: Verify existence of the site and/or asset type, if necessary
// create the site and/or type and make sure that the type is enabled in
// the site.
//
// Cause: HTTP 500: Generic server side exception.
// Remedy: Verify that the source AssetBean has been provided with all
// mandatory attributes, associations as per type definition, verify
// that at least one site has been provided in the publist attribute of
// the AssetBean.
//
// Cause: UnmarshalException.
// Remedy: Verify that the correct bean has been provided in the
// argument for post().
}
}
Adding the JARs
I searched for every JAR name mentioned in the sample comments in the the JSK
Installation directory and added them.
The JARs:
jersey-client-1.1.4.1.jar
jersey-core-1.1.4.1.jar
jsr311-api-1.1.1.jar
rest-api-11.1.1.8.0.jar
wem-sso-api-11.1.1.8.0.jar
Apparently these JARs we needed also but not mentioned:
cas-client-core-3.1.9.jar
wem-sso-api-cas-11.1.1.8.0.jar
spring 2.5.6.jar
commons-logging-1.1.1.jar
From the source code comments I extracted the XML file to be used as spring configuration, in the ssoconfig
bean added the casUrl value, and changed the attribute name of casRestPath to restPath as it
didn't exist in the class.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- DONOT CHANGE: Single Sign On provider -->
<bean id="ssoprovider" class="com.fatwire.wem.sso.cas.CASProvider">
<property name="config" ref="ssoconfig"/>
</bean>
<!-- Single Sign On configuration: change ONLY the following property: casUrl
- URL of the CAS installation -->
<bean id="ssoconfig" class="com.fatwire.wem.sso.cas.conf.CASConfig">
<property name="casUrl" value="http://127.0.0.1:9080/cas" />
<property name="restPath" value="/v1" />
</bean>
</beans>
The Exception I get running the POST method:
Jan 08, 2014 5:43:50 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext#4c08964: startup date [Wed Jan 08 17:43:50 GMT+02:00 2014]; root of context hierarchy
Jan 08, 2014 5:43:50 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [ExampleCASConfig.xml]
Jan 08, 2014 5:43:50 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#3c200d0: defining beans [ssoprovider,ssoconfig]; root of factory hierarchy
Exception in thread "main" com.sun.jersey.api.client.UniformInterfaceException: PUT http://127.0.0.1:9080/cs/REST/sites/FirstSiteII/types/Product_C/assets/0?multiticket=multi-ST-39-DPgghOvnBCAAggKLAHpa-_tmp_1374099243365 returned a response status of 401
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:563)
at com.sun.jersey.api.client.WebResource.access$300(WebResource.java:69)
at com.sun.jersey.api.client.WebResource$Builder.put(WebResource.java:475)
at com.fatwire.rest.samples.flex.CreateAsset.createUsingPut(CreateAsset.java:222)
at com.fatwire.rest.samples.flex.CreateAsset.main(CreateAsset.java:97)
On debugging I found out the the response came back with status 401 .
The Exception I get running the PUT method:
Jan 09, 2014 12:03:36 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext#4c08964: startup date [Thu Jan 09 12:03:36 GMT+02:00 2014]; root of context hierarchy
Jan 09, 2014 12:03:36 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [ExampleCASConfig.xml]
Jan 09, 2014 12:03:36 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#3c200d0: defining beans [ssoprovider,ssoconfig]; root of factory hierarchy
Exception in thread "main" com.sun.jersey.api.client.UniformInterfaceException: PUT http://127.0.0.1:9080/cs/REST/sites/FirstSiteII/types/Product_C/assets/0?multiticket=multi-ST-7-kejMYvRWO1cua39MfPYn-_tmp_1374099243365 returned a response status of 401
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:563)
at com.sun.jersey.api.client.WebResource.access$300(WebResource.java:69)
at com.sun.jersey.api.client.WebResource$Builder.put(WebResource.java:475)
at com.fatwire.rest.samples.flex.CreateAsset.createUsingPut(CreateAsset.java:222)
at com.fatwire.rest.samples.flex.CreateAsset.main(CreateAsset.java:97)
There are no existing assets with the same name as the one in the code.
The fwadmin user is tested but the default configuration of the JSK and also the after adding it to all security groups and roles (including REST ofcourse).
All used asset ID/s in the sample (for the parents and so) check out, they exist.
Don't know about the new code (11.1.1.8.0) but this old (11.1.1.6.0) code used doesn't cope with the CSRF protection token and the new version of Sites added a CSRF protection filter, so we can either handle the token from the code (as used in the new code) :
//Add the CSRF header (between steps 6 & 7).
builder = builder.header("X-CSRF-Token", multiticket);
The 11.1.1.8.0 code location
WCS_Sites/misc/Samples/WEM Samples/REST API samples/Flex
Assets/com/fatwire/rest
or add the rest request patterns to the filter exceptions list in ReqAuthConfig.xml file in /WEB-INF/classes folder
<property name="excludedURLs">
<!-- URLs in this section would be excluded from CSRF protection-->
<!-- For example to exclude rest calls add <value>/REST/**</value> in the list-->
<list>
<value>/ContentServer?[pagename=fatwire/wem/sso/ssoLogin|OpenMarket/Xcelerate/Actions/ProcessQueue|OpenMarket/Xcelerate/Actions/CleanTempObjects|OpenMarket/Xcelerate/Search/Event,#]</value>
<value>/CatalogManager?[ftcmd=login,#]</value>
<value>/FlushServer</value>
<value>/CacheServer</value>
<value>/cachetool/inventory.jsp</value>
<value>/Inventory</value>
</list>
</property>
I am experimenting with server sent event. Am following this link https://jersey.java.net/documentation/latest/user-guide.html#d0e8376. When I make request to the resource representing Server Sent Event, I get 500 Internal server error.
According to following error, I have to register the body writer for org.glassfish.jersey.media.sse.EventOutput. But, how to do it?
####<21 Nov, 2013 3:17:28 PM IST> <Error> <com.sun.jersey.spi.container.ContainerResponse> <Laptop1> <AdminServer> <[ACTIVE] ExecuteThread: '16' for queue: 'weblogic.kernel.Default (self-tuning)'> <<anonymous>> <> <> <1385027248248> <BEA-000000> <Mapped exception to response: 500 (Internal Server Error)
javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class org.glassfish.jersey.media.sse.EventOutput, and Java type class org.glassfish.jersey.media.sse.EventOutput, and MIME media type text/event-stream was not found
at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:285)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1479)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1391)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1381)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716)
at weblogic.jaxrs.server.portable.servlet.ServletContainer.service(ServletContainer.java:218)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:341)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:238)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3363)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3333)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2220)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2146)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2124)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1564)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:295)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:254)
Caused By: com.sun.jersey.api.MessageException: A message body writer for Java class org.glassfish.jersey.media.sse.EventOutput, and Java type class org.glassfish.jersey.media.sse.EventOutput, and MIME media type text/event-stream was not found
at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:285)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1479)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1391)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1381)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716)
at weblogic.jaxrs.server.portable.servlet.ServletContainer.service(ServletContainer.java:218)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:341)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:238)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3363)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3333)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2220)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2146)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2124)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1564)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:295)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:254)
Here is solution for my own question.
To register SseFeature, getSingletons method should be overridden in Application derived class, as show in below code.
#javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application {
//....
#Override
public Set<Object> getSingletons() {
Set<Object> singletons = super.getSingletons();
if(singletons == null){
singletons=new java.util.HashSet<Object>();
}
singletons.add(new SseFeature());
return singletons;
}
//....
}
to use jersey latest version ( jersey 2.8 ) we should get rid of com.sun.jersey.api
Jersey APIs are now in org.glassfish.jersey package.
I suggest you to go through the following post and resolve the issues
check the update in question and comments
NoClassDefFoundError ProcessingException while migrating from jersey 1.x to jersey 2.x ( 2.8 )
I have this code in a jersey web service:
#Path("/areThereNewOrders")
#GET
#Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON,
MediaType.TEXT_XML, MediaType.TEXT_HTML })
public List<Integer> areThereNewOrders() {
if (NewOrders.newOrders != null
&& NewOrders.newOrders.containsKey(restaurantID)
&& NewOrders.newOrders.get(restaurantID).size() != 0) {
return NewOrders.newOrders.get(restaurantID);
} else {
System.out.println("No New Orders For Restaurant " + restaurantID);
List<Integer> r = new LinkedList<Integer>();
return r;
}
}
but I got this exception:
Jul 10, 2013 2:59:22 PM com.sun.jersey.spi.container.ContainerResponse write
SEVERE: A message body writer for Java class java.util.LinkedList, and Java type java.util.List<java.lang.Integer>, and MIME media type text/html was not found
Jul 10, 2013 2:59:22 PM com.sun.jersey.spi.container.ContainerResponse write
SEVERE: The registered message body writers compatible with the MIME media type are:
*/* ->
com.sun.jersey.core.impl.provider.entity.FormProvider
com.sun.jersey.core.impl.provider.entity.StringProvider
com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
com.sun.jersey.core.impl.provider.entity.FileProvider
com.sun.jersey.core.impl.provider.entity.InputStreamProvider
com.sun.jersey.core.impl.provider.entity.DataSourceProvider
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
com.sun.jersey.core.impl.provider.entity.ReaderProvider
com.sun.jersey.core.impl.provider.entity.DocumentProvider
com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider
com.sun.jersey.core.impl.provider.entity.SourceProvider$SourceWriter
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General
com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$General
com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$General
com.sun.jersey.json.impl.provider.entity.JSONWithPaddingProvider
com.sun.jersey.server.impl.template.ViewableMessageBodyWriter
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General
com.sun.jersey.json.impl.provider.entity.JacksonProviderProxy
Jul 10, 2013 2:59:22 PM com.sun.jersey.spi.container.ContainerResponse logException
SEVERE: Mapped exception to response: 500 (Internal Server Error)
javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class java.util.LinkedList, and Java type java.util.List<java.lang.Integer>, and MIME media type text/html was not found
at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:285)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1479)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1391)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1381)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: com.sun.jersey.api.MessageException: A message body writer for Java class java.util.LinkedList, and Java type java.util.List<java.lang.Integer>, and MIME media type text/html was not found
... 25 more
I am sure that the error because I return a list of integer but i don't know the solution.
any help would be helpful, thanks in advance
Returning a
List<Integer>
or a
List<String>
does not give JAXB enough information to marshal the XML or JSON.
You generally want to return a domain object with more information than just ids.
Therefore :
public List<Integer> areThereNewOrders() {
should change to
public List<Order> areThereNewOrders() {
#XmlRootElement// this gives the root element the name order
public class Order {
private Integer id;
private String name;
..
}
This allows the JAXB marshaller to convert into
{"order":[{"id":"1","name":"Order 1"},{"id":"2","name":"Order 2"}]}
To unmarshal from Json the name "order" is used.
Try to create a JAXB-annotated wrapper, e.g.:
#XmlRootElement(name="list")
public class JaxbList<T> implements List<T> {
protected List<T> list;
public JaxbList(List<T> list){
this.list=list;
}
#XmlElement(name="item")
public List<T> getList(){
return this;
}
}
and return that from the Jersey method
return new JaxbList<Integer>(r);