Based on the example mentioned in - https://gist.github.com/canthony/3655917 I have created a new Vaadin example to upload an Excel/CSV file.
Based on the comments mentioned, I even downloaded opencsv-3.0 from the http://opencsv.sourceforge.net and added them into the project.
Below is how I added them
Right Click on Vaadin project created --> Properties --> Java Build Path --> Add Library (Created new User Library) --> New User Library --> User Libraries --> New (In User Libraries page) --> Created New Library with name CSV --> Included the OpenCSV3.0-jar
Finally this is how my setup looks like:
No errors or warnings are present, but when I publish on tomcat I get below error. This error comes up when I Browse a file and click on Upload button. Can some one please help?
SEVERE:
java.lang.NoClassDefFoundError: au/com/bytecode/opencsv/CSVReader
at com.example.uploadexcel.UploadexcelUI.buildContainerFromCSV(UploadexcelUI.java:101)
at com.example.uploadexcel.UploadexcelUI$2.uploadFinished(UploadexcelUI.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:508)
at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:198)
at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:161)
at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:979)
at com.vaadin.ui.Upload.fireUploadInterrupted(Upload.java:875)
at com.vaadin.ui.Upload$2.streamingFailed(Upload.java:1166)
at com.vaadin.server.communication.FileUploadHandler.streamToReceiver(FileUploadHandler.java:615)
at com.vaadin.server.communication.FileUploadHandler.handleFileUploadValidationAndData(FileUploadHandler.java:447)
at com.vaadin.server.communication.FileUploadHandler.doHandleSimpleMultipartFileUpload(FileUploadHandler.java:397)
at com.vaadin.server.communication.FileUploadHandler.handleRequest(FileUploadHandler.java:282)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1402)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:305)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
I don't understand why I get java.lang.NoClassDefFoundError when I have added the required jar into the Java build path.
Full code:
public class UploadexcelUI extends UI {
protected File tempFile;
protected Table table;
#WebServlet(value = "/*", asyncSupported = true)
#VaadinServletConfiguration(productionMode = false, ui = UploadexcelUI.class)
public static class Servlet extends VaadinServlet {
}
#SuppressWarnings("deprecation")
#Override
protected void init(VaadinRequest request) {
Upload upload = new Upload("Upload CSV File", new Upload.Receiver() {
#Override
public OutputStream receiveUpload(String filename, String mimeType) {
try {
/* Here, we'll stored the uploaded file as a temporary file. No doubt there's
a way to use a ByteArrayOutputStream, a reader around it, use ProgressListener (and
a progress bar) and a separate reader thread to populate a container *during*
the update.
This is quick and easy example, though.
*/
tempFile = File.createTempFile("temp", ".csv");
return new FileOutputStream(tempFile);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
});
upload.addListener(new Upload.FinishedListener() {
#Override
public void uploadFinished(Upload.FinishedEvent finishedEvent) {
try {
/* Let's build a container from the CSV File */
FileReader reader = new FileReader(tempFile);
IndexedContainer indexedContainer = buildContainerFromCSV(reader);
reader.close();
tempFile.delete();
/* Finally, let's update the table with the container */
table.setCaption(finishedEvent.getFilename());
table.setContainerDataSource(indexedContainer);
table.setVisible(true);
} catch (IOException e) {
e.printStackTrace();
}
}
});
/* Table to show the contents of the file */
table = new Table();
table.setVisible(false);
/* Main layout */
VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
layout.setSpacing(true);
layout.addComponent(table);
layout.addComponent(upload);
setContent(layout);
}
/**
* Uses http://opencsv.sourceforge.net/ to read the entire contents of a CSV
* file, and creates an IndexedContainer from it
*
* #param reader
* #return
* #throws IOException
*/
#SuppressWarnings("resource")
protected IndexedContainer buildContainerFromCSV(Reader reader) throws IOException {
IndexedContainer container = new IndexedContainer();
CSVReader csvReader = new CSVReader(reader);
String[] columnHeaders = null;
String[] record;
while ((record = csvReader.readNext()) != null) {
if (columnHeaders == null) {
columnHeaders = record;
addItemProperties(container, columnHeaders);
} else {
addItem(container, columnHeaders, record);
}
}
return container;
}
/**
* Set's up the item property ids for the container. Each is a String (of course,
* you can create whatever data type you like, but I guess you need to parse the whole file
* to work it out)
*
* #param container The container to set
* #param columnHeaders The column headers, i.e. the first row from the CSV file
*/
private static void addItemProperties(IndexedContainer container, String[] columnHeaders) {
for (String propertyName : columnHeaders) {
container.addContainerProperty(propertyName, String.class, null);
}
}
/**
* Adds an item to the given container, assuming each field maps to it's corresponding property id.
* Again, note that I am assuming that the field is a string.
*
* #param container
* #param propertyIds
* #param fields
*/
#SuppressWarnings("unchecked")
private static void addItem(IndexedContainer container, String[] propertyIds, String[] fields) {
if (propertyIds.length != fields.length) {
throw new IllegalArgumentException("Hmmm - Different number of columns to fields in the record");
}
Object itemId = container.addItem();
Item item = container.getItem(itemId);
for (int i = 0; i < fields.length; i++) {
String propertyId = propertyIds[i];
String field = fields[i];
item.getItemProperty(propertyId).setValue(field);
}
}
}
Probably, it is a dependency issue. You need to add commons-lang3 as dependency.
You can find the required .jar file here.
Check this answer.
P.S.- May be I should have put this in comment but as my reputation is quite low, I can't.
Here are the satisfactory enough dependencies of net.sf.opencsv:opencsv:2.3:
$HOME/.m2/repository/net/sf/opencsv/opencsv/2.3/opencsv-2.3.jar,$HOME/.m2/repository/org/apache/commons/commons-lang3/3.1/commons-lang3-3.1.jar,$HOME/.m2/repository/commons-beanutils/commons-beanutils/1.7.0/commons-beanutils-1.7.0.jar,$HOME/.m2/repository/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar
Related
I am trying to run a MapReduce code to calculate average satisfaction level per department. Below is the sample data. The file has headers and in order to remove the headers I placed these in another txt file and used it to check if the row values are not equal to headers.
Sample Data
satisfaction_level,last_evaluation,number_project,average_montly_hours,time_spend_company,Work_accident,left,promotion_last_5years,sales,salary
0.38,0.53,2,157,3,0,1,0,sales,low
0.8,0.86,5,262,6,0,1,0,sales,medium
0.11,0.88,7,272,4,0,1,0,sales,medium
0.72,0.87,5,223,5,0,1,0,sales,low
0.37,0.52,2,159,3,0,1,0,sales,low
0.41,0.5,2,153,3,0,1,0,sales,low
0.1,0.77,6,247,4,0,1,0,sales,low
0.92,0.85,5,259,5,0,1,0,sales,low
0.89,1,5,224,5,0,1,0,sales,low
Below is my mapper code.
public class SatisfactionLevelMapper extends Mapper<LongWritable, Text, Text, FloatWritable>
{
String header;
#Override
protected void setup(Mapper.Context context) throws IOException, InterruptedException
/* Headers are placed in a separate header.txt file for which the location is specified in the driver */
{
BufferedReader bufferedReader = new BufferedReader(new FileReader("header.txt"));
header = bufferedReader.readLine();
}
public void map(LongWritable key, Text text, Context context) throws IOException, InterruptedException
{
String row = text.toString();
String [] values = row.trim().split(","); //dataset is a CSV file with 10 columns
float satisfaction = 0.0f;
String dept = null;
try
{
if(values.length == 9 && header != row)
{
satisfaction = Float.parseFloat(values[0]); }
}
catch (Exception e)
{
e.printStackTrace();
}
context.write(new Text(dept), new FloatWritable(satisfaction));
}
}
I am getting a NullPointerException Error as below.
Error: java.lang.NullPointerException
at org.apache.hadoop.io.Text.encode(Text.java:450)
at org.apache.hadoop.io.Text.set(Text.java:198)
at org.apache.hadoop.io.Text.<init>(Text.java:88)
at com.df.hra.SatisfactionLevelMapper.map SatisfactionLevelMapper.java:62)
at com.df.hra.SatisfactionLevelMapper.map(SatisfactionLevelMapper.java:1)
at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:145)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:784)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:168)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1642)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:163)
Is there a way to figure out which part of my code has the issue?
I am new to Java and trying to figure out a way to debug MapReduce codes. Any help would be appreciated. Thanks!
You cannot initialize a Text value with null, as you're doing here (with dept). Consider using an empty String ("") instead.
I am working on a Spring Restful Web service wherein I am returning an xml file as a response. This XML file is placed inside the main/resources folder of the MAVEN project build in eclipse. The service accepts certain parameters from the caller and based on those parameters, it should update the XML file. This project is deployed as WAR in the production server. On my local project, I can see the xml file being updated but in the production server it is not. How can I get this working in the production server ?
Below is the code for controller accepting the incoming request
#RestController
public class HelloWorldRestController {
#Autowired
UserService userService; // Service which will do all data
// retrieval/manipulation work
#Autowired
DialogServiceXml dialogService;
// Returning an xml file in the response
#CrossOrigin(origins = "*")
#RequestMapping(value = "/getUpdatedDialog", method = RequestMethod.POST, produces = "application/xml")
public ResponseEntity<InputStreamResource> downloadXMLFile(#RequestBody Dialog dialog,
UriComponentsBuilder ucBuilder) throws IOException {
// Update the xml file named : "mor_dialog.xml"
dialogService.updateXml(new StringBuilder(dialog.getClassName()), new StringBuilder(dialog.getResponse()));
// Pick up the updated file from the classpath
ClassPathResource xmlFile = null;
try {
xmlFile = new ClassPathResource("mor_dialog.xml");
} catch (Exception exception) {
exception.printStackTrace();
}
// Code to prevent caching so that always the latest version of the file
// is being sent.
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Cache-Control", "no-cache, np-store, must-revalidate");
httpHeaders.add("Pragma", "no-cache");
httpHeaders.add("Expires", "0");
//httpHeaders.add("Access-Control-Allow-Origin", "http://nlc-mor-furniture.mybluemix.net");
return ResponseEntity.ok().headers(httpHeaders).contentLength(xmlFile.contentLength())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(new InputStreamResource(xmlFile.getInputStream()));
}
}
Below is the class that unmarshals the XML, updates it based on the input parameters, then marshals it back
#Service("dialogService")
public class DialogServiceXml implements DialogServiceXmlImpl {
#SuppressWarnings({ "rawtypes", "unchecked" })
#Override
public void updateXml(StringBuilder className, StringBuilder response) {
JAXBContext jaxbContext = null;
ClassLoader classLoader = getClass().getClassLoader();
try {
jaxbContext = JAXBContext.newInstance("com.sau.watson.dialog.xsd.beans");
Unmarshaller JAXBUnmarshaller = jaxbContext.createUnmarshaller();
Marshaller JAXBMarshaller = jaxbContext.createMarshaller();
JAXBMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
JAXBMarshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, "WatsonDialogDocument_1.0.xsd");
File mor_dialog = new File(classLoader.getResource("mor_dialog.xml").getFile());
//File mor_dialog = new File(classLoader.getResource("../../mor_dialog.xml").getFile());
mor_dialog.setWritable(true);
//File mor_dialog_updated = new File(classLoader.getResource("mor_dialog_updated.xml").getFile());
InputStream is = new FileInputStream(mor_dialog);
JAXBElement dialog = (JAXBElement) JAXBUnmarshaller.unmarshal(is);
is.close();
//JAXBElement dialog = (JAXBElement) JAXBUnmarshaller.unmarshal(new FileInputStream("src/main/java/com/sau/watson/dialog/xml/mor_dialog.xml"));
DialogType dialogType = (DialogType) dialog.getValue();
// System.out.println(dialogType.toString());
// System.out.println(dialogType);
FlowType flowType = (FlowType) dialogType.getFlow();
for (FolderNodeType folderNodeType : flowType.getFolder()) {
// System.out.println(folderNodeType.getLabel());
if (folderNodeType.getLabel().equalsIgnoreCase("Library")) {
for (ChatflowNode libChatFlowNode : folderNodeType.getInputOrOutputOrDefault()) {
FolderNodeType libraryFolderNode = (FolderNodeType) libChatFlowNode;
// System.out.println(libraryFolderNode.getId());
// System.out.println(libraryFolderNode.getLabel());
StringBuilder classNameFromXml = new StringBuilder();
for (ChatflowNode node : libraryFolderNode.getInputOrOutputOrDefault()) {
InputNodeType inputNodeType = (InputNodeType) node;
// Getting the class. Class name are encapsulated
// inside the <grammar> node
/**
* <grammar> <item>Salesperson_Great</item>
* <item>Great</item> </grammar>
*/
for (Object grammerTypeObj : inputNodeType.getActionOrScriptOrGrammar()) {
GrammarType grammarType = (GrammarType) grammerTypeObj;
// We are always getting the first item as it is
// assumed that there is only one class in each
// grammar node
classNameFromXml
.append(grammarType.getItemOrSourceOrParam().get(0).getValue().toString());
System.out.println("Class Name is : " + className);
}
// We are always getting the first item as it is
// assumed that there is only one class in each
// grammar node
/*
* List<Object> grammarTypeObj =
* inputNodeType.getActionOrScriptOrGrammar();
* GrammarType grammarType = (GrammarType)
* grammarTypeObj;
*
* String className =
* grammarType.getItemOrSourceOrParam().get(0).
* getValue().toString();
*
* System.out.println("Class Name is : "+className);
*/
if (!classNameFromXml.toString().equalsIgnoreCase(className.toString())) {
continue;
}
// Getting all the response items corresponding to
// this class
for (ChatflowNode outputNodeObj : inputNodeType.getInputOrOutputOrDefault()) {
OutputNodeType outputNode = (OutputNodeType) outputNodeObj;
for (Object promptTypeObj : outputNode.getActionOrScriptOrPrompt()) {
PromptType promptType = (PromptType) promptTypeObj;
List<Serializable> responseItemObjs = promptType.getContent();
for (Object responseItemObj : responseItemObjs) {
/*
* if (responseItemObj instanceof
* String) {
* System.out.println(((String)
* responseItemObj).trim()); }
*/
if (responseItemObj instanceof JAXBElement) {
// System.out.println("JAXBElement
// Instance");
JAXBElement responseItem = (JAXBElement) responseItemObj;
System.out.println("The old response is : " + responseItem.getValue().toString());
responseItem.setValue(response.toString());
}
}
}
}
}
}
}
}
FileOutputStream os = new FileOutputStream(mor_dialog);
JAXBMarshaller.marshal(dialog, os);
//os.flush();
os.close();
//JAXBMarshaller.marshal(dialog, new FileOutputStream("src/main/java/com/sau/watson/dialog/xml/mor_dialog.xml"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
The src/main/resources folder is only available on your development machine before maven builds the war file. After building the war the resources are added to the war file from the root of the classpath.
If you want to be updating the file then you probably want to access the file from the file system rather than from the classpath.
I'm trying to read .drl drools rules in my REST with Java (JAX-RS) using Jersey.
I put my .drl files in WEB-INF/rules folder, and tried to read them with this lines of code
private RuleBase trainingRules;
private RuleBase kuperMaleTrainingResultsRules;
private RuleBase kuperFemaleTrainingResultsRules;
private RuleBase basicTrainingResultsRules;
private final String trainingRulesPath = "/WEB-INF/rules/ZatraziTrening.drl";
private final String kuperMaleTrainingResultsPath = "/WEB-INF/rules/KuperMuski.drl";
private final String kuperFemaleTrainingResultsPath = "/WEB-INF/rules/KuperZenski.drl";
private final String trainingResultsRulesPath = "/WEB-INF/rules/RezultatiTreninga.drl";
private static ControllerDrools INSTANCE;
private ControllerDrools() {
try {
this.trainingRules = loadRules(trainingRulesPath);
this.kuperMaleTrainingResultsRules = loadRules(kuperMaleTrainingResultsPath);
this.kuperFemaleTrainingResultsRules = loadRules(kuperFemaleTrainingResultsPath);
this.basicTrainingResultsRules = loadRules(trainingResultsRulesPath);
} catch (DroolsParserException | IOException e) {
// TODO: dodati ispis poruke u logger
e.printStackTrace();
}
}
private RuleBase loadRules(String rulesPath) throws DroolsParserException, IOException {
Reader source = new InputStreamReader(ControllerDrools.class.getResourceAsStream(rulesPath));
PackageBuilder builder = new PackageBuilder();
builder.addPackageFromDrl(source);
Package pkg = builder.getPackage();
// Kreiranje baze znanja i dodavanje paketa u nju
RuleBase ruleBase = RuleBaseFactory.newRuleBase();
ruleBase.addPackage(pkg);
return ruleBase;
}
public static ControllerDrools getInstance() {
if (INSTANCE == null) {
INSTANCE = new ControllerDrools();
}
return INSTANCE;
}
/**
* Get's the training from drools
* #param user
* #return training to do
*/
public Training getTrening(User user) {
user.setNumberOfTrainingInCategory(user.getNumberOfTrainingInCategory() + 1);
Training training = new Training();
training.setUser(user);
try {
WorkingMemory workingMemory = trainingRules.newStatefulSession();
workingMemory.insert(user);
workingMemory.insert(training);
workingMemory.insert(user.getCategory());
workingMemory.fireAllRules();
} catch (Exception e) {
// TODO: logger
e.printStackTrace();
}
return training;
}
but i get
java.lang.NullPointerException
java.io.Reader.<init>(Unknown Source)
java.io.InputStreamReader.<init>(Unknown Source)
loadRules(ControllerDrools.java:48)
which is this line
Reader source = new InputStreamReader(ControllerDrools.class.getResourceAsStream(rulesPath));
Any body knows how to read this rules ? Where to put them ?
Thank you very much for reading this, it means a lot to me.
Using ControllerDrools.class.getResourceAsStream(rulesPath), your path should be relative from your ControllerDrools class package.
To make your path absolute, you should add a leading slash "/rules/ZatraziTrening.drl"
You can also use the following syntax to have absolute path :
this.getClass().getClassLoader().getResourceAsStream(rulesPath)
If you use maven, i advise you to put drl files directly in "src/main/resources"
I get the following problem when trying to display a list of items. For each item, I have to display an image which is dynamically loaded via a Wicket WebResource. The items are loaded step by step — 50 at a time — upon user scrolling, using an Ajax scroll.
[ERROR] 2011-04-19 09:58:18,000 btpool0-1 org.apache.wicket.RequestCycle.logRuntimeException (host=, request=, site=):
org.apache.wicket.WicketRuntimeException: component documentList:scroller:batchElem:666:content:item:3:batchItemContent:linkToPreview:imageThumbnail not found on page com.webapp.document.pages.DocumentListPage[id = 1]
listener interface = [RequestListenerInterface name=IResourceListener, method=public abstract void org.apache.wicket.IResourceListener.onResourceRequested()]
org.apache.wicket.protocol.http.request.InvalidUrlException: org.apache.wicket.WicketRuntimeException: component documentList:scroller:batchElem:666:content:item:3:batchItemContent:linkToPreview:imageThumbnail
not found on page com.webapp.document.pages.DocumentListPage[id = 1] listener interface = [RequestListenerInterface name=IResourceListener, method=public abstract void org.apache.wicket.IResourceListener.onResourceRequested()]
at org.apache.wicket.protocol.http.WebRequestCycleProcessor.resolve(WebRequestCycleProcessor.java:262)
at org.apache.wicket.RequestCycle.step(RequestCycle.java:1310)
at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1428)
at org.apache.wicket.RequestCycle.request(RequestCycle.java:545)
at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:479)
at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByGuice$$51619816.CGLIB$doGet$6()
at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByGuice$$51619816$$FastClassByGuice$$6d42bf5d.invoke()
at com.google.inject.internal.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:64)
at com.freiheit.monitoring.PerformanceMonitoringMethodInterceptor.invoke(PerformanceMonitoringMethodInterceptor.java:115)
at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:64)
at com.google.inject.internal.InterceptorStackCallback.intercept(InterceptorStackCallback.java:44)
at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByGuice$$51619816.doGet()
at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:312)
at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByGuice$$51619816.CGLIB$doFilter$4()
How can this problem be solved?
Here is the part of the code responsible for adding the image:
previewLink.add(createThumbnailSmall("imageThumbnail", documentModel));
in
createThumbnailSmall(final String id, final IModel<BaseDocument> documentModel) {
// thumbnailResource is an object that contains the path of the image
if (thumbnailResource != null) {
final WebResource resource = getWebResource(thumbnailResource);
final Image image = new Image(id, resource);
return image;
}
return new InvisibleContainer(id);
}
WebResource getWebResource(final DocumentResource documentResource) {
return new WebResource() {
private static final long serialVersionUID = 1L;
#Override
public IResourceStream getResourceStream() {
return new BaseStreamResource(documentResource);
}
};
}
where BaseStreamResource is the following:
public class BaseStreamResource extends AbstractResourceStream {
private InputStream _fileInputStream = null;
private DocumentResource _resource = null;
public BaseStreamResource(final DocumentResource documentResource) {
_resource = documentResource;
}
#Override
public InputStream getInputStream() throws ResourceStreamNotFoundException {
if (_fileInputStream == null) {
try {
if (_resource == null) {
throw new ResourceStreamNotFoundException("Resource was null");
}
_fileInputStream = _resource.getFileInputStream();
} catch (final ResourceNotAvailableException ex) {
throw new ResourceStreamNotFoundException(ex);
}
}
return _fileInputStream;
}
In HTML:
<a wicket:id="linkToPreview" href="#">
<img wicket:id="imageThumbnail" alt="Attachment"></img></a>
The code added hasn't really added any clues for me, but maybe I can help narrow it down a bit anyway.
The stacktrace includes a reference to com.webapp.document.pages.DocumentListPage, which is likely calling some of the code you've posted. The error indicates a bad url, so debugging into that class, adding debug prints, and looking at the values of any field containing a url might be worthwhile.
It might even help to modify the code in DocumentListPage (maybe temporarily for debugging) to catch org.apache.wicket.protocol.http.request.InvalidUrlException and adding debugging prints specifically when the exception is caught.
This isn't really an answer, but it's too big for a comment, and maybe it'll help you get closer to an answer.
The following solution solved the problem:
- extend WebResource class
- add extended class as a resource to application shared resources
Ex:
public class MyWebResource extends WebResource {
final ValueMap map = new ValueMap();
#Override
public IResourceStream getResourceStream() {
String fileName = getFileName();
File file = new File(basePath, fileName);
if (!file.exists()) {
LOG.error("File does not exist: " + file);
throw new IllegalStateException("File does not exist: " + file);
}
return new FileResourceStream(file);
}
public final void addResource() {
Application.get().getSharedResources().add(getClass().getName(), this);
}
protected String getFileName() {
return getParameters().getString("id");
}
public final String urlFor(final String fileName) {
final ResourceReference resourceReference = new ResourceReference(getClass().getName());
final String encodedValue = WicketURLEncoder.QUERY_INSTANCE.encode(fileName);
map.add("id", encodedValue);
final CharSequence result = RequestCycle.get().urlFor(resourceReference, map);
if (result == null) {
throw new IllegalStateException("The resource was not added! "
+ "In your Application class add the following line:"
+ "MyConcreteResource.INSTANCE.addResource()");
}
String absoluteUrl = RequestUtils.toAbsolutePath(result.toString());
return absoluteUrl;
}
}
In Application class, in init(), I have added MyWebResource to shared resources:
public void init() {
...
new MyWebResource().addResource();
...
}
My project includes multiple plugins and every plugin includes the plugin.properties file with near to 20 translations.
The MANIFEST.MF file defines the name of the properties files where the external plugin strings are stored.
Bundle-Localization: plugin
The name of the plugin i define like
%plugin.name
Eclipse will search the "%plugin.name" in the plugin.properties file at runtime.
Which class read out the MANIFEST.MF Bundle-Localization entry and at which point is the string with the starting '%' suffix is searched in the "plugin.properties" file?
I want to find and patch these class in that way, that i can first look into some other directories/files for the "%plugin.name" identifier. With these new mechanism i can add fragments to my product and overwrite single lines in a "plugin.properties" file without changing the original plugin.
With these mechanism i could create a build process for multiple customers just by adding different fragments. The fragments including the customer names and special string they want to change.
I want to do it that way, because the fragment mechanism only add files to the original plugin. When the "plugin.properties" file is existing in the plugin, the fragment "plugin.properties" files are ignored.
UPDATE 1:
The method
class ManifestLocalization{
...
protected ResourceBundle getResourceBundle(String localeString) {
}
...
}
returns the ResourceBundle of the properties file for the given locale string.
When somebody nows how i can now first look into the fragment to get the resource path please post it.
UPDATE 2:
The method in class ManifestLocalization
private URL findInResolved(String filePath, AbstractBundle bundleHost) {
URL result = findInBundle(filePath, bundleHost);
if (result != null)
return result;
return findInFragments(filePath, bundleHost);
}
Searchs for the properties file and cache it. The translations can than get from the cached file. The problem is, that the complete file is cached and not single translations.
A solution would be to first read the fragment file, than read the bundle file. When both files are existing merge them into one file and write the new properties file to the disk. The URL of the new properties file returns, so that the new propetries file can cached.
Although I got the information wrong ... I had exactly the same problem. The plugin is not activated twice and I cannot get to the fragments Bundle-Localization key.
I want all my language translations in the plugin.properties (I know this is frowned upon but it is much easier to manage a single file).
I (half)solved the problem by using
public void populate(Bundle bundle) {
String localisation = (String) bundle.getHeaders().get("Bundle-Localization");
Locale locale = Locale.getDefault();
populate(bundle.getEntry(getFileName(localisation)));
populate(bundle.getEntry(getFileName(localisation, locale.getLanguage())));
populate(bundle.getEntry(getFileName(localisation, locale.getLanguage(), locale.getCountry())));
populate(bundle.getResource(getFileName("fragment")));
populate(bundle.getResource(getFileName("fragment", locale.getLanguage())));
populate(bundle.getResource(getFileName("fragment", locale.getLanguage(), locale.getCountry())));
}
and simply call my fragment localisation file name 'fragment.properties'.
This is not particularly elegant, but it works.
By the way, to get files from the fragment you need the getResource, it seems that fragment files are on the classpath, or are only searched when using getResource.
If someone has a better approach, please correct me.
All the best,
Mark.
/**
* The Hacked NLS (National Language Support) system.
* <p>
* Singleton.
*
* #author mima
*/
public final class HackedNLS {
private static final HackedNLS instance = new HackedNLS();
private final Map<String, String> translations;
private final Set<String> knownMissing;
/**
* Create the NLS singleton.
*/
private HackedNLS() {
translations = new HashMap<String, String>();
knownMissing = new HashSet<String>();
}
/**
* Populates the NLS key/value pairs for the current locale.
* <p>
* Plugin localization files may have any name as long as it is declared in the Manifest under
* the Bundle-Localization key.
* <p>
* Fragments <b>MUST</b> define their localization using the base name 'fragment'.
* This is due to the fact that I have no access to the Bundle-Localization key for the
* fragment.
* This may change.
*
* #param bundle The bundle to use for population.
*/
public void populate(Bundle bundle) {
String baseName = (String) bundle.getHeaders().get("Bundle-Localization");
populate(getLocalizedEntry(baseName, bundle));
populate(getLocalizedEntry("fragment", bundle));
}
private URL getLocalizedEntry(String baseName, Bundle bundle) {
Locale locale = Locale.getDefault();
URL entry = bundle.getEntry(getFileName(baseName, locale.getLanguage(), locale.getCountry()));
if (entry == null) {
entry = bundle.getResource(getFileName(baseName, locale.getLanguage(), locale.getCountry()));
}
if (entry == null) {
entry = bundle.getEntry(getFileName(baseName, locale.getLanguage()));
}
if (entry == null) {
entry = bundle.getResource(getFileName(baseName, locale.getLanguage()));
}
if (entry == null) {
entry = bundle.getEntry(getFileName(baseName));
}
if (entry == null) {
entry = bundle.getResource(getFileName(baseName));
}
return entry;
}
private String getFileName(String baseName, String...arguments) {
String name = baseName;
for (int index = 0; index < arguments.length; index++) {
name += "_" + arguments[index];
}
return name + ".properties";
}
private void populate(URL resourceUrl) {
if (resourceUrl != null) {
Properties props = new Properties();
InputStream stream = null;
try {
stream = resourceUrl.openStream();
props.load(stream);
} catch (IOException e) {
warn("Could not open the resource file " + resourceUrl, e);
} finally {
try {
stream.close();
} catch (IOException e) {
warn("Could not close stream for resource file " + resourceUrl, e);
}
}
for (Object key : props.keySet()) {
translations.put((String) key, (String) props.get(key));
}
}
}
/**
* #param key The key to translate.
* #param arguments Array of arguments to format into the translated text. May be empty.
* #return The formatted translated string.
*/
public String getTranslated(String key, Object...arguments) {
String translation = translations.get(key);
if (translation != null) {
if (arguments != null) {
translation = MessageFormat.format(translation, arguments);
}
} else {
translation = "!! " + key;
if (!knownMissing.contains(key)) {
warn("Could not find any translation text for " + key, null);
knownMissing.add(key);
}
}
return translation;
}
private void warn(String string, Throwable cause) {
Status status;
if (cause == null) {
status = new Status(
IStatus.ERROR,
MiddlewareActivator.PLUGIN_ID,
string);
} else {
status = new Status(
IStatus.ERROR,
MiddlewareActivator.PLUGIN_ID,
string,
cause);
}
MiddlewareActivator.getDefault().getLog().log(status);
}
/**
* #return The NLS instance.
*/
public static HackedNLS getInstance() {
return instance;
}
/**
* #param key The key to translate.
* #param arguments Array of arguments to format into the translated text. May be empty.
* #return The formatted translated string.
*/
public static String getText(String key, Object...arguments) {
return getInstance().getTranslated(key, arguments);
}
}
Change the name of your fragment plugin.properties to something else eg. fragment.properties
in your fragment manifest change the
Bundle-Localization: plugin
to
Bundle-Localization: fragment
Your plugin will be activated twice, the first time using the plugin.properties, the second using the fragment.properties.
Plugin activation is handled by the OSGi runtime Equinox. However I would strongly discourage trying to patch any files there to create specific behavior. The suggested way from Mark seems a much more sane approach to your problem.
One way is to attach a bundle listener, and listen for installations of bundles (and perhaps also look at already installed bundles) and for each bundle generate/provide - and install - a fragment with the wanted property files. If this is done before the application starts up, this should have effect.