GithubHelp home page GithubHelp logo

jenkinsci / stapler Goto Github PK

View Code? Open in Web Editor NEW
160.0 19.0 101.0 45.46 MB

Stapler web framework

License: BSD 2-Clause "Simplified" License

Java 99.71% HTML 0.05% Shell 0.02% JavaScript 0.22%
hacktoberfest

stapler's Introduction

stapler's People

Contributors

basil avatar christ66 avatar daniel-beck avatar daspilker avatar dependabot[bot] avatar ebourg avatar fatbrain avatar hedaurabesh avatar jeffret-b avatar jglick avatar jsoref avatar jtnord avatar kohsuke avatar kzantow avatar markewaite avatar mattmoor avatar michaelneale avatar mramonleon avatar nfalco79 avatar notmyfault avatar oleg-nenashev avatar olivergondza avatar res0nance avatar rsandell avatar stephenc avatar tfennelly avatar timja avatar vivek avatar vlatombe avatar wadeck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stapler's Issues

Suspected incorrect check of methods from more complex interface inheritance chains

https://github.com/stapler/stapler/blob/a6d86809e89dc1d48084201f97e19b602ed603ed/core/src/main/java/org/kohsuke/stapler/ClassDescriptor.java#L142 does not return all interfaces only all declared interfaces, e.g. if I have

interface A {
  @WebMethod("some-method")
  void someMethod(StaplerRequest req, StaplerResponse rsp);
}

interface B extends A {
  ...
}

public class C implements B {
  public void someMethod(StaplerRequest req, StaplerResponse rsp) {
    ...
  }
}

Then C.class.getInterfaces() will include B.class but not A.class

https://github.com/stapler/stapler/blob/311dcfd92d229569e7aaaaae364f6e702188fddc/jelly/src/main/java/org/kohsuke/stapler/jelly/AnnotationProcessorImpl.java#L79 may also need checking

Liskov substitution principle broken with inheritance

Definition of Liskov's principle: If S is a subtype of T, then we can replace T by S and all the properties are still true.

I dunno if it's a desired feature or a unfortunate side-effect.

If we consider those two classes:

class A {
   @WebMethod(name = "fromA")
   public void entryPoint(){...}
}

and

class B extends A {
   @Override
   @WebMethod(name = "fromB")
   public void entryPoint(){...}
}

and they are both "gettable" from the root object.

My initial expectation was to have valid URLs: /a/fromA/, /b/fromB/ and /b/fromA/. But actually the last one is not considered.

  1. We can consider it's the expected behavior, meaning you have full control on your class. As you can provide multiple name in the annotation, there is no problem.
    1. Problem, in case the class A comes from a third party and they add a new name, as a library user you are not notified about that change and your class B will not be Liskov-compliant.
    2. Imagine you have an endpoint that propose a list of A. But inside that list, one element is a B. If you consider reaching the URL: /list/0/fromA/, if you fall on the B element, you get a 404 while a normal response was expected.
  2. As an alternative to keep the full control, we can process the annotation of all the parent classes and add a new annotation that explicitely tells Stapler
    1. either we want to remove one name from parents (to have possibility to rename URL)
    2. or avoid completely going further in the hierarchy (to avoid undesired third-party change)

Error used when DataBoundConstructor annotation is present more than once is not descriptive

Recently I've found out that if you have two constructors annotated with @DataBoundConstrutor you get this error:

[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] javax.annotation.processing.FilerException: Attempt to reopen a file for path ...... ClassName.stapler
  	at com.sun.tools.javac.processing.JavacFiler.checkFileReopening(JavacFiler.java:535)

A most descriptive message would be appreciated.

Add OpenAPI/Swagger support for exported APIs

Using the OpenAPI standard, it would be great if all exported HTTP methods, parameters, etc., could be made available through a standard endpoint. This would aid frontend development in addition to helping map out which APIs are supported. Such a feature would require additional annotations (e.g., using the ones from Swagger) to add the otherwise implicit API details where possible.

Make @WebMethod mandatory

Jesse argues in #32 and #59 that @WebMethod annotation be made mandatory to make code more explicit and prevent accidental unintended exposure of methods.

Similarly, require one or more of the HTTP verb annotations so that when somebody writes a doXyz method that receives a form submission, s/he will be forced to pick a specific verb. This prevents a common security vulnerability in Jenkins where a from submission incorrectly accepts GET, which is not protected against CSRF.

He also argues that @WebMethod(name=...) parameter be mandatory so that refactoring won't inadvertently affect the behaviour as HTTP endpoints.

Feature Wish: automatic Table of contents (clickable in sidebar of viewer)

When using cat-command, documents will be concatented.
For large/many files, the structure of the contents of the resulting file can become quite unclear.

Adding a table of contents automatically (no extra page, but with navigation like in hyperef-package from LaTeX, where a navigation on the sidebar of viewers like xpdf or evince is possible) would be nice.

Downloading a large log file fails in jenkins

I have a jenkins job that has a very large output log: 2,782,890 KB in size.

When I try to download it I get this exception:

java.lang.ArithmeticException: The byte count 2846143684 is too large to be converted to an int
	at org.apache.commons.io.output.CountingOutputStream.getCount(CountingOutputStream.java:71)
	at org.kohsuke.stapler.framework.io.LargeText.writeLogTo(LargeText.java:237)
	at hudson.console.AnnotatedLargeText.writeLogTo(AnnotatedLargeText.java:154)
	at org.kohsuke.stapler.framework.io.LargeText.writeLogTo(LargeText.java:194)
	at hudson.console.AnnotatedLargeText.writeLogTo(AnnotatedLargeText.java:145)
	at io.jenkins.blueocean.service.embedded.rest.LogResource.writeLogs(LogResource.java:75)
	at io.jenkins.blueocean.service.embedded.rest.LogResource.writeLog(LogResource.java:51)
	at io.jenkins.blueocean.service.embedded.rest.LogResource.doIndex(LogResource.java:37)
	at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)
	at org.kohsuke.stapler.Function$MethodFunction.invoke(Function.java:343)
	at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:184)
	at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:117)
	at org.kohsuke.stapler.IndexDispatcher.dispatch(IndexDispatcher.java:26)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715)
Caused: javax.servlet.ServletException
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:765)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845)
	at org.kohsuke.stapler.MetaClass$3.doDispatch(MetaClass.java:209)
	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
        ..

Looking at CountingOutputStream there is a getByteCount() method that returns a long. But LargeText is calling getCount() which does a length check, and throws this exception, before casting to an int.

LargeText.writeLogTo() returns a long, so it should be calling getByteCount() and dealing with longs, and thus allow large log files to be downloaded without this exception.

HttpResponse uses platform dependant line terminators.

org.kohsuke.stapler.HttpResponses.html(String) and org.kohsuke.stapler.HttpResponses.plainText(String) use platform dependant line terminators in the response, yet the unit test assert that response is using Unix style line ends here and here.

Obviously one is wrong as this causes the unit tests to fail on windows - yet I am not sure which is incorrect, the response or the test.

I am thinking it is more likely to be HttpResponses but am not 100% convinced.

Failed tests:
  DispatcherTest.testArbitraryWebMethodName:104 expected:<I'm index[]
] but was:<I'm index[
>
  DispatcherTest.testIndexDispatchByName:40 expected:<Hello world[]
] but was:<Hello world[
>
  DispatcherTest.testInheritance:188 expected:<abc[]
] but was:<abc[
>
  DispatcherTest.testInterceptorStage:144 expected:<3,5[]
] but was:<3,5[
>
  DispatcherTest.testInterceptorStageContentTypeWithCharset:161 expected:<3,5[]
] but was:<3,5[
>
  DispatcherTest.testPutInheritance:224 expected:<Hello World![]
] but was:<Hello World![
>
  DispatcherTest.testVerbMatch:67->check:79 expected:<Got GET[]
] but was:<Got GET[
>

Intellij 13 won't start with stapler installed

I get a hang after installing stapler on Intellij 13. I don't get any errors in the log, but I do get thread dumps. Intellij won't finish launching. I'm on Mac OS X 10.9.

Startup log:

-03-29 14:06:52,756 [ 30] INFO - #com.intellij.idea.Main - IDE: IntelliJ IDEA (build #IU-133.331, 17 Dec 2013 00:00)
2014-03-29 14:06:52,756 [ 30] INFO - #com.intellij.idea.Main - OS: Mac OS X (10.9.2, x86_64)
2014-03-29 14:06:52,756 [ 30] INFO - #com.intellij.idea.Main - JRE: 1.6.0_65-b14-462-11M4609 (Apple Inc.)
2014-03-29 14:06:52,756 [ 30] INFO - #com.intellij.idea.Main - JVM: 20.65-b04-462 (Java HotSpot(TM) 64-Bit Server VM)
2014-03-29 14:06:52,763 [ 37] INFO - #com.intellij.idea.Main - JVM Args: -Dfile.encoding=UTF-8 -ea -Dsun.io.useCanonCaches=false -Djava.net.preferIPv4Stack=true -XX:+UseCodeCacheFlushing -XX:+UseConcMarkSweepGC -XX:SoftRefLRUPolicyMSPerMB=50 -Xverify:none -Xbootclasspath/a:../lib/boot.jar -server -Xms1024m -Xmx4048m -XX:NewSize=512m -XX:MaxNewSize=128m -XX:PermSize=256m -XX:MaxPermSize=384m -XX:+UseParNewGC -XX:ParallelGCThreads=4 -XX:MaxTenuringThreshold=1 -XX:SurvivorRatio=8 -XX:+UseCodeCacheFlushing -XX:+UseConcMarkSweepGC -XX:+AggressiveOpts -XX:+CMSClassUnloadingEnabled -XX:+CMSIncrementalMode -XX:+CMSIncrementalPacing -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=65 -XX:+CMSScavengeBeforeRemark -XX:+UseCMSInitiatingOccupancyOnly -XX:ReservedCodeCacheSize=256m -XX:+UseCodeCacheFlushing -XX:+UseCompressedOops -Didea.java.redist=NoJavaDistribution -Didea.paths.selector=IntelliJIdea13 -DCVS_PASSFILE=~/.cvspass -Dsun.java2d.noddraw=true -Didea.fatal.error.notification=disabled -Didea.max.intellisense.filesize=2500 -Didea.use.default.antialiasing.in.editor=false -Dcom.apple.mrj.application.live-resize=false -Dapple.awt.graphics.UseQuartz=true -Didea.no.launcher=false -Dapple.awt.fullscreencapturealldisplays=false -Dsun.java2d.pmoffscreen=false -Dapple.laf.useScreenMenuBar=true -Dswing.bufferPerWindow=false -Djava.endorsed.dirs= -Didea.smooth.progress=false -Didea.popup.weight=heavy -Didea.cycle.buffer.size=1024 -Dsun.java2d.d3d=false -Didea.xdebug.key=-Xdebug -Didea.dynamic.classpath=false
2014-03-29 14:06:52,802 [ 76] INFO - #com.intellij.idea.Main - JNA library loaded (64-bit) in 39 ms
2014-03-29 14:06:52,849 [ 123] INFO - #com.intellij.idea.Main - Snappy library loaded (1.0.5) in 47 ms
2014-03-29 14:06:52,853 [ 127] INFO - #com.intellij.idea.Main - initializing environment
2014-03-29 14:06:52,856 [ 130] INFO - .intellij.util.EnvironmentUtil - loading shell env: /bin/zsh -l -c '/Applications/IntelliJ IDEA 13.app/bin/printenv.py' '/private/var/folders/cl/zc2f36412bbgfvv3qt_sytd00000gn/T/intellij-shell-env8079950870743971221.tmp'
2014-03-29 14:06:52,975 [ 249] INFO - .intellij.util.EnvironmentUtil - shell environment loaded (63 vars)
2014-03-29 14:06:54,147 [ 1421] INFO - llij.ide.plugins.PluginManager - Cannot find optional descriptor intellilang-tapestry-support.xml
2014-03-29 14:06:54,359 [ 1633] INFO - llij.ide.plugins.PluginManager - Cannot find optional descriptor flex-ide-specific.xml
2014-03-29 14:06:55,108 [ 2382] INFO - llij.ide.plugins.PluginManager - 136 plugins initialized in 1727 ms
2014-03-29 14:06:55,109 [ 2383] INFO - llij.ide.plugins.PluginManager - Loaded bundled plugins: Ant Support (1.0), Byte Code Viewer (0.1), CSS Support, Commander (1.0.0), Coverage, Database Support (1.0), Eclipse Integration (3.0), Emma, Git Integration (8.1), Groovy (9.0), HTML Tools (2.0), I18n for Java, IDEA CORE, Inspection-JS (2.0), JUnit (1.0), JavaScript Debugger (1.0), JavaScript Intention Power Pack (0.9.4), JavaScript Support (1.0), LESS support, Properties Support, QuirksMode, REST Client, Remote Hosts Access (0.1), SASS support, SQL support (1.0), SSH Remote Run (0.1), Stylus support, Subversion Integration (1.1), Task Management (1.0), Terminal (0.1), Time Tracking (1.0), UML Support (1.0), W3C Validators (2.0), YAML
2014-03-29 14:06:55,109 [ 2383] INFO - llij.ide.plugins.PluginManager - Loaded custom plugins: Apache config (.htaccess) support (131.61), BashSupport (1.1beta20-idea13), Google Protocol Buffers support (0.5.5), Handlebars/Mustache (133.74), JS Toolbox (1.2.1), La Clojure (0.7.61), Multirun (0.8), NodeJS (133.293), Reveal In Finder (1.0), Ruby (6.0.0.20131207), Stapler plugin for IntelliJ IDEA (1.7.3)
2014-03-29 14:06:55,109 [ 2383] INFO - llij.ide.plugins.PluginManager - Disabled plugins: ASP (0.1), Android Designer, Android Support (10.0), Application Servers View (0.2.0), AspectJ Support (1.1), CFML Support (3.53), CVS Integration (11), ClearCase Integration (2.0), Cloud Foundry integration (1.0), CloudBees integration (1.0), CoffeeScript (2.0), Copyright (8.1), Cucumber for Groovy (1.0), Cucumber for Java (1.0), DSM Analysis (1.0.0), Flash/Flex Support (1.0), FreeMarker support (1.0), GWT Support (1.0), Geronimo Integration (1.0), Gherkin (1.2), GitHub, GlassFish Integration (1.0), Google App Engine Integration (1.1.4), Gradle, Grails (9.0), GuiceyIDEA (8.0), HAML, Heroku integration (1.0), Hibernate Support (1.0), IDEtalk (1.0), IntelliLang (8.0), J2ME (1.0), JBoss Drools Support (1.0), JBoss Integration (1.0), JBoss Seam Pageflow Support (1.0), JBoss Seam Pages Support (1.0), JBoss Seam Support (1.0), JBoss jBPM (2.0.0), JSR45 Integration (1.0), Java EE: Batch Applications (1.0), Java EE: Bean Validation Support (1.1), Java EE: Contexts and Dependency Injection (1.1), Java EE: EJB, JPA, Servlets (1.0), Java EE: JMS, JSON Processing, Concurrency, Transaction (1.0), Java EE: Java Server Faces (2.2.X.), Java EE: RESTfull Web Services (JAX-RS) (1.0), Java EE: Web Services (JAX-WS) (1.9), Java EE: WebSockets (1.0), Java Server Pages Integration (1.0), JavaFX (1.0), Jetty Integration (1.0), Maven Integration, Maven Integration Extension, OpenShift integration (1.0), Osmorc (1.4.4), Perforce Integration (2.0), Persistence Frameworks Support (1.0), Playframework Support (1.0), Plugin DevKit (1.0), Refactor-X (2.01), Resin Integration (8.1), Spring Batch (1.0), Spring Data (1.0), Spring Integration Patterns (1.0), Spring OSGi (1.0), Spring Roo Console (1.0), Spring Security (1.0), Spring Support (1.0), Spring Web Flow (1.0), Spring Web Services (1.0), Spring-AOP and @AspectJ support (1.0), Structural Search (9.0), Struts 1.x (2.0), Struts 2 (1.0), TFS Integration (999.999), Tapestry support (1.0), TestNG-J (8.0), Tomcat and TomEE Integration (1.0), Type Migration, UI Designer, UI Designer (Core), Vaadin Support (1.0), Velocity support (1.0), Visual SourceSafe Integration (2.0), WebLogic Integration (1.0), WebSphere Integration (1.0), XPathView + XSLT Support (4), XSLT-Debugger (1.4), ZKM-Unscramble (1.0), dmServer Support (0.9.5), hg4idea (10.0)
2014-03-29 14:06:55,575 [ 2849] INFO - ellij.util.io.PagedFileStorage - lower=100; upper=200; buffer=10; max=4169990144
2014-03-29 14:06:55,668 [ 2942] INFO - api.vfs.impl.local.FileWatcher - Starting file watcher: /Applications/IntelliJ IDEA 13.app/bin/fsnotifier
2014-03-29 14:06:55,690 [ 2964] INFO - api.vfs.impl.local.FileWatcher - Native file watcher is operational.
2014-03-29 14:06:55,778 [ 3052] INFO - s.impl.stores.FileBasedStorage - Document was not loaded for $APP_CONFIG$/path.macros.xml file is null
2014-03-29 14:06:57,257 [ 4531] INFO - s.impl.stores.FileBasedStorage - Document was not loaded for $APP_CONFIG$/macros.xml file is null
2014-03-29 14:06:57,265 [ 4539] INFO - s.impl.stores.FileBasedStorage - Document was not loaded for $APP_CONFIG$/quicklists.xml file is null
2014-03-29 14:06:59,016 [ 6290] INFO - s.impl.stores.FileBasedStorage - Document was not loaded for $APP_CONFIG$/intentionSettings.xml file is null

Here's part of the thread dump...

"Alarm pool(shared)" prio=0 tid=0x0 nid=0x0 blocked
java.lang.Thread.State: BLOCKED
on com.intellij.openapi.application.impl.ApplicationImpl@3aafe2b5 owned by "AWT-EventQueue-1 13.0.1#IU-133.331, eap:false" Id=29
at com.intellij.openapi.application.impl.ApplicationImpl.getStateStore(ApplicationImpl.java:201)
at com.intellij.openapi.application.impl.ApplicationImpl.initializeComponent(ApplicationImpl.java:209)
at com.intellij.openapi.components.impl.ServiceManagerImpl$MyComponentAdapter.initializeInstance(ServiceManagerImpl.java:164)
at com.intellij.openapi.components.impl.ServiceManagerImpl$MyComponentAdapter$1.compute(ServiceManagerImpl.java:147)
at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:945)
at com.intellij.openapi.components.impl.ServiceManagerImpl$MyComponentAdapter.getComponentInstance(ServiceManagerImpl.java:139)
at com.intellij.util.pico.DefaultPicoContainer.getLocalInstance(DefaultPicoContainer.java:225)
at com.intellij.util.pico.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:212)
at com.intellij.util.pico.DefaultPicoContainer.getComponentInstance(DefaultPicoContainer.java:199)
at org.picocontainer.alternatives.AbstractDelegatingMutablePicoContainer.getComponentInstance(AbstractDelegatingMutablePicoContainer.java:75)
at com.intellij.openapi.components.ServiceManager.getService(ServiceManager.java:36)
at com.intellij.ide.ui.search.SearchableOptionsRegistrar.getInstance(SearchableOptionsRegistrar.java:37)
at com.intellij.codeInsight.intention.impl.config.IntentionManagerSettings$1.run(IntentionManagerSettings.java:172)
at com.intellij.util.concurrency.QueueProcessor.runSafely(QueueProcessor.java:238)
at com.intellij.util.Alarm$Request$1.run(Alarm.java:297)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:695)

"AWT-EventQueue-1 13.0.1#IU-133.331, eap:false" prio=0 tid=0x0 nid=0x0 waiting on condition
java.lang.Thread.State: WAITING
on java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync@1a966bcb
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:811)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:867)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1201)
at java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.lockInterruptibly(ReentrantReadWriteLock.java:945)
at com.intellij.openapi.application.impl.ApplicationImpl$WriteAccessToken.(ApplicationImpl.java:1252)
at com.intellij.openapi.application.impl.ApplicationImpl.acquireWriteActionLock(ApplicationImpl.java:1222)
at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:995)
at org.kohsuke.stapler.idea.StaplerApplicationComponent.initComponent(StaplerApplicationComponent.java:36)
at com.intellij.openapi.components.impl.ComponentManagerImpl$ComponentConfigComponentAdapter$1.getComponentInstance(ComponentManagerImpl.java:548)
at com.intellij.openapi.components.impl.ComponentManagerImpl$ComponentConfigComponentAdapter.getComponentInstance(ComponentManagerImpl.java:590)
at com.intellij.util.pico.DefaultPicoContainer.getLocalInstance(DefaultPicoContainer.java:225)
at com.intellij.util.pico.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:212)
at com.intellij.util.pico.DefaultPicoContainer.getComponentInstance(DefaultPicoContainer.java:199)
at org.picocontainer.alternatives.AbstractDelegatingMutablePicoContainer.getComponentInstance(AbstractDelegatingMutablePicoContainer.java:75)
at com.intellij.openapi.components.impl.ComponentManagerImpl.createComponent(ComponentManagerImpl.java:121)
at com.intellij.openapi.application.impl.ApplicationImpl.createComponent(ApplicationImpl.java:388)
at com.intellij.openapi.components.impl.ComponentManagerImpl.a(ComponentManagerImpl.java:112)
at com.intellij.openapi.components.impl.ComponentManagerImpl.init(ComponentManagerImpl.java:89)
at com.intellij.openapi.components.impl.stores.ApplicationStoreImpl.load(ApplicationStoreImpl.java:87)
at com.intellij.openapi.application.impl.ApplicationImpl.load(ApplicationImpl.java:525)
at com.intellij.idea.IdeaApplication.run(IdeaApplication.java:150)
at com.intellij.idea.MainImpl$1$1$1.run(MainImpl.java:58)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:715)
at java.awt.EventQueue.access$400(EventQueue.java:82)
at java.awt.EventQueue$2.run(EventQueue.java:676)
at java.awt.EventQueue$2.run(EventQueue.java:674)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:86)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:685)
at com.intellij.ide.IdeEventQueue.e(IdeEventQueue.java:696)
at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:524)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:335)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Quietly ignore interfaces in IndexHtmlDispatcher

After PR #102, the class hierarchy is inspected to look for index.html files (make() method).

In case the used class is an interface, getSuperclass() returns null and thus a NPE happens. Although this probably is something conceptually wrong, it is something that worked previously and hence interfaces should be silently ignored for compatibility reasons.

JSON pretty-print misformats empty collections

json?pretty misformats empty arrays and objects: spreads them across three lines (a blank line in the middle!), when a single line would do, i.e. no internal whitespace: [] or {}.

Buglet: ?pretty=false behaves like ?pretty or ?pretty=true.

Use of class sun.net.www.protocol.jar.JarURLConnection on Stapler.java

While I was testing the new version of Jenkins (1.537), I got a NoClassDefFoundError for class sun.net.www.protocol.jar.JarURLConnection inside the Stapler servlet. This error has been reported in the issue JENKINS-20163.

During my investigation, I found that the proprietary class sun.net.www.protocol.jar.JarURLConnection is explicitly imported by the current version of Stapler.java, leading to the error NoClassDefFoundError under certain conditions.

Looking into the code, it is possible to see that the reference to the class sun.net.www.protocol.jar.JarURLConnection can be replaced by java.net.JarURLConnection by changing the import clause alone (no further changes in the code).

Since sun.net.www.protocol.jar.JarURLConnection is a subclass of java.net.JarURLConnection, the original code will work as expected unless it was targeted to sun.net.www.protocol.jar.JarURLConnection only.

Export JSONObject with stapler throw NotExportableException exception when there is a field with null value.

Using JSONObject in classes with annotation @ExportedBean works fine except when there is a field with null value.

Having a field with null value is correct in JSON format. So JSONObject with JSONNull should be exportable as other JSONObject.

The exception raised is:

org.kohsuke.stapler.export.NotExportableException: class net.sf.json.JSONNull doesn't have @ExportedBean

	at org.kohsuke.stapler.export.Property.writeValue(Property.java:298)
	at org.kohsuke.stapler.export.Property.writeValue(Property.java:168)
	at org.kohsuke.stapler.export.Property.writeValue(Property.java:266)
	at org.kohsuke.stapler.export.Property.writeValue(Property.java:168)
	at org.kohsuke.stapler.export.Property.writeTo(Property.java:153)
	at org.kohsuke.stapler.export.Model.writeNestedObjectTo(Model.java:223)
	at org.kohsuke.stapler.export.Model.writeTo(Model.java:194)
	at org.kohsuke.stapler.export.Model.writeTo(Model.java:214)
	at org.kohsuke.stapler.export.Model.writeTo(Model.java:182)

PR with test to reproduce the issue: #173

AcceptHeader.select() throws NPE

AcceptHeader.select() throws NPE if given media type is not supported.

e.g..
new AcceptHeader("text/html").select("text/plain")

duplicat

when upload multi-files in form-request, like:

<input name="file" type="file" id="uploadFiles" multiple="multiple" />

then, in /org/kohsuke/stapler/RequestImpl.java#parseMultipartFormData() method, multi files will have the some feildname, and last pared file will cover the prior parsed file:

private void parseMultipartFormData() throws ServletException {
    if(parsedFormData!=null)    return;
    // use map to store fileItem, and use feildname as key.
    parsedFormData = new HashMap<String,FileItem>();
    parsedFormDataFormFields = new HashMap<String, String>();
    ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
    try {
        for( FileItem fi : (List<FileItem>)upload.parseRequest(this) ) {
            parsedFormData.put(fi.getFieldName(),fi);
            if (fi.isFormField()) {
                parsedFormDataFormFields.put(fi.getFieldName(),fi.getString());
            }
        }
    } catch (FileUploadException e) {
        throw new ServletException(e);
    }
}

I am not sure where should I fix this problem, front-end or back-end? Anyone have some suggests?

Unable to serve pre-compressed static content in stapler

If i already have pre-compressed content then stapler does not pick it up, even though it is in gzip format.

Is this feature already present in stapler on jenkins.

i tried adding init parameter gzip=true but that did not solve the problem

remove gzip compression from stapler

Stapler adds some code to do gzip compression on the fly.

However there are various routes as pointed out in the code.

All modern containers (tomcat, weblogic, jetty) have support built in for doing compression which alleviates these tricks.

Therefore in the modern age, just remove any support in stapler for compression handling and make users user their servlet container appropriately if they desire the configuration.

how to change to another servlet root?

this is probably a stupid question, but I'd like to set Stapler to a directory not /

for example, from this site

http://stapler.kohsuke.org/getting-started.html

since I set the Stapler root to be

[servlet]
[servlet-name]Stapler[/servlet-name]
[servlet-class]org.kohsuke.stapler.Stapler[/servlet-class]
[/servlet]

[servlet-mapping]
[servlet-name]Stapler[/servlet-name]
[url-pattern]/[/url-pattern]
[/servlet-mapping]

this means that the URL

http://myserver:myport/

is mapped to the Stapler servlet. This is ok.

Now, I'd like to make it answer to

http://myserver:myport/somedir

obviously, just changing the configuration below is not enough

[servlet]
[servlet-name]Stapler[/servlet-name]
[servlet-class]org.kohsuke.stapler.Stapler[/servlet-class]
[/servlet]

[servlet-mapping]
[servlet-name]Stapler[/servlet-name]
[url-pattern]/somedir/[/url-pattern]
[/servlet-mapping]

how can I change Stapler in this case?

TIA

Leo

Non-serializable BoundTable#Table is used as Jetty session attribute

Mirror issue for JENKINS-41063

I was prototyping some code around Session management in Jenkins with standard Jetty's HashSessionManager. This session manager tries to serialize sessions and their attributes to the disk. In Jetty all session attributes are supposed to be serializable, especially if they declare the Serializable interface.

Jenkins core does not support clustering and thus serialization is widely disabled in the core. But Stapler should not use Jetty session attributes to store such metadata anyway. I my case it causes massive failures if I change Jetty session manager from the default one to a one, which really performs session serialization (e.g. HashSessionManager)

stapler implements Servlet API 2.5 which is pretty old

Stapler implements only the servlet 2.5 API - yet many applications now use 3.1 (either directly or indirectly_

If you attempt to directly use parts of the 3.1 API on a StaplerRequest or StaplerResponse then weird/bad things could happen depending on what you get underneath..
I have not observed any issues yet - but if you get a org.kohsuke.stapler.StaplerResponseWrapper rather than a org.kohsuke.stapler.ResponseImpl then things are liable to blow up. the same probably applies to StaplerRequest sub classes.

Apparantly (although no details are confirmed), this is causing some issues seen in the wild on the Jenkins project

Stapler bug for non-root url-pattern

In Stapler 1.209, lines 652 to 654, it checks for additional tokens

    if(!req.tokens.hasMore()) {
        String servletPath = getServletPath(req);
        if(!servletPath.endsWith("/")) {

the problem is that if Stapler is mapped in a url-pattern other than root, it does not enter this if and gives an error.

I believe somewhere in the code, the url-pattern must be removed or ignored from the list of tokens.

TIA

Leo

Define API to expose DataBound

stapler uses introspection to create a data model for DataBound classes to be instantiated. This mechanism has been reproduced in structs-plugin as well as configuration-as-code.
This creates code duplication, introduce risks for mistakes, and adding some extra feature to stapler (like adding support for bean-validation) require to also update those alternate implementations.

Stapler could expose the introspected model for a DataBound class as an API, that other component could consume, as well as the instanciation lifecycle.

IllegalArgumentException on when the setter parameter is of type Object

The full description of the issue is here

In short: RequestImpl instantiate a ChoiceParameterDefinition class and than using reflection lookup a setter @DataBoundSetter annotated for "choice" property. It takes the parameter type from method (in this unlikely case Object) and than use apache beanutils to convert the actual value "v1\n2\n3" (String) to Object. Since there are no converter registered for Object it fails

"it" can't be resolved

I try to run the maven example, "it" can't be resolved.

<c:forEach var="i" items="${it.items }">

Also in helloJSP.jsp, ${systemTime} is not showing the value.
It seems that variables are not injected into jsps?

Schema rejects body of <st:include>

<st:include page="…" optional="true">
  …
</st:include>

works (as IncludeTag calls invokeBody) but src/site/resources/taglib.xsd#include does not permit any body, causing *.jelly using this feature to not validate. Probably need to have

<xsd:sequence>
  <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>

but was this schema mechanically generated somehow?

Support encrypted PDFs

Support for Pdftk's input_pw option to decrypt encrypted pdfs. Maybe in rename to --decrypt. Maybe add --encrypt as well.

@RequirePOST should be mandatory on web methods

Since it is common for people to forget to specify @RequirePOST, I would suggest that it take a boolean value() default true; attribute so that you can use @RequirePOST(false) to explicitly indicate that GET requests are acceptable on a given web method. (Processor would simply ignore the annotation with !value(); might require an API addition to Interceptor to allow the processor to get the actual annotation.)

Then RequirePOSTAnnotationProcessor should check for apparent web methods (whatever WebMethodAnnotationProcessor would accept) which lack the annotation, and issue an error, forcing plugin developers to make a decision about each such method.

Alternately, deprecate @RequirePOST and make @WebMethod mandatory, adding a boolean requirePOST(); attribute with no default. I tend to prefer this since it makes it much clearer in source code that something is expected to be a web method (and allows tools like IDEs to find all such methods). For binary compatibility, Stapler would need to continue to discover implicit web methods (and handle explicit web methods missing the annotation attribute), but at least the compiler would force them to be marked for newly built plugins. Would need to clarify the status of getSomething(String) methods, which @WebMethod claims to support yet which do not seem like web methods in the ordinary sense.

JENKINS-65905: ReverseProxySetupMonitor has broken referer de-/encoding

I also encountered that problem.
I have a jenkins docker images based on 2.249.3, it works fine in my Macbook Pro but broken in my Redhat linux(Tips: Reserve proxy not correct).
After setting the System property stapler.trace to true and check the response headers, I found
MacBook Pro:

Stapler-Trace-001: -> evaluate(<hudson.model.Hudson@6ec35bae> :hudson.model.Hudson,"/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/http%3A%2F%2Fjks.local%2Fmanage")

Redhat Linux:

Stapler-Trace-001: -> evaluate(<hudson.model.Hudson@46170fb7> :hudson.model.Hudson,"/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/http:/jks.devops/manage")

I am curious why http%3A%2F%2Fjks.local%2Fmanage became http:/jks.devops/manage and how can I solve this problem?

StaplerResponse.forward behaves differently than expected.

in the context of Jenkins I had a method being called by Stapler that I was forwarding on to another view by calling response.forward(this, "feedback", request)

However in doing that the breadcrumb bar in Jenkins broke.
This seems to caused by ResponseImpl.forward calling stapler.invoke which sets an empty AncestorList.
Because the ancestorList is empty the breadCrumbs are also empty.

if I manually navigated to the path ezposed by this and then added "/feedback" to the path the breadcrumbs and hence the ancestor list is correctly computed and shown.

It is suprising to me that forward takes an Object and a relative "view" but using anything other than the root and a full "path/to/view" causes unexpected behaviour.

potential fix is to instead use something akin to resp.forward(Jenkins.get(), user.getUrl() + "/" + getUrlName() + "/feedback", req); which is ugly.

Also of note that req.getView(this, "theView").forward(req,resp) does work for this use case, so it is unclear why the first method does not work in this case, and I believe that it should.

summary

StaplerResponse.forward(Object it, String url, StaplerRequest request)

behaves differently to

StaplerRequest.getView(Object it, String viewName).forward(StaplerRequest request, StaplerResponse response)

(when given the same object and a path without a slash)

yet reading the javadoc they should be logically identical (and both should have the behaviour of request.getView(...).forward(...)

Parallel request routing for Blue Ocean

This issue has its origin in Jenkins Blue Ocean project. In BO, we wanted to expose all Actions of a Build to the URL space of BO, including its sub-objects, in more REST-ful manner. Such code needs to be able to deal with arbitrary Action subtypes that plugins define.

The way we bind those objects to the URL space should mimic the classic UI, thus it should follow regular Stapler routing rules. But BO also need to be able to tweak some aspects of it. For example, index.jelly should be replaced by the state transfer of the object. By extension, we also want to disable all other Jelly/Groovy views that are defined on those objects. In the future a need might arise to do some additional tweaking like this.

I thought about various ways of doing it, such as doing this entirely in BO, but I eventually came to believe that such capability should live in Stapler. I think of this capability as a way of wrapping & filtering existing routing rules and making adjustments, and there's really nothing Jenkins specific about it.

This issue captures this task, so that the solution I propose can be discussed in the context of the requirement.

getSomeStapler throws if used before a web-request is made

I have been playing with writing a Jenkins plugin that delays the deserialization of JSON Objects for wrapped plugins. The pattern I am using (largely successfully) to accomplish this is:
WebApp webapp = WebApp.get(Jenkins.getInstance().servletContext);
Stapler stapler = webapp.getSomeStapler();
StaplerRequest request = new RequestImpl(stapler,
new org.directwebremoting.util.FakeHttpServletRequest(),
Collections.EMPTY_LIST, null);
... = request.bindJSON(...);

(I'm using the Jenkins 1.521 so that the getSomeStapler method is even present)

The only case I've found where this doesn't work is when Jenkins has started, but hasn't received a web request yet. In which case, I get:

java.util.NoSuchElementException
at java.util.concurrent.ConcurrentHashMap$HashIterator.nextEntry(ConcurrentHashMap.java:1288)
at java.util.concurrent.ConcurrentHashMap$ValueIterator.next(ConcurrentHashMap.java:1318)
at org.kohsuke.stapler.WebApp.getSomeStapler(WebApp.java:267)

I have tried a handful of other patterns to accomplish this, but the above seems the most promising, thus far.

Is there some way to trigger the stapler initialization, so that this will work reliably? Is there a better way to get my hands on a Stapler or request?

For my purposes, it is unfortunate that the JSON-binding is tied to a request object :-/

I'd appreciate any help working around this, getting it ~fixed, or any pointers to a better pattern for accomplishing the non-request-bound deserialization. An ideal solution would also work with older Jenkins/Stapler deployments (pre-getSomeStapler).

thanks,
-M

Ancestor.getRestOfUrl() starts with context path

Writing a Jenkins plugin, and accessing Stapler.getCurrentRequest().getAncestors(), from a job's main page…

  • get(0).getRestOfUrl().equals("/jenkins/view/v/job/j")
  • get(1).getRestOfUrl().equals("/jenkins/job/j")
  • get(2).getRestOfUrl().equals("/jenkins")

This seems wrong, as it contradicts the documentation and can easily result in broken URLs. Copy & paste bug in setting up the StringBuilder?

Stapler 1.223

security question re: recent Jenkins advisory

Regarding the recent Jenkins advisory: https://jenkins.io/security/advisory/2018-12-05/

"Jenkins uses the Stapler web framework for HTTP request handling. Stapler’s basic premise is that it uses reflective access to code elements matching its naming conventions. For example, any public method whose name starts with get, and that has a String, int, long, or no argument can be invoked this way on objects that are reachable through these means. As these naming conventions closely match common code patterns in Java, accessing crafted URLs could invoke methods never intended to be invoked this way."

Is this a fundamental issue in Stapler, or is this specific to Jenkins implementation? Curious if other applications should be concerned about this. Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.